21 #ifndef TENSOR_TENSOR_H
22 #define TENSOR_TENSOR_H
26 #include <tensor/numbers.h>
27 #include <tensor/vector.h>
28 #include <tensor/gen.h>
29 #include <tensor/indices.h>
30 #include <tensor/detail/functional.h>
46 template<
typename elt>
50 typedef elt_t *iterator;
51 typedef const elt_t *const_iterator;
63 Tensor(
const Vector<elt_t> &data);
66 Tensor(
const std::vector<elt_t> &data) :
67 data_(data.
size()), dims_(1)
69 dims_.at(0) = data.size();
70 std::copy(data.begin(), data.end(),
begin());
84 template<
size_t n>
Tensor(
const StaticVector<elt_t,n> &t) :
85 data_(t), dims_(igen << t.
size())
89 template<
size_t n>
Tensor(
const StaticVector<elt_t,n> &t,
const Indices &d) :
92 assert(data_.size() == d.total_size());
96 explicit Tensor(index length);
100 Tensor(index d1, index d2, index d3);
102 Tensor(index d1, index d2, index d3, index d4);
104 Tensor(index d1, index d2, index d3, index d4, index d5);
106 Tensor(index d1, index d2, index d3, index d4, index d5, index d6);
108 operator Vector<elt_t>()
const {
return data_; }
114 index
size()
const {
return data_.size(); }
119 int rank()
const {
return dims_.size(); }
131 void get_dimensions(index *d0, index *d1, index *d2, index *d3)
const;
133 void get_dimensions(index *d0, index *d1, index *d2, index *d3, index *d4)
const;
135 void get_dimensions(index *d0, index *d1, index *d2, index *d3, index *d4, index *d5)
const;
149 const elt_t &
operator()(index row, index col)
const;
151 const elt_t &
operator()(index d0, index d1, index d2)
const;
153 const elt_t &
operator()(index d0, index d1, index d2, index d3)
const;
155 const elt_t &
operator()(index d0, index d1, index d2, index d3, index d4)
const;
157 const elt_t &
operator()(index d0, index d1, index d2, index d3, index d4, index d5w)
const;
164 elt_t &
at(index row, index col);
166 elt_t &
at(index d1, index d2, index d3);
168 elt_t &
at(index d1, index d2, index d3, index d4);
170 elt_t &
at(index d1, index d2, index d3, index d4, index d5);
172 elt_t &
at(index d1, index d2, index d3, index d4, index d5, index d6);
192 static const Tensor<elt_t> random(index d1, index d2, index d3, index d4, index d5, index d6);
203 const view
operator()(PRange r1, PRange r2)
const;
205 const view
operator()(PRange r1, PRange r2, PRange r3)
const;
207 const view
operator()(PRange r1, PRange r2, PRange r3, PRange r4)
const;
209 const view
operator()(PRange r1, PRange r2, PRange r3, PRange r4, PRange r5)
const;
211 const view
operator()(PRange r1, PRange r2, PRange r3, PRange r4, PRange r5, PRange r6)
const;
215 mutable_view
at(PRange r);
217 mutable_view
at(PRange r1, PRange r2);
219 mutable_view
at(PRange r1, PRange r2, PRange r3);
221 mutable_view
at(PRange r1, PRange r2, PRange r3, PRange r4);
223 mutable_view
at(PRange r1, PRange r2, PRange r3, PRange r4, PRange r5);
225 mutable_view
at(PRange r1, PRange r2, PRange r3, PRange r4, PRange r5, PRange r6);
245 static const Tensor<elt_t> zeros(index d1, index d2, index d3, index d4, index d5, index d6);
256 iterator
begin() {
return data_.begin(); }
258 const_iterator
begin()
const {
return data_.begin_const(); }
260 const_iterator
begin_const()
const {
return data_.begin_const(); }
262 const_iterator
end_const()
const {
return data_.end_const(); }
264 const_iterator
end()
const {
return data_.end_const(); }
266 iterator
end() {
return data_.end(); }
269 int ref_count()
const {
return data_.ref_count(); }
273 return take_diag(*
this, which, ndx1, ndx2);
288 Tensor<t> operator-(
const Tensor<t> &);
293 template<
typename t1,
typename t2>
294 Tensor<typename Binop<t1,t2>::type> operator+(
const Tensor<t1> &a,
const Tensor<t2> &b);
295 template<
typename t1,
typename t2>
296 Tensor<typename Binop<t1,t2>::type> operator-(
const Tensor<t1> &a,
const Tensor<t2> &b);
297 template<
typename t1,
typename t2>
298 Tensor<typename Binop<t1,t2>::type> operator*(
const Tensor<t1> &a,
const Tensor<t2> &b);
299 template<
typename t1,
typename t2>
300 Tensor<typename Binop<t1,t2>::type> operator/(
const Tensor<t1> &a,
const Tensor<t2> &b);
302 template<
typename t1,
typename t2>
303 Tensor<typename Binop<t1,t2>::type> operator+(
const Tensor<t1> &a,
const t2 &b);
304 template<
typename t1,
typename t2>
305 Tensor<typename Binop<t1,t2>::type> operator-(
const Tensor<t1> &a,
const t2 &b);
306 template<
typename t1,
typename t2>
307 Tensor<typename Binop<t1,t2>::type> operator*(
const Tensor<t1> &a,
const t2 &b);
308 template<
typename t1,
typename t2>
309 Tensor<typename Binop<t1,t2>::type> operator/(
const Tensor<t1> &a,
const t2 &b);
311 template<
typename t1,
typename t2>
312 Tensor<typename Binop<t1,t2>::type> operator+(
const t1 &a,
const Tensor<t2> &b);
313 template<
typename t1,
typename t2>
314 Tensor<typename Binop<t1,t2>::type> operator-(
const t1 &a,
const Tensor<t2> &b);
315 template<
typename t1,
typename t2>
316 Tensor<typename Binop<t1,t2>::type> operator*(
const t1 &a,
const Tensor<t2> &b);
317 template<
typename t1,
typename t2>
318 Tensor<typename Binop<t1,t2>::type> operator/(
const t1 &a,
const Tensor<t2> &b);
320 template<
typename elt_t>
321 const Tensor<elt_t> kron(
const Tensor<elt_t> &a,
const Tensor<elt_t> &b);
322 template<
typename elt_t>
323 const Tensor<elt_t> kron2(
const Tensor<elt_t> &a,
const Tensor<elt_t> &b);
324 template<
typename elt_t>
325 const Tensor<elt_t> kron2_sum(
const Tensor<elt_t> &a,
const Tensor<elt_t> &b);
332 #ifdef TENSOR_LOAD_IMPL
333 #include <tensor/detail/tensor_base.hpp>
334 #include <tensor/detail/tensor_matrix.hpp>
335 #include <tensor/detail/tensor_kron.hpp>
337 #include <tensor/detail/tensor_slice.hpp>
338 #include <tensor/detail/tensor_ops.hpp>
346 extern template class Tensor<double>;
354 const RTensor change_dimension(
const RTensor &U,
int dimension, index new_size);
360 double norm0(
const RTensor &r);
362 double norm2(
const RTensor &r);
363 double matrix_norminf(
const RTensor &r);
377 const RTensor diag(
const RTensor &d,
int which,
int rows,
int cols);
380 double trace(
const RTensor &d);
392 const RTensor permute(
const RTensor &a, index ndx1 = 0, index ndx2 = -1);
394 inline const RTensor adjoint(
const RTensor &a) {
return transpose(a); }
396 const RTensor fold(
const RTensor &a,
int ndx1,
const RTensor &b,
int ndx2);
397 const RTensor foldc(
const RTensor &a,
int ndx1,
const RTensor &b,
int ndx2);
398 const RTensor foldin(
const RTensor &a,
int ndx1,
const RTensor &b,
int ndx2);
399 const RTensor mmult(
const RTensor &a,
const RTensor &b);
401 void fold_into(RTensor &output,
const RTensor &a,
int ndx1,
const RTensor &b,
int ndx2);
402 void foldin_into(RTensor &output,
const RTensor &a,
int ndx1,
const RTensor &b,
int ndx2);
403 void mmult_into(RTensor &output,
const RTensor &a,
const RTensor &b);
405 bool all_equal(
const RTensor &a,
const RTensor &b);
406 bool all_equal(
const RTensor &a,
double b);
407 inline bool all_equal(
double b,
const RTensor &a) {
return all_equal(a, b); }
408 template<
typename t1,
typename t2>
409 inline bool some_unequal(
const t1 &a,
const t2 &b) {
return !all_equal(a,b); }
411 const Booleans operator==(
const RTensor &a,
const RTensor &b);
412 const Booleans operator<(
const RTensor &a,
const RTensor &b);
413 const Booleans operator>(
const RTensor &a,
const RTensor &b);
414 const Booleans operator<=(
const RTensor &a,
const RTensor &b);
415 const Booleans operator>=(
const RTensor &a,
const RTensor &b);
416 const Booleans operator!=(
const RTensor &a,
const RTensor &b);
418 const Booleans operator==(
const RTensor &a,
double b);
419 const Booleans operator<(
const RTensor &a,
double b);
420 const Booleans operator>(
const RTensor &a,
double b);
421 const Booleans operator<=(
const RTensor &a,
double b);
422 const Booleans operator>=(
const RTensor &a,
double b);
423 const Booleans operator!=(
const RTensor &a,
double b);
425 inline const Booleans operator==(
double a,
const RTensor &b) {
return b == a; }
426 inline const Booleans operator<(
double a,
const RTensor &b) {
return b >= a; }
427 inline const Booleans operator>(
double a,
const RTensor &b) {
return b <= a; }
428 inline const Booleans operator<=(
double a,
const RTensor &b) {
return b > a; }
429 inline const Booleans operator>=(
double a,
const RTensor &b) {
return b < a; }
430 inline const Booleans operator!=(
double a,
const RTensor &b) {
return b != a; }
432 extern template class Tensor<cdouble>;
440 const CTensor change_dimension(
const CTensor &U,
int dimension, index new_size);
443 cdouble mean(
const CTensor &r);
446 double norm0(
const CTensor &r);
448 double norm2(
const CTensor &r);
449 double matrix_norminf(
const CTensor &r);
452 const RTensor imag(
const RTensor &r);
453 const RTensor real(
const CTensor &r);
454 const RTensor imag(
const CTensor &r);
456 const CTensor to_complex(
const RTensor &r);
457 inline const CTensor to_complex(
const CTensor &r) {
return r; }
458 const CTensor to_complex(
const RTensor &r,
const RTensor &i);
462 const CTensor conj(
const CTensor &c);
464 RTensor abs(
const CTensor &t);
465 CTensor cos(
const CTensor &t);
466 CTensor sin(
const CTensor &t);
467 CTensor tan(
const CTensor &t);
468 CTensor cosh(
const CTensor &t);
469 CTensor sinh(
const CTensor &t);
470 CTensor tanh(
const CTensor &t);
471 CTensor exp(
const CTensor &t);
472 CTensor sqrt(
const CTensor &t);
474 const CTensor diag(
const CTensor &d,
int which,
int rows,
int cols);
475 const CTensor diag(
const CTensor &d,
int which = 0);
476 const CTensor
take_diag(
const CTensor &d,
int which = 0,
int ndx1 = 0,
int ndx2 = -1);
477 cdouble trace(
const CTensor &d);
478 const CTensor trace(
const CTensor &A, index i1, index i2);
480 const CTensor
reshape(
const CTensor &t,
const Indices &new_dims);
481 const CTensor
reshape(
const CTensor &t, index length);
482 const CTensor
reshape(
const CTensor &t, index rows, index columns);
483 const CTensor
reshape(
const CTensor &t, index d1, index d2, index d3);
484 const CTensor
reshape(
const CTensor &t, index d1, index d2, index d3, index d4);
485 const CTensor
reshape(
const CTensor &t, index d1, index d2, index d3, index d4, index d5);
486 const CTensor
reshape(
const CTensor &t, index d1, index d2, index d3, index d4, index d5, index d6);
488 const CTensor
squeeze(
const CTensor &t);
489 const CTensor permute(
const CTensor &a, index ndx1 = 0, index ndx2 = -1);
490 const CTensor transpose(
const CTensor &a);
491 const CTensor adjoint(
const CTensor &a);
493 const CTensor fold(
const CTensor &a,
int ndx1,
const CTensor &b,
int ndx2);
494 const CTensor fold(
const RTensor &a,
int ndx1,
const CTensor &b,
int ndx2);
495 const CTensor fold(
const CTensor &a,
int ndx1,
const RTensor &b,
int ndx2);
497 const CTensor foldc(
const CTensor &a,
int ndx1,
const CTensor &b,
int ndx2);
498 const CTensor foldc(
const RTensor &a,
int ndx1,
const CTensor &b,
int ndx2);
499 const CTensor foldc(
const CTensor &a,
int ndx1,
const RTensor &b,
int ndx2);
501 const CTensor mmult(
const CTensor &a,
const CTensor &b);
502 const CTensor mmult(
const RTensor &a,
const CTensor &b);
503 const CTensor mmult(
const CTensor &a,
const RTensor &b);
505 const RTensor scale(
const RTensor &t,
int ndx1,
const RTensor &v);
506 const CTensor scale(
const CTensor &t,
int ndx1,
const CTensor &v);
507 const CTensor scale(
const CTensor &t,
int ndx1,
const RTensor &v);
508 void scale_inplace(RTensor &t,
int ndx1,
const RTensor &v);
509 void scale_inplace(CTensor &t,
int ndx1,
const CTensor &v);
510 void scale_inplace(CTensor &t,
int ndx1,
const RTensor &v);
512 const CTensor foldin(
const CTensor &a,
int ndx1,
const CTensor &b,
int ndx2);
514 const RTensor
linspace(
double min,
double max, index n = 100);
515 const RTensor
linspace(
const RTensor &min,
const RTensor &max, index n = 100);
516 const CTensor
linspace(cdouble min, cdouble max, index n = 100);
517 const CTensor
linspace(
const CTensor &min,
const CTensor &max, index n = 100);
519 const RTensor sort(
const RTensor &v,
bool reverse =
false);
520 const Indices sort_indices(
const RTensor &v,
bool reverse =
false);
522 const CTensor sort(
const CTensor &v,
bool reverse =
false);
523 const Indices sort_indices(
const CTensor &v,
bool reverse =
false);
525 bool all_equal(
const CTensor &a,
const CTensor &b);
526 bool all_equal(
const CTensor &a,
const cdouble &b);
527 inline bool all_equal(cdouble b,
const CTensor &a) {
return all_equal(a, b); }
529 const Booleans operator==(
const CTensor &a,
const CTensor &b);
530 const Booleans operator!=(
const CTensor &a,
const CTensor &b);
531 const Booleans operator==(
const CTensor &a, cdouble b);
532 const Booleans operator!=(
const CTensor &a, cdouble b);
533 inline const Booleans operator==(cdouble a,
const CTensor &b) {
return b == a; }
534 inline const Booleans operator!=(cdouble a,
const CTensor &b) {
return b != a; }
const Tensor & operator=(const Tensor< elt_t > &other)
Assignment operator.
void randomize()
Fills with random numbers.
int rank() const
Number of Tensor indices.
Tensor(const StaticVector< elt_t, n > &t)
Create a one-dimensional tensor from data created with "gen" expressions.
const CTensor reshape(const CTensor &t, index d1, index d2, index d3, index d4, index d5, index d6)
Return a CTensor with same data and given dimensions.
Tensor(const Tensor< e2 > &other)
Implicit coercion.
Tensor()
Constructs an empty Tensor.
An N-dimensional array of numbers.
const CTensor linspace(const CTensor &min, const CTensor &max, index n=100)
Tensor of 'n' equally spaced vectors in the interval [min, max].
index columns() const
Query the size of 2nd index.
static const Tensor< elt_t > eye(index rows)
Identity matrix.
static const Tensor< elt_t > zeros(index rows)
Matrix of zeros.
iterator end()
Iterator at the end.
index rows() const
Query then size of 1st index.
Real Tensor with elements of type "double".
const_iterator begin_const() const
Iterator at the beginning for const objects.
void fill_with_zeros()
Fill with zeros.
bool is_empty() const
Does the tensor have elements?
iterator begin()
Iterator at the beginning.
static const Tensor< elt_t > ones(index rows)
Matrix of ones.
Complex Tensor with elements of type "cdouble".
static const Tensor< elt_t > random(index length)
Build a random 1D Tensor.
const_iterator begin() const
Iterator at the beginning.
index size() const
Returns total number of elements in Tensor.
Vector of 'index' type, where 'index' fits the indices of a tensor.
const_iterator end_const() const
Iterator at the end for const objects.
Tensor(const std::vector< elt_t > &data)
Constructs a 1-D Tensor from a vector.
void fill_with(const elt_t &e)
Fill with an element.
index dimension(int which) const
Length of a given Tensor index.
Tensor(const StaticVector< elt_t, n > &t, const Indices &d)
Create a general tensor from data created with "gen" expressions.
void reshape(const Indices &new_dims)
Change the dimensions, while keeping the data.
const CTensor squeeze(const CTensor &t)
Eliminate all singleton dimensions from a tensor, preserving the data.
const elt_t & operator()(index i) const
Return an element of a 1D Tensor.
const Indices & dimensions() const
Return Tensor dimensions.
elt_t & at_seq(index i)
Return a mutable reference to the i-th element of a Tensor, in column major order.
void get_dimensions(index *length) const
Query dimensions of 1D Tensor.
const_iterator end() const
Iterator at the end for const objects.
const CTensor take_diag(const CTensor &d, int which=0, int ndx1=0, int ndx2=-1)
Extract a diagonal from a matrix or tensor.
const elt_t & operator[](index i) const
Return the i-th element, accessed in column major order.
elt_t & at(index i)
Return a mutable reference to an element of a 1D Tensor.
const Tensor< elt_t > diag(int which=0, int ndx1=0, int ndx2=-1)
Take a diagonal from a tensor.