TBCI Numerical high perf. C++ Library 2.8.0
tensor.h
Go to the documentation of this file.
1
6// AMB 98/04
7// last modified AMB 980428
8// KG, 981205: added layout in order to provide an effective means to
9// swap indices, Index iterators
10// $Id: tensor.h,v 1.33.2.30 2022/11/03 17:28:11 garloff Exp $
11
12#ifndef TBCI_TENSOR_H
13#define TBCI_TENSOR_H
14
15#include "tbci/vector.h"
16#include "tbci/index.h"
17
18// Avoid -fguiding-decls
19#if !defined(NO_GD) && !defined(AUTO_DECL)
20# include "tbci/tensor_gd.h"
21#endif
22
24
25#ifndef TBCI_DISABLE_EXCEPT
26//#include "except.h" is included in basics.h
27class TensErr : public NumErr
28{
29 public:
31 : NumErr("Error in Tensor class") {}
32 TensErr(const char* t, const long i = 0)
33 : NumErr(t, i) {}
34 TensErr(const TensErr& te)
35 : NumErr(te) {}
36 virtual ~TensErr() throw() {}
37};
38#endif
39
40#ifdef PRAGMA_I
41# pragma interface "tensor.h"
42#endif
43
44//----------------------------------------------------------------
46
50template <typename T>
52{
53
54protected:
55 Vector <T> data; // linear storage
56 unsigned rank; // rank of tensor
57 unsigned long noel; // number of elements
58 Index shape; // shape of tensor, eg. 2x3x4
59 Index layout; // memory layout of tensor, eg. 12,4,1
60 unsigned long calcsize (void)
61 {
62 noel = 1;
63 for (REGISTER unsigned i = 0; i < rank; i++)
64 noel *= shape (i);
65 return noel;
66 }
67 unsigned calclayout ()
68 {
69 unsigned long fac = 1;
70 for (REGISTER int i = rank-1; i >= 0; i--)
71 {
72 layout(i) = fac;
73 fac *= shape(i);
74 }
75 return fac;
76 }
77
78public:
79
80 typedef T value_type;
81 typedef T element_type;
82 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
83
84 CTensor () { rank = 0; } // default constructor
85 explicit CTensor (const unsigned dim_rank); // "square" constructor
86 CTensor (const Index & ix); // standard constructor
87 CTensor (const T & value, const Index & ix); // standard constructor
88 CTensor (const CTensor & ct); // copy constructor
89 CTensor (vararg va, ...); // arbitrary no of arguments
90 CTensor (const T, vararg va, ...); // arb no of arg & ini value
91
93
94 // mapping and reverse mapping
95 unsigned long calc_offs (const Index & ix) const;
96 Index calc_indx (const unsigned long i) const;
97
98 // access
99 //T & operator ()(const TVector<T> & tv) const
100 // { Vector<T> ix(tv); return data (calc_offs (ix)); }
101 T & operator () (const Index & ix)
102 { return data (calc_offs (ix)); }
103 typename tbci_traits<T>::const_refval_type
104 operator () (const Index & ix) const
105 { return data (calc_offs (ix)); }
106 T & operator () (vararg va, ...);
107 typename tbci_traits<T>::const_refval_type
108 operator () (vararg va, ...) const;
109
110 T & operator () (const unsigned long i)
111 { BCHKNR(i>=noel, TensErr, & op(): out of range, i);
112 return data(i); }
113 typename tbci_traits<T>::const_refval_type
114 operator () (const unsigned long i) const
115 { BCHKNR(i>=noel, TensErr, op() c: out of range, i);
116 return data(i); }
117
118 const T& getcref (vararg va, ...) const;
119
120 T& get_lin_idx (const unsigned long i) //const
121 { return (*this)(i); }
122 typename tbci_traits<T>::const_refval_type
123 get_lin_idx (const unsigned long i) const
124 { return (*this)(i); }
125
126#ifndef NO_POD
127 unsigned lin_read (vararg va, ...);
128#endif
129
130 // swap indices
131 CTensor<T>& transpose (const unsigned i, const unsigned j)
132 {
133 BCHK (i>=rank, TensErr, swap_idx: idx1 out of range, i, *this);
134 BCHK (j>=rank, TensErr, swap_idx: idx2 out of range, j, *this);
135 SWAP (shape(i), shape(j)); SWAP (layout(i), layout(j));
136 return *this;
137 }
138
139 // assignment
140 CTensor <T>& fill (const T & value)
141 { data.fill (value); return *this; }
142
143 // resizing equation operator!
145 {
146 rank = ct.rank; shape.resize(ct.shape);
147 layout.resize (ct.layout);
148 noel = ct.noel; data.resize(ct.data);
149 return *this;
150 }
151 CTensor <T>& operator = (const T & value)
152 { return this->fill (value); }
153
154 //misc
156 {
157 shape.resize(ix); rank = ix.size();
158 layout.resize(rank); calclayout ();
159 calcsize(); data.resize (noel);
160 return *this;
161 }
162 CTensor<T>& resize (const T& val, const Index& ix)
163 {
164 shape.resize(ix); rank = ix.size();
165 layout.resize(rank); calclayout ();
166 calcsize(); data.resize (val, noel);
167 return *this;
168 }
170 {
171 shape.resize(ct.shape); layout.resize (ct.layout);
172 rank = ct.rank; noel = ct.noel;
173 data.resize (ct.data);
174 return *this;
175 }
176
177 T max (unsigned long& pos) const { return data.max (pos); }
178 T min (unsigned long& pos) const { return data.min (pos); }
179
180 T max () const { return data.max (); }
181 T min () const { return data.min (); }
182
183 T trace () const { return 0; } // ????????????????????????????
184
185 // compare
187 {
188 if (shape != ct.shape) return false;
189 if (layout == ct.layout) {
190 if (data == ct.data) return true; else return false; }
191 // layout is different, now we are in trouble
192 Index ix(0, rank);
193 while (ix(0) < shape(0))
194 {
195 if ((*this)(ix) != ct(ix)) return false;
196 ix.next_idx (shape);
197 }
198 return true;
199 }
200
202 { return !(this->operator == (ct)); }
203
204 // info
205 unsigned long lin_size (void) const
206 { return noel; }
207 Index index_size (void) const
208 { return shape; }
209 unsigned rank_size (void) const
210 { return rank; }
211
212 // i/o operations
213 friend STD__ ostream & operator << FGD (STD__ ostream&, const CTensor <T>&);
214 friend STD__ istream & operator >> FGD (STD__ istream&, CTensor <T>&);
215
216};
217
218// class CTensor definitions
219
220template < typename T >
221inline CTensor < T >::CTensor (const unsigned dim_rank) :
222 rank (dim_rank), shape (dim_rank, dim_rank), layout (dim_rank)
223 // "square" constructor
224{
225 calcsize (); calclayout ();
226 data.resize (noel);
227}
228
229template < typename T >
230inline CTensor < T >::CTensor (const Index & ix) :
231 rank (ix.size()), shape (ix), layout (ix.size())
232 // standard constructor
233{
234 calcsize (); calclayout ();
235 data.resize (noel);
236}
237
238template < typename T >
239inline CTensor < T >::CTensor (const T & value, const Index & ix) :
240 rank (ix.size()), shape (ix), layout (ix.size())
241 // standard constructor
242{
243 //rank = shape.size ();
244 calcsize (); calclayout ();
245 data.resize (value, noel);
246}
247
248// copy constructor
249template < typename T >
250inline CTensor < T >::CTensor (const CTensor & ct)
251 : data(ct.data), rank(ct.rank), noel(ct.noel),
252 shape(ct.shape), layout(ct.layout)
253{}
254
255// arb. arg. & ini
256template < typename T >
257inline CTensor < T >::CTensor (const T value, vararg va, ...) :
258 rank (va), shape ((unsigned)va), layout ((unsigned)va)
259{
260 va_list vl;
261 va_start (vl, va);
262 for (unsigned i = 0; i < (unsigned)va; ++i)
263 shape (i) = va_arg (vl, unsigned);
264 va_end (vl);
265 calcsize (); calclayout ();
266 data.resize (value, noel);
267}
268
269// arb. arg.
270template < typename T >
271inline CTensor <T>::CTensor (vararg va, ...) :
272 rank (va), shape ((unsigned)va), layout ((unsigned)va)
273{
274 va_list vl;
275 va_start (vl, va);
276 for (unsigned i = 0; i < rank; ++i)
277 shape (i) = va_arg (vl, unsigned);
278 va_end (vl);
279 calcsize (); calclayout ();
280 data.resize (noel);
281}
282
283#ifndef NO_POD
284template < typename T >
285unsigned CTensor < T >::lin_read (vararg va, ...)
286{
287 va_list vl;
288 va_start (vl, va);
289 unsigned i;
290#if !defined(__clang__) || !defined(CPLX)
291 for (i = 0; i < (unsigned)va; ++i)
292 data (i) = va_arg (vl, T);
293#else
294 throw TensErr("vararg not supported for cplx in clang");
295#warning no vararg support with cplx numbers and clang
296#endif
297 va_end (vl);
298 return i;
299}
300#endif
301
302//Calculates eff. index
303template < typename T >
304inline unsigned long CTensor < T >::calc_offs (const Index & ix) const
305{
306 BCHK (rank != ix.size(), TensErr, Rank of Tensor and Index size dont match, ix.size(), 0);
307 unsigned long offs (0);
308 for (REGISTER unsigned i = 0; i < rank; i++)
309 {
310 offs += ix (i) * layout (i);
311 }
312 BCHK (offs >= noel, TensErr, Too large index, offs, offs);
313 return offs;
314}
315
316#if 0
317template < typename T >
318inline Index CTensor < T >::calc_indx (const unsigned long i) const
319{
320 Index ix (rank);
321 unsigned long mod = i;
322 for (unsigned r = rank; r > 0; r--)
323 {
324 ix (r - 1) = mod % shape (r - 1);
325 mod /= shape (r - 1);
326 }
327 BCHK (mod > 0, TensErr, Mapping error, mod, ix);
328 return ix;
329}
330#endif
331
332/* This function is inefficient by design! */
333template < typename T >
334inline Index CTensor < T >::calc_indx (const unsigned long i) const
335{
336 Index ix (rank); ix.fill (0);
337 unsigned long mod = i;
338 BCHK (i >= noel, TensErr, Linear index too large, i, ix);
339 // tricky stuff to start here ...
340 unsigned long maxdiv = noel;
341 while (mod)
342 {
343 // find largest divisor
344 unsigned long div = 0; unsigned ixnr = 0;
345 for (unsigned i = 0; i < rank; i++)
346 if (layout(i) > div && layout(i) < maxdiv && shape(i) > 1)
347 { div = layout(i); ixnr = i; }
348 maxdiv = div;
349 ix(ixnr) = mod / div; mod %= div;
350 }
351 return ix;
352}
353
354
355// formatted output
356template < typename T >
357STD__ ostream & operator << (STD__ ostream & os, const CTensor < T > & ct)
358{
359 if (ct.rank > 1)
360 {
361 //os << "\n";
362 Index ix (0, ct.rank);
363 for (unsigned long i = 0; i < ct.noel; i++)
364 {
365 os << ct(ix) << "\t"; ix.next_idx (ct.shape);
366 for (unsigned j = ct.rank - 1; j > 0; j--)
367 if (ix(j) == 0) os << "\n"; else break;
368 }
369 }
370 else
371 os << ct.data;
372 return os;
373}
374
375template <typename T>
376STD__ istream& operator >> (STD__ istream & is, CTensor<T>& ct)
377{
378 Index ix (0, ct.rank);
379 for (unsigned long i = 0; i < ct.noel; i++)
380 {
381 is >> ct(ix); ix.next_idx (ct.shape);
382 }
383 return is;
384}
385
386//access
387#if 0
388template <typename T>
389T& CTensor <T>::operator () (vararg va, ...) //const
390{
391 Index ix ((unsigned)va);
392 va_list vl;
393 va_start (vl, va);
394 for (unsigned i = 0; i < (unsigned)va; ++i)
395 ix (i) = va_arg (vl, int);
396 va_end (vl);
397 return (*this) (ix);
398}
399
400template <typename T>
401typename tbci_traits<T>::const_refval_type
402CTensor <T>::operator () (vararg va, ...) const
403{
404 Index ix ((unsigned)va);
405 va_list vl;
406 va_start (vl, va);
407 for (unsigned i = 0; i < (unsigned)va; ++i)
408 ix (i) = va_arg (vl, int);
409 va_end (vl);
410 return (*this) (ix);
411}
412
413#else
414
415template <typename T>
416T& CTensor <T>::operator () (vararg va, ...) //const
417{
418 BCHK((unsigned)va != rank, TensErr, vararg no must be eq to rank, (unsigned)va, data(0));
419 unsigned lin_idx = 0;
420 va_list vl;
421 va_start (vl, va);
422 for (unsigned i = 0; i < rank; ++i)
423 lin_idx += va_arg (vl, int) * layout(i);
424 va_end (vl);
425 return (data (lin_idx));
426}
427
428template <typename T>
429typename tbci_traits<T>::const_refval_type
430CTensor <T>::operator () (vararg va, ...) const
431{
432 BCHK((unsigned)va != rank, TensErr, vararg no must be eq to rank, (unsigned)va, data(0));
433 unsigned lin_idx = 0;
434 va_list vl;
435 va_start (vl, va);
436 for (unsigned i = 0; i < rank; ++i)
437 lin_idx += va_arg (vl, int) * layout(i);
438 va_end (vl);
439 return (data (lin_idx));
440}
441#endif
442
443
444template <typename T>
445const T& CTensor <T>::getcref (vararg va, ...) const
446{
447 BCHK((unsigned)va != rank, TensErr, vararg no must be eq to rank, (unsigned)va, data.getcref(0));
448 unsigned lin_idx = 0;
449 va_list vl;
450 va_start (vl, va);
451 for (unsigned i = 0; i < rank; ++i)
452 lin_idx += va_arg (vl, int) * layout(i);
453 va_end (vl);
454 return data.getcref (lin_idx);
455}
456
457
458//-----------------------------------------------------------------------------
459
460
464
465template<typename T>
466class Tensor : public CTensor<T>
467{
468
469protected:
470 // additional data structure
471
472public:
473
474 typedef T value_type;
476 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
477 // constructors
478 Tensor () : CTensor <T> () {}
479 Tensor (const unsigned dim_rank) : CTensor <T> (dim_rank) {}
480 Tensor (const Index & ix) : CTensor <T> (ix) {}
481 Tensor (const T & value, const Index & ix) : CTensor <T> (value, ix) {}
482 Tensor (const Tensor <T>& ct) : CTensor <T> (ct) {}
483 Tensor (vararg va, ...);
484 Tensor (const T, vararg va, ...);
486
487 // basic arithmetics
490
491 Tensor<T> operator + (const Tensor<T> &) const;
492 Tensor<T> operator - (const Tensor<T> &) const;
493
494 Tensor<T>& operator *= (const T m) { this->data *= m; return *this; }
495 Tensor<T>& operator /= (const T m) { this->data /= m; return *this; }
496 Tensor<T>& operator += (const T m) { this->data += m; return *this; }
497 Tensor<T>& operator -= (const T m) { this->data -= m; return *this; }
498
499 Tensor<T> operator * (const T m) const
500 {
501 Tensor<T> r (this->shape);
502 for (unsigned long i = 0; i < this->noel; ++i)
503 r.data(i) = this->data(i) * m;
504 return r;
505 }
506
507
508 //for friend NOINST Tensor<T> operator * FGD (const T, const Tensor<T> &);
509 Tensor<T> mult (const T) const;
510
511 Tensor<T> operator / (const T m) const
512 {
513 Tensor<T> r (this->shape);
514 for (unsigned long i = 0; i < this->noel; ++i)
515 r.data(i) = this->data(i) / m;
516 return r;
517 }
518
520 {
521 Tensor<T> r (this->shape);
522 for (unsigned long i=0; i < this->noel; ++i)
523 r.data(i) = - this->data(i);
524 return r;
525 }
526
527 // tensor arithmetics
528 Tensor<T> contract (const unsigned, const unsigned) const; // contraction over 2 indices
529 // direct tensor product
530 Tensor<T> drctmul (const Tensor<T>&) const;
532 // multiplication with contraction over 2 indices
533 Tensor<T> cntrmul (const Tensor<T>&, const unsigned, const unsigned) const;
534 friend Tensor<T> FRIEND_TBCI2__ ctrmul FGD (const Tensor<T>&, const Tensor<T>&, const unsigned, const unsigned);
535 // multiplication w/ metric results in differently ordered indices comp. to cntrmul
536 friend Tensor<T> FRIEND_TBCI2__ metrmul FGD (const Tensor<T>&, const Tensor<T>&, const unsigned, const unsigned);
537
538};
539
540
541//implementations of class Tensor
542
543
544// arb. arg. & ini
545template < typename T >
546inline Tensor < T >::Tensor (const T value, vararg va, ...)
547 //: CTensor<T>::rank (va.num), CTensor<T>::layout (va.num), CTensor<T>::shape (va.num)
548{
549 this->rank = va;
550 this->layout.resize ((unsigned)va);
551 this->shape.resize ((unsigned)va);
552 va_list vl;
553 va_start (vl, va);
554 for (unsigned i = 0; i < (unsigned)va; ++i)
555 this->shape (i) = va_arg (vl, unsigned);
556 va_end (vl);
557 this->calcsize (); this->calclayout ();
558 this->data.resize (value, this->noel);
559}
560
561// arb. arg.
562template < typename T >
563inline Tensor <T>::Tensor (vararg va, ...)
564 //: CTensor<T>::rank (va.num), CTensor<T>::layout (va.num), CTensor<T>::shape (va.num)
565{
566 this->rank = va;
567 this->layout.resize ((unsigned)va);
568 this->shape.resize ((unsigned)va);
569 va_list vl;
570 va_start (vl, va);
571 for (unsigned i = 0; i < this->rank; ++i)
572 this->shape (i) = va_arg (vl, unsigned);
573 va_end (vl);
574 this->calcsize (); this->calclayout ();
575 this->data.resize (this->noel);
576}
577
578
579template <typename T>
580Tensor<T> Tensor <T>::contract (const unsigned i1, const unsigned i2) const
581{
582 // Calculate shape
583 Index ix (idx_remove2 (this->shape, i1, i2));
584 Tensor < T > t (0, ix);
585
586 BCHK (this->shape (i1) != this->shape (i2), TensErr, Contraction over diff. sized indices, this->shape (i2), t);
587
588 Index bx (0, ix.size());
589 while (bx(0) < ix(0)) {
590 unsigned long l = t.calc_offs (bx);
591 for (unsigned m = 0; m < this->shape (i1); ++m)
592 t.data (l) += (*this) (idx_fill_in2 (bx, i1, m, i2, m));
593 bx.next_idx (ix);
594 }
595 return t;
596}
597
598#if 1
599template <typename T>
600Tensor<T> Tensor<T>::cntrmul (const Tensor<T>& t2, const unsigned i1, const unsigned i2) const
601{
602 BCHK(this->shape (i1) != t2.shape (i2), TensErr, CntrMul: Diff. sizes, t2.shape(i2), 0);
603 Index sh2 (this->shape); sh2.append (t2.shape);
604 Index ix (idx_remove2 (sh2, i1, i2 + this->rank));
605
606 Tensor <T> result (0, ix);
607 Index ixr (0, result.rank);
608
609 while (ixr(0) < ix(0)) {
610 unsigned long i = result.calc_offs (ixr);
611 for (unsigned m = 0; m < this->shape (i1); ++m) {
612 Index ix1 (idx_fill_in1 (ixr.slice(0, this->rank-1), i1, m));
613 Index ix2 (idx_fill_in1 (ixr.slice(this->rank-1, result.rank), i2, m));
614 result.data(i) += (*this) (ix1) * t2 (ix2);
615 }
616 ixr.next_idx (ix);
617 }
618 return result;
619}
620
621#else
622
623template <typename T>
624Tensor<T> Tensor<T>::cntrmul (const Tensor<T>& t2, const unsigned i1, const unsigned i2) const
625{
626 BCHK(this->shape (i1) != t2.shape (i2), TensErr, CrtMul: Diff. sizes, t2.shape(i2), 0);
627 Index ix (this->rank + t2.rank - 2); // rank of result tensor
628 unsigned c = 0; // counter
629 {
630 for (unsigned i = 0; i < this->rank; i++)
631 if (i != i1)
632 ix (c++) = this->shape (i);
633 } // index from 1rst
634 {
635 for (unsigned i = 0; i < t2.rank; i++) i
636 if (i != i2)
637 ix (c++) = t2.shape (i);
638 } // & from 2nd tensor excl. sum. index
639
640 Tensor <T> result (0, ix);
641 Index ixr (result.rank);
642 Index ix1 (this->rank);
643 Index ix2 (t2.rank);
644 for (unsigned long i = 0; i < result.noel; ++i) {
645 ixr = result.calc_indx (i);
646 for (unsigned m = 0; m < this->shape (i1); ++m) {
647 c = 0; // reset counter
648 for (unsigned k = 0; k < this->rank; ++k) {
649 if (k != i1)
650 ix1 (k) = ixr (c++);
651 else
652 ix1 (k) = m;
653 }
654 for (unsigned l = 0; l < t2.rank; ++l) {
655 if (l != i2)
656 ix2 (l) = ixr (c++);
657 else
658 ix2 (l) = m;
659 }
660 result.data(i) += (*this)(ix1) * t2(ix2);
661 }
662 }
663 return result;
664}
665
666#endif
667
668// Same as cntrmul, but friend instead of member
669template <typename T>
670Tensor<T> ctrmul (const Tensor<T>& t1, const Tensor<T>& t2, const unsigned i1, const unsigned i2)
671{
672 BCHK(t1.shape (i1) != t2.shape (i2), TensErr, CtrMul: Diff. sizes, t2.shape(i2), 0);
673 Index sh2 (t1.shape); sh2.append (t2.shape);
674 Index ix (idx_remove2 (sh2, i1, i2 + t1.rank));
675 Tensor < T > result (0, ix);
676
677 Index ixr (0, result.rank);
678 while (ixr(0) < ix(0)) {
679 unsigned long i = result.calc_offs (ixr);
680 for (unsigned m = 0; m < t1.shape (i1); ++m) {
681 result.data(i) += t1 (idx_fill_in1 (ixr.slice(0,t1.rank-1), i1, m))
682 * t2 (idx_fill_in1 (ixr.slice(t1.rank-1,result.rank), i2, m));
683 }
684 ixr.next_idx (ix);
685 }
686 return result;
687}
688
689template <typename T>
690Tensor<T> metrmul (const Tensor<T>& metr, const Tensor<T>& t, const unsigned i1, const unsigned i2)
691{
692 BCHK(metr.shape (i1) != t.shape (i2), TensErr, MetrMul: Diff. sizes, t.shape(i2), 0);
693 BCHK(metr.rank != 2, TensErr, Metric w/ rank != 2 ?, metr.rank, t);
694 BCHKNR(metr.shape(0) != metr.shape(1), TensErr, Non-quadr. metric ?, metr.shape(i1));
695
696 Index ix (t.shape);
697 Tensor < T > result (0, ix);
698
699 unsigned long io = 1 - i1; // other index in metric
700
701 Index ixr (0, result.rank);
702 Index mix (2);
703 while (ixr(0) < ix(0)) {
704 unsigned long i = result.calc_offs (ixr);
705 for (unsigned m = 0; m < metr.shape (i1); ++m) {
706 mix (io) = ixr (i2); mix (i1) = m;
707 result.data (i) += metr (mix) * t (idx_set1 (ixr, i2, m));
708 }
709 ixr.next_idx (ix);
710 }
711 return result;
712}
713
714template <typename T>
716{
717 Index ix (t1.shape); // rank of result tensor
718 ix.append (this->shape);
719 Tensor < T > result (0, ix);
720 Index ixr (0, result.rank);
721 while (ixr(0) < ix(0)) {
722 result (ixr) = (*this) (ixr.slice (0, this->rank))
723 * t1 (ixr.slice (this->rank, result.rank));
724 ixr.next_idx (ix);
725 }
726 return result;
727}
728
729// Same as drctmul, but friend
730template <typename T>
731Tensor<T> dctmul (const Tensor<T> &t0, const Tensor<T> &t1)
732{
733 Index ix (t1.shape); // rank of result tensor
734 ix.append (t0.shape);
735 Tensor < T > result (0, ix);
736 Index ixr (0, result.rank);
737 while (ixr(0) < ix(0)) {
738 result (ixr) = t0 (ixr.slice (0, t0.rank))
739 * t1 (ixr.slice (t0.rank, result.rank));
740 ixr.next_idx (ix);
741 }
742 return result;
743}
744
745template <typename T>
747{
748 BCHK(this->shape!=t.shape, TensErr, Diff Tensor shape in op +=, t.noel, *this);
749 if (this->layout == t.layout)
750 for (unsigned long i = 0; i < this->noel; i++)
751 this->data(i) += t.data(i);
752 else {
753 Index ix (0, this->rank);
754 while (ix(0) < this->shape(0)) {
755 (*this)(ix) += t(ix);
756 ix.next_idx(this->shape);
757 }
758 }
759 return *this;
760}
761
762template <typename T>
764{
765 BCHK(this->shape!=t.shape, TensErr, Diff Tensor shape in op -=, t.noel, *this);
766 if (this->layout == t.layout)
767 for (unsigned long i = 0; i < this->noel; i++)
768 this->data(i) -= t.data(i);
769 else {
770 Index ix (0, this->rank);
771 while (ix(0) < this->shape(0)) {
772 (*this)(ix) -= t(ix);
773 ix.next_idx(this->shape);
774 }
775 }
776 return *this;
777}
778
779template <typename T>
781{
782 Tensor<T> r (this->shape);
783 BCHK(this->shape!=t.shape, TensErr, Diff Tensor shape in op +, t.noel, r);
784 if (this->layout == t.layout)
785 for (unsigned long i = 0; i < this->noel; i++)
786 r.data(i) = this->data(i) + t.data(i);
787 else {
788 Index ix (0, this->rank);
789 while (ix(0) < this->shape(0)) {
790 r(ix) = (*this)(ix) + t(ix);
791 ix.next_idx(this->shape);
792 }
793 }
794 return r;
795}
796
797template <typename T>
799{
800 Tensor<T> r (this->shape);
801 BCHK(this->shape!=t.shape, TensErr, Diff Tensor shape in op -, t.noel, r);
802 if (this->layout == t.layout)
803 for (unsigned long i = 0; i < this->noel; i++)
804 r.data(i) = this->data(i) - t.data(i);
805 else {
806 Index ix (0, this->rank);
807 while (ix(0) < this->shape(0)) {
808 r(ix) = (*this)(ix) - t(ix);
809 ix.next_idx(this->shape);
810 }
811 }
812 return r;
813}
814
815
816template <typename T>
818{
819 Tensor<T> res (this->shape);
820 for (unsigned long i = 0; i < this->noel; ++i)
821 res.data(i) = m * this->data(i);
822 return res;
823}
824
825INST(template <typename T> class Tensor friend Tensor<T> operator * (const T, const Tensor<T> &);)
826template <typename T>
827inline Tensor<T> operator * (const T m, const Tensor<T> &t)
828{ return t.mult (m); }
829
830
832
833#endif /* TBCI_TENSOR_H */
long int Vector< T > & index
Definition LM_fit.h:69
int i
Definition LM_fit.h:71
#define STD__
Definition basics.h:338
#define BCHK(cond, exc, txt, ind, rtval)
Definition basics.h:575
#define MIN_ALIGN2
Definition basics.h:424
#define FRIEND_TBCI2__
Definition basics.h:335
#define NAMESPACE_END
Definition basics.h:323
#define INST(x)
Definition basics.h:238
#define NAMESPACE_TBCI
Definition basics.h:317
#define BCHKNR(cond, exc, txt, ind)
Definition basics.h:586
#define REGISTER
Definition basics.h:108
#define FGD
Definition basics.h:144
#define T
Definition bdmatlib.cc:20
BVector< T > & append(const T &)
performs poorly
Definition bvector.h:412
Note (KG, 981214): We don't handle rank == 0.
Definition tensor.h:52
unsigned rank
Definition tensor.h:56
Vector< T > data
Definition tensor.h:55
unsigned rank_size(void) const
Definition tensor.h:209
CTensor< T > & operator=(const CTensor< T > &ct)
Definition tensor.h:144
tbci_traits< T >::const_refval_type get_lin_idx(const unsigned long i) const
Definition tensor.h:123
unsigned long calcsize(void)
Definition tensor.h:60
bool operator==(const CTensor< T > &ct)
Definition tensor.h:186
const T & getcref(vararg va,...) const
Definition tensor.h:445
T & operator()(const Index &ix)
Definition tensor.h:101
CTensor< T > & resize(const Index &ix)
Definition tensor.h:155
T aligned_value_type TALIGN(MIN_ALIGN2)
Definition tensor.h:82
Index layout
Definition tensor.h:59
CTensor< T > & fill(const T &value)
Definition tensor.h:140
~CTensor()
Definition tensor.h:92
T & get_lin_idx(const unsigned long i)
Definition tensor.h:120
unsigned long lin_size(void) const
Definition tensor.h:205
CTensor< T > & resize(const T &val, const Index &ix)
Definition tensor.h:162
T max(unsigned long &pos) const
Definition tensor.h:177
T min() const
Definition tensor.h:181
T element_type
Definition tensor.h:81
CTensor()
Definition tensor.h:84
unsigned long calc_offs(const Index &ix) const
Definition tensor.h:304
unsigned calclayout()
Definition tensor.h:67
unsigned long noel
Definition tensor.h:57
T max() const
Definition tensor.h:180
T min(unsigned long &pos) const
Definition tensor.h:178
CTensor< T > & transpose(const unsigned i, const unsigned j)
Definition tensor.h:131
Index shape
Definition tensor.h:58
bool operator!=(const CTensor< T > &ct)
Definition tensor.h:201
CTensor< T > & resize(const CTensor< T > &ct)
Definition tensor.h:169
T trace() const
Definition tensor.h:183
Index calc_indx(const unsigned long i) const
Definition tensor.h:334
Index index_size(void) const
Definition tensor.h:207
T value_type
Definition tensor.h:80
unsigned lin_read(vararg va,...)
Definition tensor.h:285
Note that this pragma interface might create problems as the class index is not templated!
Definition index.h:49
Index next_idx(const Index &max)
Definition index.h:86
NumErr()
Definition except.h:65
unsigned long size() const
Definition vector.h:104
TensErr(const char *t, const long i=0)
Definition tensor.h:32
virtual ~TensErr()
Definition tensor.h:36
TensErr()
Definition tensor.h:30
TensErr(const TensErr &te)
Definition tensor.h:34
Tensor class including arithmetics.
Definition tensor.h:467
Tensor< T > & operator-=(const Tensor< T > &)
Definition tensor.h:763
T aligned_value_type TALIGN(MIN_ALIGN2)
Definition tensor.h:476
T value_type
Definition tensor.h:474
Tensor< T > mult(const T) const
Definition tensor.h:817
Tensor(const Index &ix)
Definition tensor.h:480
Tensor< T > cntrmul(const Tensor< T > &, const unsigned, const unsigned) const
Definition tensor.h:600
Tensor< T > operator/(const T m) const
Definition tensor.h:511
Tensor< T > operator-() const
Definition tensor.h:519
T element_type
Definition tensor.h:475
friend Tensor< T > FRIEND_TBCI2__ metrmul FGD(const Tensor< T > &, const Tensor< T > &, const unsigned, const unsigned)
Tensor(const unsigned dim_rank)
Definition tensor.h:479
Tensor< T > contract(const unsigned, const unsigned) const
Definition tensor.h:580
friend Tensor< T > FRIEND_TBCI2__ dctmul FGD(const Tensor< T > &, const Tensor< T > &)
Tensor< T > drctmul(const Tensor< T > &) const
Definition tensor.h:715
friend Tensor< T > FRIEND_TBCI2__ ctrmul FGD(const Tensor< T > &, const Tensor< T > &, const unsigned, const unsigned)
Tensor< T > & operator*=(const T m)
Definition tensor.h:494
Tensor(const T &value, const Index &ix)
Definition tensor.h:481
~Tensor()
Definition tensor.h:485
Tensor(const Tensor< T > &ct)
Definition tensor.h:482
Tensor< T > operator*(const T m) const
Definition tensor.h:499
Tensor< T > operator+(const Tensor< T > &) const
Definition tensor.h:780
Tensor< T > & operator/=(const T m)
Definition tensor.h:495
Tensor()
Definition tensor.h:478
Tensor< T > & operator+=(const Tensor< T > &)
Definition tensor.h:746
TVector< T > slice(unsigned long, unsigned long) const
Definition vector.h:2335
Vector< T > & fill(const T &v)
Definition vector.h:1577
return c
Definition f_matrix.h:760
tm fac
Definition f_matrix.h:1052
TVector< unsigned > idx_fill_in1(const Index &idx, const unsigned where, const unsigned what)
Definition index.h:146
TVector< unsigned > idx_fill_in2(const Index &idx, const unsigned where1, const unsigned what1, const unsigned where2, const unsigned what2)
Definition index.h:168
TVector< unsigned > idx_remove2(const Index &idx, const unsigned which1, const unsigned which2)
Definition index.h:205
TVector< unsigned > idx_set1(const Index &idx, const unsigned which, const unsigned what)
Definition index.h:219
const unsigned TMatrix< T > * res
Tensor< T > dctmul(const Tensor< T > &t0, const Tensor< T > &t1)
Definition tensor.h:731
STD__ istream & operator>>(STD__ istream &is, CTensor< T > &ct)
Definition tensor.h:376
Tensor< T > metrmul(const Tensor< T > &metr, const Tensor< T > &t, const unsigned i1, const unsigned i2)
Definition tensor.h:690
STD__ ostream & operator<<(STD__ ostream &os, const CTensor< T > &ct)
Definition tensor.h:357
Tensor< T > ctrmul(const Tensor< T > &t1, const Tensor< T > &t2, const unsigned i1, const unsigned i2)
Definition tensor.h:670
#define large