v0.6.10
Tensor2_value.hpp
Go to the documentation of this file.
1 /* A general version, not for pointers. */
2 
3 template <class T, int Tensor_Dim0, int Tensor_Dim1,
4  Layout layout>
5 class Tensor2
6 {
7  T data[(layout==column_major) ? Tensor_Dim0 : Tensor_Dim1]
8  [(layout==column_major) ? Tensor_Dim1 : Tensor_Dim0];
9 public:
10  /* Initializations for varying numbers of elements, with each one
11  defined for a particular Tensor_Dim. To initialize a different
12  dimension, just add the appropriate constructor and call to
13  the Tensor2_constructor constructor. */
14  Tensor2(T d00, T d01,T d10, T d11)
15  {
17  (data,d00,d01,d10,d11);
18  }
19  Tensor2(T d00, T d01, T d02, T d10, T d11, T d12, T d20, T d21, T d22)
20  {
22  (data,d00,d01,d02,d10,d11,d12,d20,d21,d22);
23  }
24  Tensor2(T d00, T d01, T d10, T d11, T d20, T d21)
25  {
27  (data,d00,d01,d10,d11,d20,d21);
28  }
29  Tensor2(T d00, T d01, T d02, T d03, T d10, T d11, T d12, T d13,
30  T d20, T d21, T d22, T d23, T d30, T d31, T d32, T d33)
31  {
33  (data,d00,d01,d02,d03,d10,d11,d12,d13,d20,d21,d22,d23,d30,d31,d32,d33);
34  }
35  Tensor2() {}
36 
37  /* There are two operator(int,int)'s, one for non-consts that lets you
38  change the value, and one for consts that doesn't. */
39 
40  T & operator()(const int N1, const int N2)
41  {
42 #ifdef FTENSOR_DEBUG
43  if(N1>=Tensor_Dim0 || N1<0 || N2>=Tensor_Dim1 || N2<0)
44  {
45  std::stringstream s;
46  s << "Bad index in Tensor2<T,"
47  << Tensor_Dim0 << "," << Tensor_Dim1
48  << ">.operator(" << N1 << "," << N2 << ")"
49  << std::endl;
50  throw std::runtime_error(s.str());
51  }
52 #endif
53  return ((layout==column_major) ? data[N1][N2] : data[N2][N1]);
54  }
55 
56  T operator()(const int N1, const int N2) const
57  {
58 #ifdef FTENSOR_DEBUG
59  if(N1>=Tensor_Dim0 || N1<0 || N2>=Tensor_Dim1 || N2<0)
60  {
61  std::stringstream s;
62  s << "Bad index in Tensor2<T,"
63  << Tensor_Dim0 << "," << Tensor_Dim1
64  << ">.operator(" << N1 << "," << N2 << ") const"
65  << std::endl;
66  throw std::runtime_error(s.str());
67  }
68 #endif
69  return ((layout==column_major) ? data[N1][N2] : data[N2][N1]);
70  }
71 
72  /* These operator()'s are the first part in constructing template
73  expressions. They can be used to slice off lower dimensional
74  parts. They are not entirely safe, since you can accidently use a
75  higher dimension than what is really allowed (like Dim=5). */
76 
77  template<char i, char j, int Dim0, int Dim1>
80  {
81  return Tensor2_Expr<Tensor2<T,Tensor_Dim0,Tensor_Dim1,layout>,T,Dim0,Dim1,i,j>
82  (*this);
83  }
84 
85  template<char i, char j, int Dim0, int Dim1>
87  operator()(const Index<i,Dim0> , const Index<j,Dim1> ) const
88  {
89  return Tensor2_Expr<const Tensor2<T,Tensor_Dim0,Tensor_Dim1,layout>,
90  T,Dim0,Dim1,i,j>(*this);
91  }
92 
93  /* This is for expressions where a number is used for one slot, and
94  an index for another, yielding a Tensor1_Expr. The non-const
95  versions don't actually create a Tensor2_number_rhs_[01] object.
96  They create a Tensor1_Expr directly, which provides the
97  appropriate indexing operators. The const versions do create a
98  Tensor2_number_[01]. */
99 
100  template<char i, int Dim, int N>
102  T,N>,T,Dim,i>
104  {
106  T,N> TensorExpr;
107  return Tensor1_Expr<TensorExpr,T,Dim,i>(*this);
108  }
109 
110  template<char i, int Dim, int N>
112  T,N>,T,Dim,i>
114  {
116  TensorExpr;
117  return Tensor1_Expr<TensorExpr,T,Dim,i>(*this);
118  }
119 
120  template<char i, int Dim, int N>
122  T,N>,T,Dim,i>
123  operator()(const Index<i,Dim> , const Number<N> ) const
124  {
126  TensorExpr;
127  return Tensor1_Expr<TensorExpr,T,Dim,i>(TensorExpr(*this));
128  }
129 
130  template<char i, int Dim, int N>
132  T,N>,T,Dim,i>
133  operator()(const Number<N> , const Index<i,Dim> ) const
134  {
136  TensorExpr;
137  return Tensor1_Expr<TensorExpr,T,Dim,i>(TensorExpr(*this));
138  }
139 
140  /* This is for expressions where an actual number (not a Number<>)
141  is used for one slot, and an index for another, yielding a
142  Tensor1_Expr. */
143 
144  template<char i, int Dim>
146  <T,Tensor_Dim0,Tensor_Dim1>,T>,T,Dim,i>
147  operator()(const Index<i,Dim>, const int N) const
148  {
150  TensorExpr;
151  return Tensor1_Expr<TensorExpr,T,Dim,i>(TensorExpr(*this,N));
152  }
153 
154  template<char i, int Dim>
156  <T,Tensor_Dim0,Tensor_Dim1>,T>,T,Dim,i>
157  operator()(const int N, const Index<i,Dim> ) const
158  {
160  TensorExpr;
161  return Tensor1_Expr<TensorExpr,T,Dim,i>(TensorExpr(*this,N));
162  }
163 
164  /* These two operator()'s return the Tensor2 with internal
165  contractions, yielding a T. I have to specify one for both
166  const and non-const because otherwise they compiler will use the
167  operator() which gives a Tensor2_Expr<>. */
168 
169  template<char i, int Dim>
171  {
172  return internal_contract(Number<Dim>());
173  }
174 
175  template<char i, int Dim>
176  T operator()(const Index<i,Dim> , const Index<i,Dim> ) const
177  {
178  return internal_contract(Number<Dim>());
179  }
180 private:
181  template<int N>
183  {
184  return data[N-1][N-1] + internal_contract(Number<N-1>());
185  }
186 
188  {
189  return data[0][0];
190  }
191 };
Tensor2(T d00, T d01, T d02, T d03, T d10, T d11, T d12, T d13, T d20, T d21, T d22, T d23, T d30, T d31, T d32, T d33)
Tensor1_Expr< const Tensor2_number_1< const Tensor2< T, Tensor_Dim0, Tensor_Dim1, layout >, T, N >, T, Dim, i > operator()(const Index< i, Dim >, const Number< N >) const
Tensor2(T d00, T d01, T d02, T d10, T d11, T d12, T d20, T d21, T d22)
Layout
Definition: Layout.hpp:6
T data[(layout==column_major) ? Tensor_Dim0 :Tensor_Dim1][(layout==column_major) ? Tensor_Dim1 :Tensor_Dim0]
Tensor1_Expr< Tensor2_number_rhs_1< Tensor2< T, Tensor_Dim0, Tensor_Dim1, layout >, T, N >, T, Dim, i > operator()(const Index< i, Dim >, const Number< N >)
Tensor2(T d00, T d01, T d10, T d11)
Tensor2_Expr< const Tensor2< T, Tensor_Dim0, Tensor_Dim1, layout >, T, Dim0, Dim1, i, j > operator()(const Index< i, Dim0 >, const Index< j, Dim1 >) const
Tensor2_Expr< Tensor2< T, Tensor_Dim0, Tensor_Dim1, layout >, T, Dim0, Dim1, i, j > operator()(const Index< i, Dim0 >, const Index< j, Dim1 >)
Definition: Number.hpp:8
T internal_contract(Number< N >)
Definition: Index.hpp:20
Tensor2(T d00, T d01, T d10, T d11, T d20, T d21)
Tensor1_Expr< Tensor2_number_rhs_0< Tensor2< T, Tensor_Dim0, Tensor_Dim1, layout >, T, N >, T, Dim, i > operator()(const Number< N >, const Index< i, Dim >)
T operator()(const int N1, const int N2) const
T operator()(const Index< i, Dim >, const Index< i, Dim >) const
Tensor1_Expr< const Tensor2_numeral_1< const Tensor2< T, Tensor_Dim0, Tensor_Dim1 >, T >, T, Dim, i > operator()(const Index< i, Dim >, const int N) const
Tensor1_Expr< const Tensor2_numeral_0< const Tensor2< T, Tensor_Dim0, Tensor_Dim1 >, T >, T, Dim, i > operator()(const int N, const Index< i, Dim >) const
const int N
Definition: speed_test.cpp:3
T internal_contract(Number< 1 >)
T operator()(const Index< i, Dim >, const Index< i, Dim >)
T & operator()(const int N1, const int N2)
Tensor1_Expr< const Tensor2_number_0< const Tensor2< T, Tensor_Dim0, Tensor_Dim1, layout >, T, N >, T, Dim, i > operator()(const Number< N >, const Index< i, Dim >) const