v0.5.86
Tensor4_ddg_value.hpp
Go to the documentation of this file.
1 /* A general version, not for pointers. */
2 
3 template <class T, int Tensor_Dim01, int Tensor_Dim23>
5 {
6  T data[(Tensor_Dim01*(Tensor_Dim01+1))/2][(Tensor_Dim23*(Tensor_Dim23+1))/2];
7 public:
8  /* There are two operator(int,int,int,int)'s, one for non-consts
9  that lets you change the value, and one for consts that
10  doesn't. */
11 
12  T & operator()(const int N1, const int N2, const int N3, const int N4)
13  {
14 #ifdef FTENSOR_DEBUG
15  if(N1>=Tensor_Dim01 || N1<0 || N2>=Tensor_Dim01 || N2<0
16  || N3>=Tensor_Dim23 || N3<0 || N4>=Tensor_Dim23 || N4<0)
17  {
18  std::stringstream s;
19  s << "Bad index in Tensor3_dg<T,"
20  << Tensor_Dim01 << "," << Tensor_Dim23
21  << ">.operator("
22  << N1 << "," << N2 << "," << N3 << "," << N4 << ")"
23  << std::endl;
24  throw std::runtime_error(s.str());
25  }
26 #endif
27  return N1>N2 ? (N3>N4 ? data[N1+(N2*(2*Tensor_Dim01-N2-1))/2]
28  [N3+(N4*(2*Tensor_Dim23-N4-1))/2]
29  : data[N1+(N2*(2*Tensor_Dim01-N2-1))/2]
30  [N4+(N3*(2*Tensor_Dim23-N3-1))/2])
31  : (N3>N4 ? data[N2+(N1*(2*Tensor_Dim01-N1-1))/2]
32  [N3+(N4*(2*Tensor_Dim23-N4-1))/2]
33  : data[N2+(N1*(2*Tensor_Dim01-N1-1))/2]
34  [N4+(N3*(2*Tensor_Dim23-N3-1))/2]);
35  }
36 
37  T operator()(const int N1, const int N2, const int N3, const int N4)
38  const
39  {
40 #ifdef FTENSOR_DEBUG
41  if(N1>=Tensor_Dim01 || N1<0 || N2>=Tensor_Dim01 || N2<0
42  || N3>=Tensor_Dim23 || N3<0 || N4>=Tensor_Dim23 || N4<0)
43  {
44  std::stringstream s;
45  s << "Bad index in Tensor3_dg<T,"
46  << Tensor_Dim01 << "," << Tensor_Dim23
47  << ">.operator("
48  << N1 << "," << N2 << "," << N3 << "," << N4
49  << ") const"
50  << std::endl;
51  throw std::runtime_error(s.str());
52  }
53 #endif
54  return N1>N2 ? (N3>N4 ? data[N1+(N2*(2*Tensor_Dim01-N2-1))/2]
55  [N3+(N4*(2*Tensor_Dim23-N4-1))/2]
56  : data[N1+(N2*(2*Tensor_Dim01-N2-1))/2]
57  [N4+(N3*(2*Tensor_Dim23-N3-1))/2])
58  : (N3>N4 ? data[N2+(N1*(2*Tensor_Dim01-N1-1))/2]
59  [N3+(N4*(2*Tensor_Dim23-N4-1))/2]
60  : data[N2+(N1*(2*Tensor_Dim01-N1-1))/2]
61  [N4+(N3*(2*Tensor_Dim23-N3-1))/2]);
62  }
63 
64  /* These operator()'s are the first part in constructing template
65  expressions. They can be used to slice off lower dimensional
66  parts. They are not entirely safe, since you can accidently use a
67  higher dimension than what is really allowed (like Dim=5). */
68 
69  template<char i, char j, char k, char l, int Dim01, int Dim23>
71  T,Dim01,Dim23,i,j,k,l> operator()
72  (const Index<i,Dim01> , const Index<j,Dim01> ,
73  const Index<k,Dim23> , const Index<l,Dim23> )
74  {
76  T,Dim01,Dim23,i,j,k,l> (*this);
77  }
78 
79 
80  template<char i, char j, char k, char l, int Dim01, int Dim23>
82  T,Dim01,Dim23,i,j,k,l> operator()
83  (const Index<i,Dim01> , const Index<j,Dim01> ,
84  const Index<k,Dim23> , const Index<l,Dim23> ) const
85  {
87  T,Dim01,Dim23,i,j,k,l> (*this);
88  }
89 
90  /* This is for expressions where a number is used for two slots, and
91  an index for the other two, yielding a Tensor2_symmetric_Expr. */
92 
93  template<char i, char j, int N0, int N1, int Dim>
95  <const Tensor4_ddg<T,Tensor_Dim01,Tensor_Dim23>,T,N0,N1>,T,Dim,i,j>
97  const Index<i,Dim> , const Index<j,Dim> ) const
98  {
99  typedef const Tensor4_ddg_number_01<const Tensor4_ddg
100  <T,Tensor_Dim01,Tensor_Dim23>,T,N0,N1> TensorExpr;
101  return Tensor2_symmetric_Expr<TensorExpr,T,Dim,i,j>(TensorExpr(*this));
102  }
103 
104  template<char i, char j, int N0, int N1, int Dim>
106  <Tensor4_ddg<T,Tensor_Dim01,Tensor_Dim23>,T,N0,N1>,T,Dim,i,j>
108  const Index<i,Dim> , const Index<j,Dim> )
109  {
111  T,N0,N1> TensorExpr;
113  }
114 
115  /* This is for expressions where a number is used for one slot, and
116  an index for the other three, yielding a Tensor3_dg_Expr. */
117 
118  template<char i, char j, char k, int N0, int Dim1, int Dim23>
120  <const Tensor4_ddg<T,Tensor_Dim01,Tensor_Dim23>,T,N0>,T,Dim23,Dim1,i,j,k>
122  const Index<i,Dim23> , const Index<j,Dim23> ) const
123  {
124  typedef const Tensor4_ddg_number_0<const Tensor4_ddg
125  <T,Tensor_Dim01,Tensor_Dim23>,T,N0> TensorExpr;
126  return Tensor3_dg_Expr<TensorExpr,T,Dim23,Dim1,i,j,k>(TensorExpr(*this));
127  }
128 
129  template<char i, char j, char k, int N0, int Dim1, int Dim23>
131  <Tensor4_ddg<T,Tensor_Dim01,Tensor_Dim23>,T,N0>,T,Dim23,Dim1,i,j,k>
133  const Index<i,Dim23> , const Index<j,Dim23> )
134  {
136  T,N0> TensorExpr;
138  }
139 
140  /* This is for expressions where an int (not a Number) is used for
141  two slots, and an index for the other two, yielding a
142  Tensor2_symmetric_Expr. */
143 
144  template<char i, char j, int Dim>
146  <const Tensor4_ddg<T,Tensor_Dim01,Tensor_Dim23>,T>,T,Dim,i,j>
147  operator()(const int N0, const int N1,
148  const Index<i,Dim> , const Index<j,Dim> ) const
149  {
150  typedef const Tensor4_ddg_numeral_01<const Tensor4_ddg
151  <T,Tensor_Dim01,Tensor_Dim23>,T> TensorExpr;
153  (TensorExpr(*this,N0,N1));
154  }
155 
156  template<char i, char j, int Dim>
158  <const Tensor4_ddg<T,Tensor_Dim01,Tensor_Dim23>,T>,T,Dim,i,j>
160  const int N2, const int N3) const
161  {
162  typedef const Tensor4_ddg_numeral_23<const Tensor4_ddg
163  <T,Tensor_Dim01,Tensor_Dim23>,T> TensorExpr;
165  (TensorExpr(*this,N2,N3));
166  }
167 
168  /* int in two slots but yielding a Tensor2 */
169 
170  template<char i, char j, int Dim1, int Dim3>
172  <const Tensor4_ddg<T,Tensor_Dim01,Tensor_Dim23>,T>,T,Dim1,Dim3,i,j>
173  operator()(const int N0, const Index<i,Dim1> ,
174  const int N2, const Index<j,Dim3> ) const
175  {
176  typedef const Tensor4_ddg_numeral_02<const Tensor4_ddg
177  <T,Tensor_Dim01,Tensor_Dim23>,T> TensorExpr;
179  (TensorExpr(*this,N0,N2));
180  }
181 
182  /* int in three slots, Index in the other yielding a Tensor1_Expr. */
183 
184  template<char i, int Dim>
186  <T,Tensor_Dim01,Tensor_Dim23>,T>,T,Dim,i>
187  operator()(const Index<i,Dim> , const int N1, const int N2,
188  const int N3)
189  {
190  typedef const Tensor4_ddg_numeral_123<const Tensor4_ddg
191  <T,Tensor_Dim01,Tensor_Dim23>,T> TensorExpr;
192  return Tensor1_Expr<TensorExpr,T,Dim,i>(TensorExpr(*this,N1,N2,N3));
193  }
194 
195  template<char i, int Dim>
197  <T,Tensor_Dim01,Tensor_Dim23>,T>,T,Dim,i>
198  operator()(const int N1, const Index<i,Dim> , const int N2,
199  const int N3)
200  {
201  typedef const Tensor4_ddg_numeral_123<const Tensor4_ddg
202  <T,Tensor_Dim01,Tensor_Dim23>,T> TensorExpr;
203  return Tensor1_Expr<TensorExpr,T,Dim,i>(TensorExpr(*this,N1,N2,N3));
204  }
205 
206  /* This is for expressions where an int (not a Number) is used for
207  one slot, and an index for the other three, yielding a
208  Tensor3_dg_Expr. */
209 
210  template<char i, char j, char k, int Dim1, int Dim23>
212  <const Tensor4_ddg<T,Tensor_Dim01,Tensor_Dim23>,T>,T,Dim23,Dim1,i,j,k>
213  operator()(const int N0, const Index<k,Dim1> ,
214  const Index<i,Dim23> , const Index<j,Dim23> ) const
215  {
216  typedef const Tensor4_ddg_numeral_0<const Tensor4_ddg
217  <T,Tensor_Dim01,Tensor_Dim23>,T> TensorExpr;
219  (TensorExpr(*this,N0));
220  }
221 };
T data[(Tensor_Dim01 *(Tensor_Dim01+1))/2][(Tensor_Dim23 *(Tensor_Dim23+1))/2]
const Tensor2_symmetric_Expr< const Tensor4_ddg_numeral_23< const Tensor4_ddg< T, Tensor_Dim01, Tensor_Dim23 >, T >, T, Dim, i, j > operator()(const Index< i, Dim >, const Index< j, Dim >, const int N2, const int N3) const
const Tensor3_dg_Expr< const Tensor4_ddg_number_0< const Tensor4_ddg< T, Tensor_Dim01, Tensor_Dim23 >, T, N0 >, T, Dim23, Dim1, i, j, k > operator()(const Number< N0 >, const Index< k, Dim1 >, const Index< i, Dim23 >, const Index< j, Dim23 >) const
const Tensor2_symmetric_Expr< const Tensor4_ddg_numeral_01< const Tensor4_ddg< T, Tensor_Dim01, Tensor_Dim23 >, T >, T, Dim, i, j > operator()(const int N0, const int N1, const Index< i, Dim >, const Index< j, Dim >) const
Tensor3_dg_Expr< Tensor4_ddg_number_rhs_0< Tensor4_ddg< T, Tensor_Dim01, Tensor_Dim23 >, T, N0 >, T, Dim23, Dim1, i, j, k > operator()(const Number< N0 >, const Index< k, Dim1 >, const Index< i, Dim23 >, const Index< j, Dim23 >)
Definition: Number.hpp:8
T & operator()(const int N1, const int N2, const int N3, const int N4)
Tensor2_symmetric_Expr< Tensor4_ddg_number_rhs_01< Tensor4_ddg< T, Tensor_Dim01, Tensor_Dim23 >, T, N0, N1 >, T, Dim, i, j > operator()(const Number< N0 >, const Number< N1 >, const Index< i, Dim >, const Index< j, Dim >)
Definition: Index.hpp:20
const Tensor2_Expr< const Tensor4_ddg_numeral_02< const Tensor4_ddg< T, Tensor_Dim01, Tensor_Dim23 >, T >, T, Dim1, Dim3, i, j > operator()(const int N0, const Index< i, Dim1 >, const int N2, const Index< j, Dim3 >) const
const Tensor2_symmetric_Expr< const Tensor4_ddg_number_01< const Tensor4_ddg< T, Tensor_Dim01, Tensor_Dim23 >, T, N0, N1 >, T, Dim, i, j > operator()(const Number< N0 >, const Number< N1 >, const Index< i, Dim >, const Index< j, Dim >) const
T operator()(const int N1, const int N2, const int N3, const int N4) const
const Tensor1_Expr< const Tensor4_ddg_numeral_123< const Tensor4_ddg< T, Tensor_Dim01, Tensor_Dim23 >, T >, T, Dim, i > operator()(const int N1, const Index< i, Dim >, const int N2, const int N3)
const Tensor3_dg_Expr< const Tensor4_ddg_numeral_0< const Tensor4_ddg< T, Tensor_Dim01, Tensor_Dim23 >, T >, T, Dim23, Dim1, i, j, k > operator()(const int N0, const Index< k, Dim1 >, const Index< i, Dim23 >, const Index< j, Dim23 >) const
const Tensor1_Expr< const Tensor4_ddg_numeral_123< const Tensor4_ddg< T, Tensor_Dim01, Tensor_Dim23 >, T >, T, Dim, i > operator()(const Index< i, Dim >, const int N1, const int N2, const int N3)