Class tensor (o2scl)¶
-
template<class data_t = double, class vec_t = std::vector<data_t>, class vec_size_t = std::vector<size_t>>
class tensor¶ Tensor class with arbitrary dimensions.
The elements of a tensor are typically specified as a list of
size_t
numbers with length equal to the tensor rank. For a rank-4 tensor namedt
, the elementt[1][2][0][3]
can be obtained with something similar tosize_t ix[4]={1,2,0,3}; double x=t.get(ix);
Empty tensors have zero rank.
The type
vec_t
can be any vector type withoperator[]
,size()
andresize()
methods. The typevec_size_t
can be any integer-like vector type withoperator[]
,size()
andresize()
methods.For I/O with tensors, see o2scl_hdf::hdf_file::setd_ten() and o2scl_hdf::hdf_file::getd_ten() .
See the the discussion in the sections Tensors and I/O and contiguous storage of the User’s Guide for more details.
The storage pattern is a generalization of row-major order. In the case of a 4-rank tensor, the location of a generic element is
\[ \left( \left( i_0 s_1 + i_1 \right) s_2 + i_2 \right) s_3 + i_3 \, . \]In this case the distance between two elements \((i_0,i_1, i_2,i_3)\) and \( (i_0+1,i_1,i_2,i_3) \) is \( s_1 s_2 s_3 \), the distance between two elements \((i_0,i_1,i_2, i_3)\) and \( (i_0,i_1+1,i_2,i_3) \) is \( s_2 s_3 \), and the elements \((i_0,i_1,i_2,i_3)\) and \( (i_0,i_1,i_2,i_3+1) \) are adjacent.Todo
In class tensor:
Future: Create an operator[] for tensor and not just tensor1?
Future: Could implement arithmetic operators + and - and some different products.
Future: Implement copies to and from vector and matrices
Future: Implement tensor contractions, i.e. tensor = tensor * tensor
Future: Could be interesting to write an iterator for this class.
Note
Slices of tensors are subsets obtained from fixing the index of several dimensions, while letting other dimensions vary. For a slice with one dimension not fixed, see vector_slice(). The o2scl::tensor::vector_slice() function should clearly work for uBlas vectors, and seems to work with std::vector objects also, but latter use has not been fully tested.
Get functions
-
typedef boost::numeric::ublas::slice slice¶
-
template<class size_vec_t>
inline data_t &get(const size_vec_t &index)¶ Get the element indexed by
index
.
-
template<class size_vec_t>
inline data_t const &get(const size_vec_t &index) const¶ Get a const reference to the element indexed by
index
.
Method to check for valid object
-
inline void is_valid() const¶
Check that the o2scl::tensor object is valid.
Copy constructors
-
inline tensor(const tensor<data_t, vec_t, vec_size_t> &t)¶
Copy using
operator()
-
inline tensor<data_t, vec_t, vec_size_t> &operator=(const tensor<data_t, vec_t, vec_size_t> &t)¶
Copy using
operator=()
Clear method
-
inline void clear()¶
Clear the tensor of all data and free allocated memory.
Set functions
-
template<class size_vec_t>
inline void set(const size_vec_t &index, data_t val)¶ Set the element indexed by
index
to valueval
.
Slice function
-
template<class size_vec_t>
inline ubvector_slice vector_slice(size_t ix, const size_vec_t &index)¶ Fix all but one index to create a vector.
This fixes all of the indices to the values given in
index
except for the index numberix
, and returns the corresponding vector, whose length is equal to the size of the tensor in that index. The valueindex[ix]
is ignored.For example, for a rank 3 tensor allocated with
the following codetensor t; size_t dim[3]={3,4,5}; t.resize(3,dim);
Gives a vectorsize_t index[3]={1,0,3}; ubvector_view v=t.vector_slice(1,index);
v
of length 4 which refers to the valuest(1,0,3)
,t(1,1,3)
,t(1,2,3)
, andt(1,3,3)
.
Resize method
-
template<class size_vec_t>
inline void resize(size_t rank, const size_vec_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.If the user requests any of the sizes to be zero, this function will call the error handler.
Size functions
-
inline size_t get_rank() const¶
Return the rank of the tensor.
-
inline size_t get_size(size_t i) const¶
Returns the size of the ith index.
-
inline const vec_size_t &get_size_arr() const¶
Return the full vector of sizes.
-
inline size_t total_size() const¶
Returns the size of the tensor (the product of the sizes over every index)
Index manipulation
-
template<class size_vec_t>
inline size_t pack_indices(const size_vec_t &index)¶ Pack the indices into a single vector index.
-
template<class size_vec_t>
inline void unpack_index(size_t ix, size_vec_t &index)¶ Unpack the single vector index into indices.
Minimum, maximum, and sum
-
inline void min_index(vec_size_t &index)¶
Compute the index of the minimum value in the tensor.
-
inline void min(vec_size_t &index, data_t &val)¶
Compute the index of the minimum value in the tensor and return the minimum.
-
inline void max_index(vec_size_t &index)¶
Compute the index of the maximum value in the tensor.
-
inline void max(vec_size_t &index, data_t &val)¶
Compute the index and value of the maximum value in the tensor and return the maximum.
-
inline void minmax_value(data_t &min, data_t &max)¶
Compute the minimum and maximum values in the tensor.
-
inline void minmax_index(vec_size_t &index_min, vec_size_t &index_max)¶
Compute the indices of the minimum and maximum values in the tensor.
-
inline void minmax(vec_size_t &index_min, data_t &min, vec_size_t &index_max, data_t &max)¶
Compute the indices and values of the maximum and minimum in the tensor.
-
inline double total_sum() const¶
Return the sum over every element in the tensor.
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")¶
Convert to a o2scl::table3d object by summing over all but two indices.
-
inline void index_spec_preprocess(std::string str, std::vector<std::string> &sv, int verbose = 0)¶
Take a set of index specifications contained in a single string
str
and arrange them insv
.Todo
In tensor::index_spec_preprocess():
Future: Improve this to be more intelligent about whitespace and other characters between index specifications. Right now, this function fails if there are, e.g. two spaces between index specs.
-
inline virtual int strings_to_indexes(std::vector<std::string> sv2, std::vector<o2scl::index_spec> &vis, int verbose = 0, bool err_on_fail = false)¶
Given a set of index specifications specified in a list of strings, reformat them into a list of o2scl::index_spec objects
The tensor rearrange commands use index specifications to specify how the tensor should be rearranged. Index specifications may be specified as separate arguments e.g. “index(1)” “fixed(2,10)” or multiple index specifications may be given in a single argument separated by spaces or commas, e.g. “index(1) fixed(2,10)” or “index(1),fixed(2,10)”. The indices begin with 0, the first index so that index 1 is the second index. The list of index specification is:
index(ix): Retain index ix in the new tensor.
fixed(ix): Fix the value of index ix.
sum(ix): Sum over the value of index ix
trace(ix1,ix2): Trace (sum) over indices ix and ix2. If the number of entries in either index is smaller than the other, then the remaining entries are ignored in the sum.
reverse(ix): Retain index ix but reverse the order.
range(ix,start,end): Retain index ix but modify range. Ranges include both of their endpoints.
interp(ix,value) (for tensor_grid): fix index ix by interpolating ‘value’ into the grid for index ix.
grid(ix,begin,end,n_bins,log) (for tensor_grid): interpolate the specified index on a grid to create a new index. If the value of log is 1, then the grid is logarithmic.
gridw(ix,begin,end,bin_width,log) (for tensor_grid): interpolate the specified index on a grid with a fixed bin width to create a new index. If the value of log is 1, then the grid is logarithmic and the bin_width is the multiplicative factor between bin edges.
Note that the index specifications which result in a tensor index (all except ‘fixed’, ‘sum’, ‘trace’ and ‘interp’) must be given in the order they should appear in the tensor which results. Also, the ‘rearrange’ commands require that the result of the rearrangement must have at least one index left.
Examples:
index(1),index(0) - take the transpose of a rank 2 tensor (i.e. a matrix)
index(1),fixed(2,0),index(0) - fix the value of index 2 (i.e. the third index) to zero and transpose the other two indices
fixed(2,0),index(1),index(0) - same as above
-
inline tensor<data_t> rearrange_and_copy(std::vector<index_spec> spec, int verbose = 0, bool err_on_fail = true)¶
Rearrange, sum and copy current tensor to a new tensor.
- Todo:
We need to check all of the degenerate cases, for example, a range spec. with only one element, a grid specification with only one element in the result, etc.
Todo
In tensor::rarrange_and_copy():
Future: Return a scalar if possible as a rank 1 tensor with 1 element.
Public Functions
-
inline tensor()¶
Create an empty tensor with zero rank.
-
template<class size_vec_t>
inline tensor(size_t rank, const size_vec_t &dim)¶ Create a tensor of rank
rank
with sizes given indim
.The parameter
dim
must be a pointer to a vector of sizes with lengthrank
. If the user requests any of the sizes to be zero, this constructor will call the error handler, create an empty tensor, and will allocate no memory.
-
inline virtual ~tensor()¶
Protected Attributes
-
vec_size_t size¶
A rank-sized vector of the sizes of each dimension.
-
size_t rk¶
Rank.