Class tensor_grid (o2scl)¶

template<class vec_t = std::vector<double>, class vec_size_t = std::vector<size_t>>
class tensor_grid : public o2scl::tensor<double, std::vector<double>, std::vector<size_t>>¶ Tensor class with arbitrary dimensions with a grid.
This tensor class allows one to assign the indexes to numerical scales, effectively defining a data set on an ndimensional grid. To set the grid, use default_grid(), set_grid() or set_grid_packed().
By convention, member functions ending in the
_val
suffix return the closest gridpoint to some userspecified values.Slicing
New o2scl::tensor_grid objects can be obtained by fixing any set of indices using copy_slice_interp().
Fixing all but two indices also results in a o2scl::table3d object, and five functions perform this task in different ways. The function copy_table3d_align() copies a twodimensional slice to a o2scl::table3d object presuming that the grid in the o2scl::table3d object has already been set and exactly matches the corresponding sizes for the selected tensor indices. This function does not check that the grids between the two objects match, it only ensures that they have the same size. In order to copy to a o2scl::table3d object and set its grid to match that from the unfixed indices in the o2scl::tensor_grid object, the function copy_table3d_align_setxy() can be used. The function copy_table3d_interp() uses interpolation to extract values from the o2scl::tensor_grid object. It allows the user to select indices to be fixed and then uses the values in the grid in the o2scl::table3d object for the indices which vary. Alternatively copy_table3d_interp_values() allows the user to specify values on the grid for the indices to be fixed and uses the grid in the o2scl::table3d object for the indices which vary. Finally, copy_table3d_interp_values_setxy() acts like copy_table3d_interp_values() except that it sets the o2scl::table3d grid to be the same as the grid in the o2scl::tensor_grid object which corresponds to the indices which are being varied.
Notes and Todos
Todo
Class tensor_grid: It is possible for the user to create a tensor_grid object, upcast it to a tensor object, and then use tensor::resize() to resize the tensor, failing to resize the grid. Following this, grid access functions will access random parts of memory or segfault. This can be fixed by ensuring that resize functions are virtual and have a version in tensor_grid which ensure that the grid and tensor data are matched. The problem is that the resize functions are templates, so they cannot be virtual.
Future: Create a swap function for the grid similar to the data swap function in the parent ref o2scl::tensor class?
Future: Only allocate space for grid if it is set.
Future: as with ref o2scl::tensor, generalize to other base data types.
Future: The function ref interp_linear_partial() appears to be a generalization of ref copy_table3d_interp_values_setxy(), so there may be some code duplication between the two that can be avoided.
Note
Currently, HDF5 I/O is only allowed if the tensor is allocated with std::vectorbased types, and the interpolate() function only works with ublasbased vector types.
Constructors and Destructors

inline tensor_grid()¶
Create an empty tensor with zero rank.

template<class size_vec_t>
inline tensor_grid(size_t rank, const size_vec_t &dim)¶ Create a tensor of rank
rank
with sizes given indim
.The parameter
dim
must be a vector of sizes with lengthrank
. If the user requests any of the sizes to be zero, this constructor will call the error handler.

inline tensor_grid(std::vector<uniform_grid<double>> &ugs)¶
Create a tensor with a grid defined by a set of o2scl::uniform_grid objects.

inline virtual ~tensor_grid()¶
Destructor.
Method to check for valid object

inline void is_valid() const¶
Check that the o2scl::tensor_grid object is valid.
Copy constructors

inline tensor_grid(const tensor_grid<vec_t, vec_size_t> &t)¶
Copy using
operator()

inline tensor_grid<vec_t, vec_size_t> &operator=(const tensor_grid<vec_t, vec_size_t> &t)¶
Copy using
operator=()
Set functions
Get functions

template<class vec2_t>
inline double get_val(const vec2_t &gridp)¶ Get the element closest to grid point
gridp
.
Resize method

template<class size_vec2_t>
inline void resize(size_t rank, const size_vec2_t &dim)¶ Resize the tensor to rank
rank
with sizes given indim
.The parameter
dim
must be a vector of sizes with a length equal torank
. This resize method is always destructive, and the grid is always reset.If the user requests any of the sizes to be zero, this function will call the error handler.
Grid manipulation

inline bool is_grid_set() const¶
Return true if the grid has been set.

template<class vec2_t>
inline void set_grid_packed(const vec2_t &grid_vec)¶ Set the grid.
The grid must be specified for all of the dimensions at once. Denote \( (\mathrm{size})_0 \) as the size of the first dimension, \( (\mathrm{size})_1 \) as the size of the second dimesion, and so on. Then the first \( (\mathrm{size})_0 \) entries in
grid
must be the grid for the first dimension, the next \( (\mathrm{size})_1 \) entries must be the grid for the second dimension, and so on. Thusgrid
must be a vector of size\[ \sum_{i=0}^{\mathrm{rank}} (\mathrm{size})_i \]Note that the grid is copied so the function argument may be destroyed by the user after calling set_grid_packed() without affecting the tensor grid.
Todo
In set_grid_packed(): Define a more generic interface for matrix types

template<class vec_vec_t>
inline void set_grid(const vec_vec_t &grid_vecs)¶ Set grid from a vector of vectors of grid points.

inline void default_grid()¶
Use a default grid which just uses the index.

template<class vec2_t>
inline void set_grid_i_vec(size_t ix, const vec2_t &grid_vec)¶ Set grid for one index from a vector.

inline void set_grid_i_func(size_t ix, std::string func)¶
Set grid for one index from a function.

inline void set_grid(std::vector<uniform_grid<double>> &ugs)¶
Set grid from a vector of uniform grid objects.
Note
This is called by one of the constructors.

template<class rvec_t>
inline void copy_grid(size_t i, rvec_t &v) const¶ Copy grid for index
i
to vectorv
.The type
rvec_t
must be a vector with a resize method.

inline double get_grid(size_t i, size_t j) const¶
Lookup jth value on the ith grid.

inline void set_grid(size_t i, size_t j, double val)¶
Set the jth value on the ith grid.

inline size_t lookup_grid_val(size_t i, const double &val, double &val2) const¶
Lookup index for grid closest to
val
, returning the grid point.The parameters
val
andval2
may refer to the same object.

inline size_t lookup_grid(size_t i, double val) const¶
Lookup index for grid closest to
val
.

template<class vec2_t, class size_vec2_t>
inline void lookup_grid_vec(const vec2_t &vals, size_vec2_t &indices) const¶ Lookup indices for grid closest point to
vals
.The values in
vals
are not modified by this function.

inline size_t lookup_grid_packed_val(size_t i, double val, double &val2) const¶
Lookup internal packed grid index for point closest to
val
and store closest value inval2
.This version, rather than o2scl::tensor_grid::lookup_grid_val() can be useful because it gives the index of the grid point in the internal grid vector object.

inline size_t lookup_grid_packed(size_t i, double val) const¶
Lookup internal packed grid index for point closest to
val
.
Slicing to tensor_grid objects

template<class size_vec2_t, class vec2_t>
inline tensor_grid copy_slice_interp(size_vec2_t &ifix, vec2_t &vals) const¶ Copy an abitrary slice by fixing 1 or more indices and use interpolation to return a new tensor_grid object.
Slicing and converting to table3d objects

inline void convert_table3d_sum(size_t ix_x, size_t ix_y, table3d &tab, std::string x_name = "x", std::string y_name = "y", std::string slice_name = "z") const¶
Convert to a o2scl::table3d object by summing over all but two indices.

template<class size_vec2_t>
inline void copy_table3d_align(size_t ix_x, size_t ix_y, size_vec2_t &index, table3d &tab, std::string slice_name = "z") const¶ Create a slice in a o2scl::table3d object with an aligned grid.
This function uses the grid associated with indices
ix_x
andix_y
, to copy data to a slice namedslice_name
in the table3d objecttab
. All other indices are fixed to values specified by the user inindex
and the values ofindex[ix_x]
andindex[ix_y]
are used for temporary storage.If the table3d object does not currently have a grid set, then the grid is automatically set to be the same as that stored in the tensor_grid object associated with ranks
ix_x
andiy_y
. If the o2scl::table3d object does have a grid set, then the values returned by o2scl::table3d::get_nx() and o2scl::table3d::get_ny() must be equal to the size of the tensor in indicesix_x
and ix_y, respectively. If a slice namedslice_name
is not already present intab
, then a new slice with that name is created.The error handler is called if
ix_x
is the same asix_y
, or if either of these two values is greater than or equal to the tensor rank.

template<class size_vec2_t>
inline void copy_table3d_align_setxy(size_t ix_x, size_t ix_y, size_vec2_t &index, table3d &tab, std::string x_name = "x", std::string y_name = "y", std::string slice_name = "z") const¶ Create a slice in a table3d object with a new aligned grid.

template<class size_vec2_t>
inline void copy_table3d_interp(size_t ix_x, size_t ix_y, size_vec2_t &index, table3d &tab, std::string slice_name = "z") const¶ Copy to a slice in a table3d object using interpolation.
This function uses the grid associated with indices
ix_x
andix_y
, and the tensor interpolation function to copy the tensor information to the slice namedslice_name
in the table3d objecttab
. All other indices are fixed to values specified by the user inindex
and the values ofindex[ix_x]
andindex[ix_y]
are used for temporary storage.If a slice named
slice_name
is not already present intab
, then a new slice with that name is created.The error handler is called if
ix_x
is the same asix_y
, or if either of these two values is greater than or equal to the tensor rank.Note
This function uses the tensor_grid::interp_linear() for the interpolation.

template<class vec2_t>
inline void copy_table3d_interp_values(size_t ix_x, size_t ix_y, vec2_t &values, table3d &tab, std::string slice_name = "z", int verbose = 0) const¶ Copy to a slice in a table3d object using interpolation.
Clear method

inline void clear()¶
Clear the tensor of all data and free allocated memory.
Interpolation

inline void set_interp_type(size_t interp_type)¶
Set interpolation type for interpolate()

template<class range_t = ub_range, class data_range_t = ubvector_range, class index_range_t = ubvector_size_t_range>
inline double interpolate(double *vals)¶ Interpolate values
vals
into the tensor, returning the result.This is a quick and dirty implementation of ndimensional interpolation by recursive application of the 1dimensional routine from interp_vec, using the base interpolation object specified in the template parameter
base_interp_t
. This will be very slow for sufficiently large data sets. Idea for Future:
It should be straightforward to improve the scaling of this algorithm significantly by creating a “window” of local points around the point of interest. This could be done easily by constructing an initial subtensor. However, this should probably be superceded by a more generic alternative which avoids explicit use of the 1d interpolation types.
Note
This function requires a range objects to obtain ranges of vector objects. In ublas, this is done with
ublas::vector_range
objects, so this function will certainly work for tensor_grid objects built on ublas vector types. There is no correspondingstd::range
, but you may be able to use eitherublas::vector_range
orBoost.Range
in order to call this function with tensor_grid objects built onstd::vector
. However, this is not fully tested at the moment.

template<class vec2_size_t, class vec3_size_t, class vec2_t>
inline double interp_linear_partial(const vec2_size_t &ix_to_interp, vec3_size_t &ix, const vec2_t &val) const¶ Obtain a value by looking up some indices and interpolating the others.
To call this function, the arguments should be of the following form
The vector
ix_to_interp
should be a list of indices to interpolate. The size ofix_to_interp
must be at least 1 or larger but smaller than or equal to the full tensor rank. All entries inix_to_interp
should be smaller than the full tensor rank.The vector
ix
should have a size equal to the tensor rank, but values stored in entries corresponding to the indices inix_to_interp
will be ignoredThe vector
val
should be a list of values to be interpolated and should have a size equal to that ofix_to_interp
.
Todo
In tensor_grid::interp_linear_partial(): Double check and document if the vector “ix_to_interp” needs to be ordered. I’m pretty sure it doesn’t, so long as the ordering in c val and c ix_to_interp are consistent.

template<class vec2_t>
inline double interp_linear(vec2_t &v) const¶ Perform a linear interpolation of
v
into the function implied by the tensor and grid.This performs multidimensional linear interpolation (or extrapolation) It works by first using o2scl::search_vec to find the interval containing (or closest to) the specified point in each direction and constructing the corresponding hypercube of size \( 2^{\mathrm{rank}} \) containing
v
. It then calls interp_linear_power_two() to perform the interpolation in that hypercube.This function calls the error handler if the user tries to interpolate an empty tensor.
 Idea for Future:
This starts with a small copy, which can be eliminated by creating a new version of interp_linear_power_two which accepts an offset vector parameter so that the first interpolation is offset. Remaining interpolations don’t need to be offset because the tensor has to be created from the previous interpolation round.

template<class vec2_t>
inline double interp_linear_power_two(vec2_t &v) const¶ Perform linear interpolation assuming that all indices can take only two values.
This function works by recursively slicing the hypercube of size \( 2^{\mathrm{rank}} \) into a hypercube of size \( 2^{\mathrm{rank1}} \) performing linear interpolation for each pair of points.
Note
This is principally a function for internal use by interp_linear().

template<class vec2_t, class vec3_t>
inline void interp_linear_vec0(vec2_t &v, vec3_t &res) const¶ Perform a linear interpolation of
v[1]
tov[n1]
resulting in a vector.This performs multidimensional linear interpolation (or extrapolation) in the last
n1
indices of the rankn
tensor leaving the first index free and places the results in the vectorres
.Note
The type
vec2_t
for the vectorres
must have aresize()
method.

template<class vec2_t, class vec3_t>
inline void interp_linear_power_two_vec0(vec2_t &v, vec3_t &res) const¶ Perform linear interpolation assuming that the last
n1
indices can take only two values.This function performs linear interpolation assuming that the last
n1
indices can take only two values and placing the result intores
.Note
The type
vec2_t
for the vectorres
must have aresize()
method. This is principally a function for internal use by interp_linear_vec0().

template<class vec2_t, class vec3_t>
inline void interp_linear_vec(vec2_t &v, size_t ifree, vec3_t &res) const¶ Perform a linear interpolation of
v
into the tensor leaving one index free resulting in a vector.This performs multidimensional linear interpolation (or extrapolation) in the last
n1
indices of the rankn
tensor leaving the first index free and places the results in the vectorres
. Idea for Future:
This function could be more efficient.

inline tensor_grid<vec_t, vec_size_t> rearrange_and_copy(std::vector<index_spec> spec, int verbose = 0, bool err_on_fail = true) const¶
Rearrange, sum and copy current tensor to a new tensor.
 Idea for Future:
Some code duplication between this function and the one in the tensor class.
Note
Experimental

inline tensor_grid<vec_t, vec_size_t> rearrange_and_copy(std::string spec, int verbose = 0, bool err_on_fail = true)¶
Rearrange, sum and copy current tensor to a new tensor (string input version)

template<class vecf_t, class vecf_size_t>
friend void hdf_output(o2scl_hdf::hdf_file &hf, tensor_grid<vecf_t, vecf_size_t> &t, std::string name)¶

template<class vecf_t, class vecf_size_t>
friend void hdf_input(o2scl_hdf::hdf_file &hf, tensor_grid<vecf_t, vecf_size_t> &t, std::string name)¶