All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tensor.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2006-2014, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 #ifndef O2SCL_TENSOR_H
24 #define O2SCL_TENSOR_H
25 
26 /** \file tensor.h
27  \brief File defining \ref o2scl::tensor and rank-specific children
28 */
29 #include <iostream>
30 #include <cstdlib>
31 #include <string>
32 #include <fstream>
33 #include <sstream>
34 
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>
39 
40 #include <gsl/gsl_matrix.h>
41 #include <gsl/gsl_ieee_utils.h>
42 
43 #include <o2scl/err_hnd.h>
44 #include <o2scl/interp.h>
45 
46 #ifndef DOXYGEN_NO_O2NS
47 namespace o2scl {
48 #endif
49 
50  /** \brief Tensor class with arbitrary dimensions
51 
52  The elements of a tensor are typically specified as a list of
53  <tt>size_t</tt> numbers with length equal to the tensor rank.
54  For a rank-4 tensor named \c t, the element
55  <tt>t[1][2][0][3]</tt> can be obtained with something similar to
56  \code
57  size_t ix[4]={1,2,0,3};
58  double x=t.get(ix);
59  \endcode
60 
61  Empty tensors have zero rank.
62 
63  Slices of tensors are subsets obtained from fixing the index of
64  several dimensions, while letting other dimensions vary. For a
65  slice with one dimension not fixed, see \ref vector_slice().
66  \comment
67  For a slice with two dimensions not fixed, see \ref matrix_slice().
68  \endcomment
69 
70  For I/O with tensors, see \ref o2scl_hdf::hdf_file::setd_ten()
71  and \ref o2scl_hdf::hdf_file::getd_ten() .
72 
73  The storage pattern is a generalization of row-major order.
74  In the case of a 4-rank tensor, the location of a generic
75  element is
76  \f[
77  \left( \left( i_0 s_1 + i_1 \right) s_2 + i_2 \right) s_3 + i_3 \, .
78  \f]
79  In this case the distance between two elements \f$(i_0,i_1,
80  i_2,i_3)\f$ and \f$ (i_0+1,i_1,i_2,i_3) \f$ is \f$ s_1 s_2 s_3
81  \f$,the distance between two elements \f$(i_0,i_1,i_2,
82  i_3)\f$ and \f$ (i_0,i_1+1,i_2,i_3) \f$ is \f$ s_2 s_3 \f$, and
83  the distance between two elements \f$(i_0,i_1,i_2,i_3)\f$ and
84  \f$ (i_0,i_1,i_2,i_3+1) \f$ is just unity.
85 
86  \todo Specify somewhere what kind of vector types can be used
87  for the template parameter. ublas objects work, but what about
88  armadillo and Eigen vectors? The main reason the default type is
89  std::vector is because of HDF5 I/O.
90 
91  \todo The \ref o2scl::tensor::vector_slice() function should
92  clearly work for uBlas vectors, and seems to work with
93  std::vector objects also, but latter use has not been fully
94  tested.
95 
96  \future Create an operator[] for tensor and not just tensor1?
97 
98  \future Could implement arithmetic operators + and - and some
99  different products.
100 
101  \future Implement copies to and from vector
102  and matrices
103 
104  \future Implement tensor contractions, i.e. tensor
105  = tensor * tensor
106 
107  \future Consider making a template type to replace double,
108  e.g. <tt>value_t</tt>.
109 
110  \future Could be interesting to write an iterator for this class.
111 
112  \future Create an is_valid() function which checks sizes
113  \comment
114  A tensor is defined to be empty if it's rank is zero. A tensor's
115  rank should be zero if and only if no memory has been allocated
116  for it.
117  \endcomment
118 
119  */
120  template<class vec_t=std::vector<double>,
121  class vec_size_t_int=std::vector<size_t> > class tensor {
122 
123  public:
124 
125 #ifndef DOXYGEN_INTERNAL
126 
127  protected:
128 
129  /// The data
130  vec_t data;
131 
132  /// A rank-sized vector of the sizes of each dimension
133  vec_size_t_int size;
134 
135  /// Rank
136  size_t rk;
137 
138 #endif
139 
140  public:
141 
142  /// Create an empty tensor with zero rank
143  tensor() {
144  rk=0;
145  }
146 
147  /** \brief Create a tensor of rank \c rank with sizes given in \c dim
148 
149  The parameter \c dim must be a pointer to a vector of sizes with
150  length \c rank. If the user requests any of the sizes to be
151  zero, this constructor will call the error handler, create an
152  empty tensor, and will allocate no memory.
153  */
154  template<class size_vec_t>
155  tensor(size_t rank, const size_vec_t &dim) {
156  if (rank==0) {
157  rk=0;
158  } else {
159  rk=rank;
160  for(size_t i=0;i<rk;i++) {
161  if (dim[i]==0) {
162  rk=0;
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(),
166  exc_einval);
167  }
168  }
169  size.resize(rk);
170  size_t tot=1;
171  for(size_t i=0;i<rk;i++) {
172  size[i]=dim[i];
173  tot*=size[i];
174  }
175  data.resize(tot);
176  }
177  }
178 
179  ~tensor() {
180  }
181 
182  /// \name Set functions
183  //@{
184  /// Set the element indexed by \c index to value \c val
185  template<class size_vec_t>
186  void set(const size_vec_t &index, double val) {
187 #if O2SCL_NO_RANGE_CHECK
188 #else
189  if (rk==0) {
190  O2SCL_ERR("Empty tensor in tensor::set().",exc_einval);
191  }
192  if (index[0]>=size[0]) {
193  O2SCL_ERR((((std::string)"Value of index[0]=")+szttos(index[0])+
194  " greater than or equal to size[0]="+
195  szttos(size[0])+" in tensor::set().").c_str(),
196  exc_eindex);
197  }
198 #endif
199  size_t ix=index[0];
200  for(size_t i=1;i<rk;i++) {
201 #if O2SCL_NO_RANGE_CHECK
202 #else
203  if (index[i]>=size[i]) {
204  O2SCL_ERR((((std::string)"Value of index[")+szttos(i)+"]="+
205  szttos(index[i])+" greater than or equal to size "+
206  szttos(size[i])+" in tensor::set().").c_str(),
207  exc_eindex);
208  }
209 #endif
210  ix*=size[i];
211  ix+=index[i];
212  }
213  data[ix]=val;
214  return;
215  }
216 
217  /// Set all elements in a tensor to some fixed value
218  void set_all(double x) {
219  for(size_t i=0;i<total_size();i++) data[i]=x;
220  return;
221  }
222  //@}
223 
224  /// \name Get functions
225  //@{
226  /// Get the element indexed by \c index
227  template<class size_vec_t> double &get(const size_vec_t &index) {
228 #if O2SCL_NO_RANGE_CHECK
229 #else
230  if (rk==0) {
231  O2SCL_ERR("Empty tensor in tensor::get().",exc_einval);
232  }
233  if (index[0]>=size[0]) {
234  O2SCL_ERR((((std::string)"Value of index[0]=")+szttos(index[0])+
235  " greater than or equal to size[0]="+
236  szttos(size[0])+" in tensor::get().").c_str(),
237  exc_eindex);
238  }
239 #endif
240  size_t ix=index[0];
241  for(size_t i=1;i<rk;i++) {
242 #if O2SCL_NO_RANGE_CHECK
243 #else
244  if (index[i]>=size[i]) {
245  O2SCL_ERR((((std::string)"Value of index[")+szttos(i)+"]="+
246  szttos(index[i])+" greater than or equal to size "+
247  szttos(size[i])+" in tensor::get().").c_str(),
248  exc_eindex);
249  }
250 #endif
251  ix*=size[i];
252  ix+=index[i];
253  }
254  return data[ix];
255  }
256 
257  /// Get a const reference to the element indexed by \c index
258  template<class size_vec_t>
259  double const &get(const size_vec_t &index) const {
260 #if O2SCL_NO_RANGE_CHECK
261 #else
262  if (rk==0) {
263  O2SCL_ERR("Empty tensor in tensor::get() (const).",exc_einval);
264  }
265  if (index[0]>=size[0]) {
266  O2SCL_ERR((((std::string)"Value of index[0]=")+szttos(index[0])+
267  " greater than or equal to size[0]="+
268  szttos(size[0])+" in tensor::get() (const).").c_str(),
269  exc_eindex);
270  }
271 #endif
272  size_t ix=index[0];
273  for(size_t i=1;i<rk;i++) {
274 #if O2SCL_NO_RANGE_CHECK
275 #else
276  if (index[i]>=size[i]) {
277  O2SCL_ERR((((std::string)"Value of index[")+szttos(i)+"]="+
278  szttos(index[i])+" greater than or equal to size "+
279  szttos(size[i])+" in tensor::get() (const).").c_str(),
280  exc_eindex);
281  }
282 #endif
283  ix*=size[i];
284  ix+=index[i];
285  }
286  return data[ix];
287  }
288  //@}
289 
290 #ifndef O2SCL_NEVER_DEFINED
291 
292  typedef boost::numeric::ublas::vector_slice<
293  boost::numeric::ublas::vector<double> > ubvector_slice;
294  typedef boost::numeric::ublas::slice slice;
295 
296  /// \name Slice function
297  //@{
298  /** \brief Fix all but one index to create a vector
299 
300  This fixes all of the indices to the values given in \c index
301  except for the index number \c ix, and returns the
302  corresponding vector, whose length is equal to the size of the
303  tensor in that index. The value <tt>index[ix]</tt> is ignored.
304 
305  For example, for a rank 3 tensor allocated with
306  \code
307  tensor t;
308  size_t dim[3]={3,4,5};
309  t.resize(3,dim);
310  \endcode
311  the following code
312  \code
313  size_t index[3]={1,0,3};
314  ubvector_view v=t.vector_slice(1,index);
315  \endcode
316  Gives a vector \c v of length 4 which refers to the values
317  <tt>t(1,0,3)</tt>, <tt>t(1,1,3)</tt>, <tt>t(1,2,3)</tt>, and
318  <tt>t(1,3,3)</tt>.
319  */
320  template<class size_vec_t>
321  ubvector_slice vector_slice(size_t ix, const size_vec_t &index) {
322  if (ix+1>rk) {
323  O2SCL_ERR((((std::string)"Specified index ")+szttos(ix)+
324  " greater than or equal to rank "+szttos(rk)+
325  " in tensor::vector_slice()").c_str(),
326  exc_eindex);
327  }
328  size_t start;
329  if (ix==0) start=0;
330  else start=index[0];
331  for(size_t i=1;i<rk;i++) {
332  start*=size[i];
333  if (i!=ix) start+=index[i];
334  }
335  size_t stride=1;
336  for(size_t i=ix+1;i<rk;i++) stride*=size[i];
337  return ubvector_slice(data,slice(start,stride,size[ix]));
338  }
339  //@}
340 
341 #endif
342 #ifdef O2SCL_NEVER_DEFINED
343 
344  /** \brief Fix all but two indices to create a matrix
345 
346  One could use ublas::make_matrix_from_pointer() and
347  then ublas matrix slicing to perform this operation, but
348  only if data was guaranteed to have contiguous storage.
349  Currently, since data is a ubvector, this doesn't work.
350  */
351  template<class size_vec_t> ubmatrix_array matrix_slice() {
352  }
353 
354 #endif
355 
356  /// \name Resize method
357  //@{
358  /** \brief Resize the tensor to rank \c rank with sizes
359  given in \c dim
360 
361  The parameter \c dim must be a vector of sizes with a length
362  equal to \c rank. This resize method is always destructive.
363 
364  If the user requests any of the sizes to be zero, this
365  function will call the error handler.
366  */
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++) {
370  if (dim[i]==0) {
371  O2SCL_ERR((((std::string)"Requested zero size with non-zero ")+
372  "rank for index "+szttos(i)+" in tensor::"+
373  "resize().").c_str(),exc_einval);
374  }
375  }
376  rk=rank;
377  size.resize(rk);
378  if (rk==0) {
379  data.resize(0);
380  } else {
381  size_t tot=1;
382  for(size_t i=0;i<rk;i++) {
383  size[i]=dim[i];
384  tot*=size[i];
385  }
386  data.resize(tot);
387  }
388  return;
389  }
390  //@}
391 
392  /// \name Size functions
393  //@{
394  /// Return the rank of the tensor
395  size_t get_rank() const { return rk; }
396 
397  /// Returns the size of the ith index
398  size_t get_size(size_t i) const {
399  if (i>=rk) {
400  O2SCL_ERR((((std::string)"Specified index ")+szttos(i)+
401  " greater than or equal to rank "+szttos(rk)+
402  " in tensor::get_size()").c_str(),
403  exc_einval);
404  }
405  return size[i];
406  }
407 
408  /// Return the full vector of sizes
409  const vec_size_t_int &get_size_arr() const {
410  return size;
411  }
412 
413  /// Return the full data vector
414  const vec_t &get_data() const {
415  return data;
416  }
417 
418  /** \brief Returns the size of the tensor (the product of
419  the sizes over every index)
420  */
421  size_t total_size() const {
422  if (rk==0) return 0;
423  size_t tot=1;
424  for(size_t i=0;i<rk;i++) tot*=size[i];
425  return tot;
426  }
427  //@}
428 
429  /// \name Index manipulation
430  //@{
431  /// Pack the indices into a single vector index
432  template<class size_vec_t>
433  size_t pack_indices(const size_vec_t &index) {
434  if (rk==0) {
435  O2SCL_ERR("Empty tensor in tensor::pack_indices().",exc_einval);
436  return 0;
437  }
438  if (index[0]>=size[0]) {
439  O2SCL_ERR((((std::string)"Value of index[0]=")+szttos(index[0])+
440  " greater than or equal to size[0]="+
441  szttos(size[0])+" in tensor::pack_indices().").c_str(),
442  exc_eindex);
443  }
444  size_t ix=index[0];
445  for(size_t i=1;i<rk;i++) {
446  if (index[i]>=size[i]) {
447  O2SCL_ERR((((std::string)"Value of index[")+szttos(i)+"]="+
448  szttos(index[i])+" greater than or equal to size "+
449  szttos(size[i])+" in tensor::pack_indices().").c_str(),
450  exc_eindex);
451  }
452  ix*=size[i];
453  ix+=index[i];
454  }
455  return ix;
456  }
457 
458  /// Unpack the single vector index into indices
459  template<class size_vec_t>
460  void unpack_indices(size_t ix, size_vec_t &index) {
461  if (ix>=total_size()) {
462  O2SCL_ERR((((std::string)"Value of index ")+szttos(ix)+
463  " greater than or equal to total size"+
464  szttos(total_size())+
465  " in tensor::unpack_indices().").c_str(),
466  exc_eindex);
467  return;
468  }
469  size_t ix2, sub_size;
470  for(size_t i=0;i<rk;i++) {
471  if (i==rk-1) {
472  index[i]=ix;
473  } else {
474  sub_size=1;
475  for(size_t j=i+1;j<rk;j++) sub_size*=size[j];
476  index[i]=ix/sub_size;
477  // (Remember we're doing integer arithmetic here.)
478  ix-=sub_size*(ix/sub_size);
479  }
480  }
481  return;
482  }
483  //@}
484 
485  };
486 
487  /** \brief Rank 1 tensor
488  */
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> {
492 
493  public:
494 
495  /// Create an empty tensor
496  tensor1() : tensor<vec_t,vec_size_t_int>() {}
497 
498  /// Create a rank 1 tensory of size \c sz
499  tensor1(size_t sz) : tensor<vec_t,vec_size_t_int>() {
500  vec_size_t_int sizex(1);
501  sizex[0]=sz;
502  this->resize(1,sizex);
503  }
504 
505  /// Get the element indexed by \c ix
506  double &get(size_t ix) {
508  }
509 
510  /// Get the element indexed by \c ix
511  const double &get(size_t ix) const {
513  }
514 
515  /// Set the element indexed by \c index to value \c val
516  void set(size_t index, double val)
517  { tensor<vec_t,vec_size_t_int>::set(&index,val); }
518 
519  /** \brief Set the element indexed by \c index to value \c val
520 
521  (We have to explicitly provide this version since the set()
522  function is overloaded in this child of \ref tensor.)
523  */
524  template<class size_vec_t>
525  void set(const size_vec_t &index, double val) {
527  }
528 
529  /// Get an element using array-like indexing
530  double &operator[](size_t ix) { return this->data[ix]; }
531 
532  /// Get an element using array-like indexing (const version)
533  const double &operator[](size_t ix) const { return this->data[ix]; }
534 
535  /// Get an element using operator()
536  double &operator()(size_t ix) { return this->data[ix]; }
537 
538  /// Get an element using operator() (const version)
539  const double &operator()(size_t ix) const { return this->data[ix]; }
540  };
541 
542  /** \brief Rank 2 tensor
543  */
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> {
547 
548  public:
549 
550  /// Create an empty tensor
551  tensor2() : tensor<vec_t,vec_size_t_int>() {}
552 
553  /// Create a rank 2 tensor of size \c (sz,sz2)
554  tensor2(size_t sz, size_t sz2) : tensor<vec_t,vec_size_t_int>() {
555  this->rk=2;
556  this->size.resize(2);
557  this->size[0]=sz;
558  this->size[1]=sz2;
559  size_t tot=sz*sz2;
560  this->data.resize(tot);
561  }
562 
563  /// Get the element indexed by \c (ix1,ix2)
564  double &get(size_t ix1, size_t ix2) {
565  size_t sz[2]={ix1,ix2};
567  }
568 
569  /// Get the element indexed by \c (ix1,ix2)
570  const double &get(size_t ix1, size_t ix2) const {
571  size_t sz[2]={ix1,ix2};
573  }
574 
575  /// Set the element indexed by \c (ix1,ix2) to value \c val
576  void set(size_t ix1, size_t ix2, double val) {
577  size_t sz[2]={ix1,ix2};
579  return;
580  }
581 
582  /** \brief Set the element indexed by \c index to value \c val
583 
584  (We have to explicitly provide this version since the set()
585  function is overloaded in this child of \ref tensor.)
586  */
587  template<class size_vec_t>
588  void set(const size_vec_t &index, double val) {
590  return;
591  }
592 
593  /// Get the element indexed by \c (ix1,ix2)
594  double &operator()(size_t ix, size_t iy)
595  { return this->data[ix*this->size[1]+iy]; }
596 
597  /// Get the element indexed by \c (ix1,ix2) (const version)
598  const double &operator()(size_t ix, size_t iy) const
599  { return this->data[ix*this->size[1]+iy]; }
600  };
601 
602  /** \brief Rank 3 tensor
603  */
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> {
607 
608  public:
609 
610  /// Create an empty tensor
611  tensor3() : tensor<vec_t,vec_size_t_int>() {}
612 
613  /// Create a rank 3 tensor of size \c (sz,sz2,sz3)
614  tensor3(size_t sz, size_t sz2, size_t sz3) :
615  tensor<vec_t,vec_size_t_int>() {
616  this->rk=3;
617  this->size.resize(3);
618  this->size[0]=sz;
619  this->size[1]=sz2;
620  this->size[2]=sz3;
621  size_t tot=sz*sz2*sz3;
622  this->data.resize(tot);
623  }
624 
625  /// Get the element indexed by \c (ix1,ix2,ix3)
626  double &get(size_t ix1, size_t ix2, size_t ix3) {
627  size_t sz[3]={ix1,ix2,ix3};
629  }
630 
631  /// Get the element indexed by \c (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};
635  }
636 
637  /// Set the element indexed by \c (ix1,ix2,ix3) to value \c val
638  void set(size_t ix1, size_t ix2, size_t ix3, double val) {
639  size_t sz[3]={ix1,ix2,ix3};
641  return;
642  }
643 
644  /** \brief Set the element indexed by \c index to value \c val
645 
646  (We have to explicitly provide this version since the set()
647  function is overloaded in this child of \ref tensor.)
648  */
649  template<class size_vec_t>
650  void set(const size_vec_t &index, double val) {
652  return;
653  }
654 
655  };
656 
657  /** \brief Rank 4 tensor
658  */
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> {
662 
663  public:
664 
665  /// Create an empty tensor
666  tensor4() : tensor<vec_t,vec_size_t_int>() {}
667 
668  /// Create a rank 4 tensor of size \c (sz,sz2,sz3,sz4)
669  tensor4(size_t sz, size_t sz2, size_t sz3, size_t sz4) :
670  tensor<vec_t,vec_size_t_int>() {
671  this->rk=4;
672  this->size.resize(4);
673  this->size[0]=sz;
674  this->size[1]=sz2;
675  this->size[2]=sz3;
676  this->size[3]=sz4;
677  size_t tot=sz*sz2*sz3*sz4;
678  this->data.resize(tot);
679  }
680 
681  /// Get the element indexed by \c (ix1,ix2,ix3,ix4)
682  double &get(size_t ix1, size_t ix2, size_t ix3, size_t ix4) {
683  size_t sz[4]={ix1,ix2,ix3,ix4};
685  }
686 
687  /// Get the element indexed by \c (ix1,ix2,ix3,ix4)
688  const double &get(size_t ix1, size_t ix2, size_t ix3,
689  size_t ix4) const {
690  size_t sz[4]={ix1,ix2,ix3,ix4};
692  }
693 
694  /// Set the element indexed by \c (ix1,ix2,ix3,ix4) to value \c val
695  void set(size_t ix1, size_t ix2, size_t ix3, size_t ix4,
696  double val) {
697  size_t sz[4]={ix1,ix2,ix3,ix4};
699  return;
700  }
701 
702  /** \brief Set the element indexed by \c index to value \c val
703 
704  (We have to explicitly provide this version since the set()
705  function is overloaded in this child of \ref tensor.)
706  */
707  template<class size_vec_t>
708  void set(const size_vec_t &index, double val) {
710  return;
711  }
712  };
713 
714 #ifndef DOXYGEN_NO_O2NS
715 }
716 #endif
717 
718 #endif
719 
720 
721 
double & operator()(size_t ix)
Get an element using operator()
Definition: tensor.h:536
void set(size_t index, double val)
Set the element indexed by index to value val.
Definition: tensor.h:516
const vec_size_t_int & get_size_arr() const
Return the full vector of sizes.
Definition: tensor.h:409
Rank 1 tensor.
Definition: tensor.h:490
tensor3()
Create an empty tensor.
Definition: tensor.h:611
Rank 3 tensor.
Definition: tensor.h:605
tensor3(size_t sz, size_t sz2, size_t sz3)
Create a rank 3 tensor of size (sz,sz2,sz3)
Definition: tensor.h:614
vec_t data
The data.
Definition: tensor.h:130
tensor1(size_t sz)
Create a rank 1 tensory of size sz.
Definition: tensor.h:499
const vec_t & get_data() const
Return the full data vector.
Definition: tensor.h:414
const double & operator()(size_t ix, size_t iy) const
Get the element indexed by (ix1,ix2) (const version)
Definition: tensor.h:598
invalid argument supplied by user
Definition: err_hnd.h:59
tensor()
Create an empty tensor with zero rank.
Definition: tensor.h:143
tensor(size_t rank, const size_vec_t &dim)
Create a tensor of rank rank with sizes given in dim.
Definition: tensor.h:155
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
Definition: tensor.h:588
double & operator[](size_t ix)
Get an element using array-like indexing.
Definition: tensor.h:530
size_t pack_indices(const size_vec_t &index)
Pack the indices into a single vector index.
Definition: tensor.h:433
size_t rk
Rank.
Definition: tensor.h:136
double & operator()(size_t ix, size_t iy)
Get the element indexed by (ix1,ix2)
Definition: tensor.h:594
void set(size_t ix1, size_t ix2, double val)
Set the element indexed by (ix1,ix2) to value val.
Definition: tensor.h:576
size_t get_rank() const
Return the rank of the tensor.
Definition: tensor.h:395
tensor2()
Create an empty tensor.
Definition: tensor.h:551
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
Definition: tensor.h:650
void set_all(double x)
Set all elements in a tensor to some fixed value.
Definition: tensor.h:218
const double & operator[](size_t ix) const
Get an element using array-like indexing (const version)
Definition: tensor.h:533
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
Definition: tensor.h:186
tensor2(size_t sz, size_t sz2)
Create a rank 2 tensor of size (sz,sz2)
Definition: tensor.h:554
void resize(size_t rank, const size_vec_t &dim)
Resize the tensor to rank rank with sizes given in dim.
Definition: tensor.h:368
double & get(const size_vec_t &index)
Get the element indexed by index.
Definition: tensor.h:227
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Definition: err_hnd.h:273
void unpack_indices(size_t ix, size_vec_t &index)
Unpack the single vector index into indices.
Definition: tensor.h:460
ubvector_slice vector_slice(size_t ix, const size_vec_t &index)
Fix all but one index to create a vector.
Definition: tensor.h:321
tensor4(size_t sz, size_t sz2, size_t sz3, size_t sz4)
Create a rank 4 tensor of size (sz,sz2,sz3,sz4)
Definition: tensor.h:669
const double & operator()(size_t ix) const
Get an element using operator() (const version)
Definition: tensor.h:539
size_t total_size() const
Returns the size of the tensor (the product of the sizes over every index)
Definition: tensor.h:421
Rank 2 tensor.
Definition: tensor.h:545
Rank 4 tensor.
Definition: tensor.h:660
tensor1()
Create an empty tensor.
Definition: tensor.h:496
Invalid index for array or matrix.
Definition: err_hnd.h:123
void set(size_t ix1, size_t ix2, size_t ix3, double val)
Set the element indexed by (ix1,ix2,ix3) to value val.
Definition: tensor.h:638
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
Definition: tensor.h:708
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.
Definition: tensor.h:133
tensor4()
Create an empty tensor.
Definition: tensor.h:666
Tensor class with arbitrary dimensions.
Definition: tensor.h:121
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
Definition: tensor.h:525
size_t get_size(size_t i) const
Returns the size of the ith index.
Definition: tensor.h:398
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.
Definition: tensor.h:695

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).
Hosted at Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads..