23 #ifndef O2SCL_TENSOR_H
24 #define O2SCL_TENSOR_H
35 #include <boost/numeric/ublas/vector.hpp>
36 #include <boost/numeric/ublas/vector_proxy.hpp>
37 #include <boost/numeric/ublas/matrix.hpp>
38 #include <boost/numeric/ublas/matrix_proxy.hpp>
40 #include <gsl/gsl_matrix.h>
41 #include <gsl/gsl_ieee_utils.h>
43 #include <o2scl/err_hnd.h>
44 #include <o2scl/interp.h>
46 #ifndef DOXYGEN_NO_O2NS
120 template<
class vec_t=std::vector<
double>,
121 class vec_
size_t_
int=std::vector<
size_t> >
class tensor {
125 #ifndef DOXYGEN_INTERNAL
154 template<
class size_vec_t>
155 tensor(
size_t rank,
const size_vec_t &dim) {
160 for(
size_t i=0;i<
rk;i++) {
163 O2SCL_ERR((((std::string)
"Requested zero size with non-zero ")+
164 "rank for index "+
szttos(i)+
165 " in tensor::tensor(size_t,size_vec_t)").c_str(),
171 for(
size_t i=0;i<
rk;i++) {
185 template<
class size_vec_t>
186 void set(
const size_vec_t &index,
double val) {
187 #if O2SCL_NO_RANGE_CHECK
192 if (index[0]>=
size[0]) {
194 " greater than or equal to size[0]="+
195 szttos(
size[0])+
" in tensor::set().").c_str(),
200 for(
size_t i=1;i<
rk;i++) {
201 #if O2SCL_NO_RANGE_CHECK
203 if (index[i]>=
size[i]) {
205 szttos(index[i])+
" greater than or equal to size "+
206 szttos(
size[i])+
" in tensor::set().").c_str(),
227 template<
class size_vec_t>
double &
get(
const size_vec_t &index) {
228 #if O2SCL_NO_RANGE_CHECK
233 if (index[0]>=
size[0]) {
235 " greater than or equal to size[0]="+
236 szttos(
size[0])+
" in tensor::get().").c_str(),
241 for(
size_t i=1;i<
rk;i++) {
242 #if O2SCL_NO_RANGE_CHECK
244 if (index[i]>=
size[i]) {
246 szttos(index[i])+
" greater than or equal to size "+
247 szttos(
size[i])+
" in tensor::get().").c_str(),
258 template<
class size_vec_t>
259 double const &
get(
const size_vec_t &index)
const {
260 #if O2SCL_NO_RANGE_CHECK
265 if (index[0]>=
size[0]) {
267 " greater than or equal to size[0]="+
268 szttos(
size[0])+
" in tensor::get() (const).").c_str(),
273 for(
size_t i=1;i<
rk;i++) {
274 #if O2SCL_NO_RANGE_CHECK
276 if (index[i]>=
size[i]) {
278 szttos(index[i])+
" greater than or equal to size "+
279 szttos(
size[i])+
" in tensor::get() (const).").c_str(),
290 #ifndef O2SCL_NEVER_DEFINED
292 typedef boost::numeric::ublas::vector_slice<
294 typedef boost::numeric::ublas::slice slice;
320 template<
class size_vec_t>
324 " greater than or equal to rank "+
szttos(
rk)+
325 " in tensor::vector_slice()").c_str(),
331 for(
size_t i=1;i<
rk;i++) {
333 if (i!=ix) start+=index[i];
336 for(
size_t i=ix+1;i<
rk;i++) stride*=
size[i];
337 return ubvector_slice(
data,slice(start,stride,
size[ix]));
342 #ifdef O2SCL_NEVER_DEFINED
351 template<
class size_vec_t> ubmatrix_array matrix_slice() {
367 template<
class size_vec_t>
368 void resize(
size_t rank,
const size_vec_t &dim) {
369 for(
size_t i=0;i<rank;i++) {
371 O2SCL_ERR((((std::string)
"Requested zero size with non-zero ")+
372 "rank for index "+
szttos(i)+
" in tensor::"+
382 for(
size_t i=0;i<
rk;i++) {
401 " greater than or equal to rank "+
szttos(
rk)+
402 " in tensor::get_size()").c_str(),
424 for(
size_t i=0;i<
rk;i++) tot*=
size[i];
432 template<
class size_vec_t>
438 if (index[0]>=
size[0]) {
440 " greater than or equal to size[0]="+
441 szttos(
size[0])+
" in tensor::pack_indices().").c_str(),
445 for(
size_t i=1;i<
rk;i++) {
446 if (index[i]>=
size[i]) {
448 szttos(index[i])+
" greater than or equal to size "+
449 szttos(
size[i])+
" in tensor::pack_indices().").c_str(),
459 template<
class size_vec_t>
463 " greater than or equal to total size"+
465 " in tensor::unpack_indices().").c_str(),
469 size_t ix2, sub_size;
470 for(
size_t i=0;i<
rk;i++) {
475 for(
size_t j=i+1;j<
rk;j++) sub_size*=
size[j];
476 index[i]=ix/sub_size;
478 ix-=sub_size*(ix/sub_size);
489 template<
class vec_t=std::vector<
double>,
490 class vec_
size_t_
int=std::vector<
size_t> >
class tensor1 :
491 public tensor<vec_t,vec_size_t_int> {
500 vec_size_t_int sizex(1);
506 double &
get(
size_t ix) {
511 const double &
get(
size_t ix)
const {
516 void set(
size_t index,
double val)
524 template<
class size_vec_t>
525 void set(
const size_vec_t &index,
double val) {
544 template<
class vec_t=std::vector<
double>,
545 class vec_
size_t_
int=std::vector<
size_t> >
class tensor2 :
546 public tensor<vec_t,vec_size_t_int> {
556 this->
size.resize(2);
560 this->
data.resize(tot);
564 double &
get(
size_t ix1,
size_t ix2) {
565 size_t sz[2]={ix1,ix2};
570 const double &
get(
size_t ix1,
size_t ix2)
const {
571 size_t sz[2]={ix1,ix2};
576 void set(
size_t ix1,
size_t ix2,
double val) {
577 size_t sz[2]={ix1,ix2};
587 template<
class size_vec_t>
588 void set(
const size_vec_t &index,
double val) {
595 {
return this->
data[ix*this->
size[1]+iy]; }
599 {
return this->
data[ix*this->
size[1]+iy]; }
604 template<
class vec_t=std::vector<
double>,
605 class vec_
size_t_
int=std::vector<
size_t> >
class tensor3 :
606 public tensor<vec_t,vec_size_t_int> {
615 tensor<vec_t,vec_size_t_int>() {
617 this->
size.resize(3);
621 size_t tot=sz*sz2*sz3;
622 this->
data.resize(tot);
626 double &
get(
size_t ix1,
size_t ix2,
size_t ix3) {
627 size_t sz[3]={ix1,ix2,ix3};
632 const double &
get(
size_t ix1,
size_t ix2,
size_t ix3)
const {
633 size_t sz[3]={ix1,ix2,ix3};
638 void set(
size_t ix1,
size_t ix2,
size_t ix3,
double val) {
639 size_t sz[3]={ix1,ix2,ix3};
649 template<
class size_vec_t>
650 void set(
const size_vec_t &index,
double val) {
659 template<
class vec_t=std::vector<
double>,
660 class vec_
size_t_
int=std::vector<
size_t> >
class tensor4 :
661 public tensor<vec_t,vec_size_t_int> {
669 tensor4(
size_t sz,
size_t sz2,
size_t sz3,
size_t sz4) :
670 tensor<vec_t,vec_size_t_int>() {
672 this->
size.resize(4);
677 size_t tot=sz*sz2*sz3*sz4;
678 this->
data.resize(tot);
682 double &
get(
size_t ix1,
size_t ix2,
size_t ix3,
size_t ix4) {
683 size_t sz[4]={ix1,ix2,ix3,ix4};
688 const double &
get(
size_t ix1,
size_t ix2,
size_t ix3,
690 size_t sz[4]={ix1,ix2,ix3,ix4};
695 void set(
size_t ix1,
size_t ix2,
size_t ix3,
size_t ix4,
697 size_t sz[4]={ix1,ix2,ix3,ix4};
707 template<
class size_vec_t>
708 void set(
const size_vec_t &index,
double val) {
714 #ifndef DOXYGEN_NO_O2NS
double & operator()(size_t ix)
Get an element using operator()
void set(size_t index, double val)
Set the element indexed by index to value val.
const vec_size_t_int & get_size_arr() const
Return the full vector of sizes.
tensor3()
Create an empty tensor.
tensor3(size_t sz, size_t sz2, size_t sz3)
Create a rank 3 tensor of size (sz,sz2,sz3)
tensor1(size_t sz)
Create a rank 1 tensory of size sz.
const vec_t & get_data() const
Return the full data vector.
const double & operator()(size_t ix, size_t iy) const
Get the element indexed by (ix1,ix2) (const version)
invalid argument supplied by user
tensor()
Create an empty tensor with zero rank.
tensor(size_t rank, const size_vec_t &dim)
Create a tensor of rank rank with sizes given in dim.
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
double & operator[](size_t ix)
Get an element using array-like indexing.
size_t pack_indices(const size_vec_t &index)
Pack the indices into a single vector index.
double & operator()(size_t ix, size_t iy)
Get the element indexed by (ix1,ix2)
void set(size_t ix1, size_t ix2, double val)
Set the element indexed by (ix1,ix2) to value val.
size_t get_rank() const
Return the rank of the tensor.
tensor2()
Create an empty tensor.
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
void set_all(double x)
Set all elements in a tensor to some fixed value.
const double & operator[](size_t ix) const
Get an element using array-like indexing (const version)
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
tensor2(size_t sz, size_t sz2)
Create a rank 2 tensor of size (sz,sz2)
void resize(size_t rank, const size_vec_t &dim)
Resize the tensor to rank rank with sizes given in dim.
double & get(const size_vec_t &index)
Get the element indexed by index.
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
void unpack_indices(size_t ix, size_vec_t &index)
Unpack the single vector index into indices.
ubvector_slice vector_slice(size_t ix, const size_vec_t &index)
Fix all but one index to create a vector.
tensor4(size_t sz, size_t sz2, size_t sz3, size_t sz4)
Create a rank 4 tensor of size (sz,sz2,sz3,sz4)
const double & operator()(size_t ix) const
Get an element using operator() (const version)
size_t total_size() const
Returns the size of the tensor (the product of the sizes over every index)
tensor1()
Create an empty tensor.
Invalid index for array or matrix.
void set(size_t ix1, size_t ix2, size_t ix3, double val)
Set the element indexed by (ix1,ix2,ix3) to value val.
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
std::string szttos(size_t x)
Convert a size_t to a string.
vec_size_t_int size
A rank-sized vector of the sizes of each dimension.
tensor4()
Create an empty tensor.
Tensor class with arbitrary dimensions.
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
size_t get_size(size_t i) const
Returns the size of the ith index.
void set(size_t ix1, size_t ix2, size_t ix3, size_t ix4, double val)
Set the element indexed by (ix1,ix2,ix3,ix4) to value val.