QMCPACK
TensorOps.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 //
9 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #ifndef OHMMS_TENSOR_OPERATORS_H
14 #define OHMMS_TENSOR_OPERATORS_H
15 
16 /*** Tenor operators. Generic operators are specialized for 1,2 and 3 D
17  */
18 namespace qmcplusplus
19 {
20 template<class T1, class T2, class OP, unsigned D>
21 struct OTAssign<Tensor<T1, D>, Tensor<T2, D>, OP>
22 {
23  inline static void apply(Tensor<T1, D>& lhs, const Tensor<T2, D>& rhs, OP op)
24  {
25  for (unsigned d = 0; d < D * D; ++d)
26  op(lhs[d], rhs[d]);
27  }
28 };
29 
30 template<class T1, class T2, class OP, unsigned D>
31 struct OTAssign<Tensor<T1, D>, T2, OP>
32 {
33  inline static void apply(Tensor<T1, D>& lhs, T2 rhs, OP op)
34  {
35  for (unsigned d = 0; d < D * D; ++d)
36  op(lhs[d], rhs);
37  }
38 };
39 
40 //////////////////////////////////////////////////////////////////////
41 //
42 // Specializations for Tensors with D=1.
43 //
44 //////////////////////////////////////////////////////////////////////
45 
46 template<class T1, class T2, class OP>
47 struct OTAssign<Tensor<T1, 1>, Tensor<T2, 1>, OP>
48 {
49  inline static void apply(Tensor<T1, 1>& lhs, const Tensor<T2, 1>& rhs, OP op) { op(lhs[0], rhs[0]); }
50 };
51 
52 template<class T1, class T2, class OP>
53 struct OTAssign<Tensor<T1, 1>, T2, OP>
54 {
55  inline static void apply(Tensor<T1, 1>& lhs, T2 rhs, OP op) { op(lhs[0], rhs); }
56 };
57 
58 //////////////////////////////////////////////////////////////////////
59 //
60 // Specializations for Tensors with D=2.
61 //
62 //////////////////////////////////////////////////////////////////////
63 
64 template<class T1, class T2, class OP>
65 struct OTAssign<Tensor<T1, 2>, Tensor<T2, 2>, OP>
66 {
67  inline static void apply(Tensor<T1, 2>& lhs, const Tensor<T2, 2>& rhs, OP op)
68  {
69  op(lhs[0], rhs[0]);
70  op(lhs[1], rhs[1]);
71  op(lhs[2], rhs[2]);
72  op(lhs[3], rhs[3]);
73  }
74 };
75 
76 template<class T1, class T2, class OP>
77 struct OTAssign<Tensor<T1, 2>, T2, OP>
78 {
79  inline static void apply(Tensor<T1, 2>& lhs, T2 rhs, OP op)
80  {
81  op(lhs[0], rhs);
82  op(lhs[1], rhs);
83  op(lhs[2], rhs);
84  op(lhs[3], rhs);
85  }
86 };
87 
88 //////////////////////////////////////////////////////////////////////
89 //
90 // Specializations for Tensors with D=3.
91 //
92 //////////////////////////////////////////////////////////////////////
93 
94 template<class T1, class T2, class OP>
95 struct OTAssign<Tensor<T1, 3>, Tensor<T2, 3>, OP>
96 {
97  inline static void apply(Tensor<T1, 3>& lhs, const Tensor<T2, 3>& rhs, OP op)
98  {
99  op(lhs[0], rhs[0]);
100  op(lhs[1], rhs[1]);
101  op(lhs[2], rhs[2]);
102  op(lhs[3], rhs[3]);
103  op(lhs[4], rhs[4]);
104  op(lhs[5], rhs[5]);
105  op(lhs[6], rhs[6]);
106  op(lhs[7], rhs[7]);
107  op(lhs[8], rhs[8]);
108  }
109 };
110 
111 template<class T1, class T2, class OP>
112 struct OTAssign<Tensor<T1, 3>, T2, OP>
113 {
114  inline static void apply(Tensor<T1, 3>& lhs, T2 rhs, OP op)
115  {
116  op(lhs[0], rhs);
117  op(lhs[1], rhs);
118  op(lhs[2], rhs);
119  op(lhs[3], rhs);
120  op(lhs[4], rhs);
121  op(lhs[5], rhs);
122  op(lhs[6], rhs);
123  op(lhs[7], rhs);
124  op(lhs[8], rhs);
125  }
126 };
127 
128 
129 //////////////////////////////////////////////////////////////////////
130 //
131 // The default definitions for SymTensors of arbitrary size.
132 //
133 //////////////////////////////////////////////////////////////////////
134 
135 template<class T1, class T2, class OP, unsigned D>
136 struct OTAssign<SymTensor<T1, D>, SymTensor<T2, D>, OP>
137 {
138  inline static void apply(SymTensor<T1, D>& lhs, const SymTensor<T2, D>& rhs, OP op)
139  {
140  for (unsigned d = 0; d < D * (D + 1) / 2; ++d)
141  op(lhs[d], rhs[d]);
142  }
143 };
144 
145 template<class T1, class T2, class OP, unsigned D>
146 struct OTAssign<SymTensor<T1, D>, T2, OP>
147 {
148  inline static void apply(SymTensor<T1, D>& lhs, T2 rhs, OP op)
149  {
150  for (unsigned d = 0; d < D * (D + 1) / 2; ++d)
151  op(lhs[d], rhs);
152  }
153 };
154 
155 //////////////////////////////////////////////////////////////////////
156 //
157 // Specializations for SymTensors with D=1.
158 //
159 //////////////////////////////////////////////////////////////////////
160 
161 template<class T1, class T2, class OP>
162 struct OTAssign<SymTensor<T1, 1>, SymTensor<T2, 1>, OP>
163 {
164  inline static void apply(SymTensor<T1, 1>& lhs, const SymTensor<T2, 1>& rhs, OP op) { op(lhs[0], rhs[0]); }
165 };
166 
167 template<class T1, class T2, class OP>
168 struct OTAssign<SymTensor<T1, 1>, T2, OP>
169 {
170  inline static void apply(SymTensor<T1, 1>& lhs, T2 rhs, OP op) { op(lhs[0], rhs); }
171 };
172 
173 //////////////////////////////////////////////////////////////////////
174 //
175 // Specializations for SymTensors with D=2.
176 //
177 //////////////////////////////////////////////////////////////////////
178 
179 template<class T1, class T2, class OP>
180 struct OTAssign<SymTensor<T1, 2>, SymTensor<T2, 2>, OP>
181 {
182  inline static void apply(SymTensor<T1, 2>& lhs, const SymTensor<T2, 2>& rhs, OP op)
183  {
184  op(lhs[0], rhs[0]);
185  op(lhs[1], rhs[1]);
186  op(lhs[2], rhs[2]);
187  }
188 };
189 
190 template<class T1, class T2, class OP>
191 struct OTAssign<SymTensor<T1, 2>, T2, OP>
192 {
193  inline static void apply(SymTensor<T1, 2>& lhs, T2 rhs, OP op)
194  {
195  op(lhs[0], rhs);
196  op(lhs[1], rhs);
197  op(lhs[2], rhs);
198  }
199 };
200 
201 //////////////////////////////////////////////////////////////////////
202 //
203 // Specializations for SymTensors with D=3.
204 //
205 //////////////////////////////////////////////////////////////////////
206 
207 template<class T1, class T2, class OP>
208 struct OTAssign<SymTensor<T1, 3>, SymTensor<T2, 3>, OP>
209 {
210  inline static void apply(SymTensor<T1, 3>& lhs, const SymTensor<T2, 3>& rhs, OP op)
211  {
212  op(lhs[0], rhs[0]);
213  op(lhs[1], rhs[1]);
214  op(lhs[2], rhs[2]);
215  op(lhs[3], rhs[3]);
216  op(lhs[4], rhs[4]);
217  op(lhs[5], rhs[5]);
218  }
219 };
220 
221 template<class T1, class T2, class OP>
222 struct OTAssign<SymTensor<T1, 3>, T2, OP>
223 {
224  inline static void apply(SymTensor<T1, 3>& lhs, T2 rhs, OP op)
225  {
226  op(lhs[0], rhs);
227  op(lhs[1], rhs);
228  op(lhs[2], rhs);
229  op(lhs[3], rhs);
230  op(lhs[4], rhs);
231  op(lhs[5], rhs);
232  }
233 };
234 
235 //////////////////////////////////////////////////////////////////////
236 //
237 // The default definitions for AntiSymTensors of arbitrary size.
238 //
239 //////////////////////////////////////////////////////////////////////
240 
241 template<class T1, class T2, class OP, unsigned D>
242 struct OTAssign<AntiSymTensor<T1, D>, AntiSymTensor<T2, D>, OP>
243 {
244  inline static void apply(AntiSymTensor<T1, D>& lhs, const AntiSymTensor<T2, D>& rhs, OP op)
245  {
246  for (unsigned d = 0; d < D * (D - 1) / 2; ++d)
247  op(lhs[d], rhs[d]);
248  }
249 };
250 
251 template<class T1, class T2, class OP, unsigned D>
252 struct OTAssign<AntiSymTensor<T1, D>, T2, OP>
253 {
254  inline static void apply(AntiSymTensor<T1, D>& lhs, T2 rhs, OP op)
255  {
256  for (unsigned d = 0; d < D * (D - 1) / 2; ++d)
257  op(lhs[d], rhs);
258  }
259 };
260 
261 //////////////////////////////////////////////////////////////////////
262 //
263 // Specializations for AntiSymTensors with D=1.
264 //
265 //////////////////////////////////////////////////////////////////////
266 
267 template<class T1, class T2, class OP>
268 struct OTAssign<AntiSymTensor<T1, 1>, AntiSymTensor<T2, 1>, OP>
269 {
270  inline static void apply(AntiSymTensor<T1, 1>& lhs, const AntiSymTensor<T2, 1>& rhs, OP op) {}
271 };
272 
273 template<class T1, class T2, class OP>
274 struct OTAssign<AntiSymTensor<T1, 1>, T2, OP>
275 {
276  inline static void apply(AntiSymTensor<T1, 1>& lhs, T2 rhs, OP op) {}
277 };
278 
279 //////////////////////////////////////////////////////////////////////
280 //
281 // Specializations for AntiSymTensors with D=2.
282 //
283 //////////////////////////////////////////////////////////////////////
284 
285 template<class T1, class T2, class OP>
286 struct OTAssign<AntiSymTensor<T1, 2>, AntiSymTensor<T2, 2>, OP>
287 {
288  inline static void apply(AntiSymTensor<T1, 2>& lhs, const AntiSymTensor<T2, 2>& rhs, OP op) { op(lhs[0], rhs[0]); }
289 };
290 
291 template<class T1, class T2, class OP>
292 struct OTAssign<AntiSymTensor<T1, 2>, T2, OP>
293 {
294  inline static void apply(AntiSymTensor<T1, 2>& lhs, T2 rhs, OP op) { op(lhs[0], rhs); }
295 };
296 
297 //////////////////////////////////////////////////////////////////////
298 //
299 // Specializations for AntiSymTensors with D=3.
300 //
301 //////////////////////////////////////////////////////////////////////
302 
303 template<class T1, class T2, class OP>
304 struct OTAssign<AntiSymTensor<T1, 3>, AntiSymTensor<T2, 3>, OP>
305 {
306  inline static void apply(AntiSymTensor<T1, 3>& lhs, const AntiSymTensor<T2, 3>& rhs, OP op)
307  {
308  op(lhs[0], rhs[0]);
309  op(lhs[1], rhs[1]);
310  op(lhs[2], rhs[2]);
311  }
312 };
313 
314 template<class T1, class T2, class OP>
315 struct OTAssign<AntiSymTensor<T1, 3>, T2, OP>
316 {
317  inline static void apply(AntiSymTensor<T1, 3>& lhs, T2 rhs, OP op)
318  {
319  op(lhs[0], rhs);
320  op(lhs[1], rhs);
321  op(lhs[2], rhs);
322  }
323 };
324 
325 //////////////////////////////////////////////////////////////////////
326 //
327 // Specializations for Tensors of arbitrary size.
328 //
329 //////////////////////////////////////////////////////////////////////
330 
331 template<class T1, class T2, class OP, unsigned D>
332 struct OTBinary<Tensor<T1, D>, Tensor<T2, D>, OP>
333 {
335  inline static Tensor<Type_t, D> apply(const Tensor<T1, D>& lhs, const Tensor<T2, D>& rhs, OP op)
336  {
337  Tensor<Type_t, D> ret;
338  for (unsigned d = 0; d < D * D; ++d)
339  ret[d] = op(lhs[d], rhs[d]);
340  return ret;
341  }
342 };
343 
344 template<class T1, class T2, class OP, unsigned D>
345 struct OTBinary<Tensor<T1, D>, T2, OP>
346 {
348  inline static Tensor<Type_t, D> apply(const Tensor<T1, D>& lhs, T2 rhs, OP op)
349  {
350  Tensor<Type_t, D> ret;
351  for (unsigned d = 0; d < D * D; ++d)
352  ret[d] = op(lhs[d], rhs);
353  return ret;
354  }
355 };
356 
357 template<class T1, class T2, class OP, unsigned D>
358 struct OTBinary<T1, Tensor<T2, D>, OP>
359 {
361  inline static Tensor<Type_t, D> apply(T1 lhs, const Tensor<T2, D>& rhs, OP op)
362  {
363  Tensor<Type_t, D> ret;
364  for (unsigned d = 0; d < D * D; ++d)
365  ret[d] = op(lhs, rhs[d]);
366  return ret;
367  }
368 };
369 
370 //////////////////////////////////////////////////////////////////////
371 //
372 // Specializations of OTBinary for Tensors with D=1.
373 //
374 //////////////////////////////////////////////////////////////////////
375 
376 template<class T1, class T2, class OP>
377 struct OTBinary<Tensor<T1, 1>, Tensor<T2, 1>, OP>
378 {
380  inline static Tensor<Type_t, 1> apply(const Tensor<T1, 1>& lhs, const Tensor<T2, 1>& rhs, OP op)
381  {
382  return Tensor<Type_t, 1>(op(lhs[0], rhs[0]));
383  }
384 };
385 
386 template<class T1, class T2, class OP>
387 struct OTBinary<Tensor<T1, 1>, T2, OP>
388 {
390  inline static Tensor<Type_t, 1> apply(const Tensor<T1, 1>& lhs, T2 rhs, OP op)
391  {
392  return Tensor<Type_t, 1>(op(lhs[0], rhs));
393  }
394 };
395 
396 template<class T1, class T2, class OP>
397 struct OTBinary<T1, Tensor<T2, 1>, OP>
398 {
400  inline static Tensor<Type_t, 1> apply(T1 lhs, const Tensor<T2, 1>& rhs, OP op)
401  {
402  return Tensor<Type_t, 1>(op(lhs, rhs[0]));
403  }
404 };
405 
406 //////////////////////////////////////////////////////////////////////
407 //
408 // Specializations of OTBinary for Tensors with D=2.
409 //
410 //////////////////////////////////////////////////////////////////////
411 
412 template<class T1, class T2, class OP>
413 struct OTBinary<Tensor<T1, 2>, Tensor<T2, 2>, OP>
414 {
416  inline static Tensor<Type_t, 2> apply(const Tensor<T1, 2>& lhs, const Tensor<T2, 2>& rhs, OP op)
417  {
418  return Tensor<Type_t, 2>(op(lhs[0], rhs[0]), op(lhs[1], rhs[1]), op(lhs[2], rhs[2]), op(lhs[3], rhs[3]));
419  }
420 };
421 
422 template<class T1, class T2, class OP>
423 struct OTBinary<Tensor<T1, 2>, T2, OP>
424 {
426  inline static Tensor<Type_t, 2> apply(const Tensor<T1, 2>& lhs, T2 rhs, OP op)
427  {
428  return Tensor<Type_t, 2>(op(lhs[0], rhs), op(lhs[1], rhs), op(lhs[2], rhs), op(lhs[3], rhs));
429  }
430 };
431 
432 template<class T1, class T2, class OP>
433 struct OTBinary<T1, Tensor<T2, 2>, OP>
434 {
436  inline static Tensor<Type_t, 2> apply(T1 lhs, const Tensor<T2, 2>& rhs, OP op)
437  {
438  return Tensor<Type_t, 2>(op(lhs, rhs[0]), op(lhs, rhs[1]), op(lhs, rhs[2]), op(lhs, rhs[3]));
439  }
440 };
441 
442 //////////////////////////////////////////////////////////////////////
443 //
444 // Specializations of OTBinary for Tensors with D=3.
445 //
446 //////////////////////////////////////////////////////////////////////
447 
448 template<class T1, class T2, class OP>
449 struct OTBinary<Tensor<T1, 3>, Tensor<T2, 3>, OP>
450 {
452  inline static Tensor<Type_t, 3> apply(const Tensor<T1, 3>& lhs, const Tensor<T2, 3>& rhs, OP op)
453  {
454  return Tensor<Type_t, 3>(op(lhs[0], rhs[0]), op(lhs[1], rhs[1]), op(lhs[2], rhs[2]), op(lhs[3], rhs[3]),
455  op(lhs[4], rhs[4]), op(lhs[5], rhs[5]), op(lhs[6], rhs[6]), op(lhs[7], rhs[7]),
456  op(lhs[8], rhs[8]));
457  }
458 };
459 
460 template<class T1, class T2, class OP>
461 struct OTBinary<Tensor<T1, 3>, T2, OP>
462 {
464  inline static Tensor<Type_t, 3> apply(const Tensor<T1, 3>& lhs, T2 rhs, OP op)
465  {
466  return Tensor<Type_t, 3>(op(lhs[0], rhs), op(lhs[1], rhs), op(lhs[2], rhs), op(lhs[3], rhs), op(lhs[4], rhs),
467  op(lhs[5], rhs), op(lhs[6], rhs), op(lhs[7], rhs), op(lhs[8], rhs));
468  }
469 };
470 
471 template<class T1, class T2, class OP>
472 struct OTBinary<T1, Tensor<T2, 3>, OP>
473 {
475  inline static Tensor<Type_t, 3> apply(T1 lhs, const Tensor<T2, 3>& rhs, OP op)
476  {
477  return Tensor<Type_t, 3>(op(lhs, rhs[0]), op(lhs, rhs[1]), op(lhs, rhs[2]), op(lhs, rhs[3]), op(lhs, rhs[4]),
478  op(lhs, rhs[5]), op(lhs, rhs[6]), op(lhs, rhs[7]), op(lhs, rhs[8]));
479  }
480 };
481 
482 //////////////////////////////////////////////////////////////////////
483 //
484 // Specializations for SymTensors of arbitrary size.
485 //
486 //////////////////////////////////////////////////////////////////////
487 
488 template<class T1, class T2, class OP, unsigned D>
489 struct OTBinary<SymTensor<T1, D>, SymTensor<T2, D>, OP>
490 {
492  inline static SymTensor<Type_t, D> apply(const SymTensor<T1, D>& lhs, const SymTensor<T2, D>& rhs, OP op)
493  {
495  for (unsigned d = 0; d < D * (D + 1) / 2; ++d)
496  ret[d] = op(lhs[d], rhs[d]);
497  return ret;
498  }
499 };
500 
501 template<class T1, class T2, class OP, unsigned D>
502 struct OTBinary<SymTensor<T1, D>, T2, OP>
503 {
505  inline static SymTensor<Type_t, D> apply(const SymTensor<T1, D>& lhs, T2 rhs, OP op)
506  {
508  for (unsigned d = 0; d < D * (D + 1) / 2; ++d)
509  ret[d] = op(lhs[d], rhs);
510  return ret;
511  }
512 };
513 
514 template<class T1, class T2, class OP, unsigned D>
515 struct OTBinary<T1, SymTensor<T2, D>, OP>
516 {
518  inline static SymTensor<Type_t, D> apply(T1 lhs, const SymTensor<T2, D>& rhs, OP op)
519  {
521  for (unsigned d = 0; d < D * (D + 1) / 2; ++d)
522  ret[d] = op(lhs, rhs[d]);
523  return ret;
524  }
525 };
526 
527 //////////////////////////////////////////////////////////////////////
528 //
529 // Specializations of OTBinary for SymTensors with D=1.
530 //
531 //////////////////////////////////////////////////////////////////////
532 
533 template<class T1, class T2, class OP>
534 struct OTBinary<SymTensor<T1, 1>, SymTensor<T2, 1>, OP>
535 {
537  inline static SymTensor<Type_t, 1> apply(const SymTensor<T1, 1>& lhs, const SymTensor<T2, 1>& rhs, OP op)
538  {
539  return SymTensor<Type_t, 1>(op(lhs[0], rhs[0]));
540  }
541 };
542 
543 template<class T1, class T2, class OP>
544 struct OTBinary<SymTensor<T1, 1>, T2, OP>
545 {
547  inline static SymTensor<Type_t, 1> apply(const SymTensor<T1, 1>& lhs, T2 rhs, OP op)
548  {
549  return SymTensor<Type_t, 1>(op(lhs[0], rhs));
550  }
551 };
552 
553 template<class T1, class T2, class OP>
554 struct OTBinary<T1, SymTensor<T2, 1>, OP>
555 {
557  inline static SymTensor<Type_t, 1> apply(T1 lhs, const SymTensor<T2, 1>& rhs, OP op)
558  {
559  return SymTensor<Type_t, 1>(op(lhs, rhs[0]));
560  }
561 };
562 
563 //////////////////////////////////////////////////////////////////////
564 //
565 // Specializations of OTBinary for SymTensors with D=2.
566 //
567 //////////////////////////////////////////////////////////////////////
568 
569 template<class T1, class T2, class OP>
570 struct OTBinary<SymTensor<T1, 2>, SymTensor<T2, 2>, OP>
571 {
573  inline static SymTensor<Type_t, 2> apply(const SymTensor<T1, 2>& lhs, const SymTensor<T2, 2>& rhs, OP op)
574  {
575  return SymTensor<Type_t, 2>(op(lhs[0], rhs[0]), op(lhs[1], rhs[1]), op(lhs[2], rhs[2]));
576  }
577 };
578 
579 template<class T1, class T2, class OP>
580 struct OTBinary<SymTensor<T1, 2>, T2, OP>
581 {
583  inline static SymTensor<Type_t, 2> apply(const SymTensor<T1, 2>& lhs, T2 rhs, OP op)
584  {
585  return SymTensor<Type_t, 2>(op(lhs[0], rhs), op(lhs[1], rhs), op(lhs[2], rhs));
586  }
587 };
588 
589 template<class T1, class T2, class OP>
590 struct OTBinary<T1, SymTensor<T2, 2>, OP>
591 {
593  inline static SymTensor<Type_t, 2> apply(T1 lhs, const SymTensor<T2, 2>& rhs, OP op)
594  {
595  return SymTensor<Type_t, 2>(op(lhs, rhs[0]), op(lhs, rhs[1]), op(lhs, rhs[2]));
596  }
597 };
598 
599 //////////////////////////////////////////////////////////////////////
600 //
601 // Specializations of OTBinary for SymTensors with D=3.
602 //
603 //////////////////////////////////////////////////////////////////////
604 
605 template<class T1, class T2, class OP>
606 struct OTBinary<SymTensor<T1, 3>, SymTensor<T2, 3>, OP>
607 {
609  inline static SymTensor<Type_t, 3> apply(const SymTensor<T1, 3>& lhs, const SymTensor<T2, 3>& rhs, OP op)
610  {
611  return SymTensor<Type_t, 3>(op(lhs[0], rhs[0]), op(lhs[1], rhs[1]), op(lhs[2], rhs[2]), op(lhs[3], rhs[3]),
612  op(lhs[4], rhs[4]), op(lhs[5], rhs[5]));
613  }
614 };
615 
616 template<class T1, class T2, class OP>
617 struct OTBinary<SymTensor<T1, 3>, T2, OP>
618 {
620  inline static SymTensor<Type_t, 3> apply(const SymTensor<T1, 3>& lhs, T2 rhs, OP op)
621  {
622  return SymTensor<Type_t, 3>(op(lhs[0], rhs), op(lhs[1], rhs), op(lhs[2], rhs), op(lhs[3], rhs), op(lhs[4], rhs),
623  op(lhs[5], rhs));
624  }
625 };
626 
627 template<class T1, class T2, class OP>
628 struct OTBinary<T1, SymTensor<T2, 3>, OP>
629 {
631  inline static SymTensor<Type_t, 3> apply(T1 lhs, const SymTensor<T2, 3>& rhs, OP op)
632  {
633  return SymTensor<Type_t, 3>(op(lhs, rhs[0]), op(lhs, rhs[1]), op(lhs, rhs[2]), op(lhs, rhs[3]), op(lhs, rhs[4]),
634  op(lhs, rhs[5]));
635  }
636 };
637 
638 //////////////////////////////////////////////////////////////////////
639 //
640 // Specialization for SymTensor OP Tensor of arbitrary size.
641 //
642 //////////////////////////////////////////////////////////////////////
643 
644 template<class T1, class T2, class OP, unsigned D>
645 struct OTBinary<SymTensor<T1, D>, Tensor<T2, D>, OP>
646 {
648  inline static Tensor<Type_t, D> apply(const SymTensor<T1, D>& lhs, const Tensor<T2, D>& rhs, OP op)
649  {
650  Tensor<Type_t, D> ret;
651  for (unsigned i = 0; i < D; i++)
652  for (unsigned j = 0; j < D; j++)
653  ret(i, j) = op(lhs(i, j), rhs(i, j));
654  return ret;
655  }
656 };
657 
658 //////////////////////////////////////////////////////////////////////
659 //
660 // Specialization for Tensor OP SymTensor of arbitrary size.
661 //
662 //////////////////////////////////////////////////////////////////////
663 
664 template<class T1, class T2, class OP, unsigned D>
665 struct OTBinary<Tensor<T1, D>, SymTensor<T2, D>, OP>
666 {
668  inline static Tensor<Type_t, D> apply(const Tensor<T1, D>& lhs, const SymTensor<T2, D>& rhs, OP op)
669  {
670  Tensor<Type_t, D> ret;
671  for (unsigned i = 0; i < D; i++)
672  for (unsigned j = 0; j < D; j++)
673  ret(i, j) = op(lhs(i, j), rhs(i, j));
674  return ret;
675  }
676 };
677 
678 //////////////////////////////////////////////////////////////////////
679 //
680 // Specializations for AntiSymTensors of arbitrary size.
681 //
682 //////////////////////////////////////////////////////////////////////
683 
684 template<class T1, class T2, class OP, unsigned D>
685 struct OTBinary<AntiSymTensor<T1, D>, AntiSymTensor<T2, D>, OP>
686 {
688  inline static AntiSymTensor<Type_t, D> apply(const AntiSymTensor<T1, D>& lhs, const AntiSymTensor<T2, D>& rhs, OP op)
689  {
691  for (unsigned d = 0; d < D * (D - 1) / 2; ++d)
692  ret[d] = op(lhs[d], rhs[d]);
693  return ret;
694  }
695 };
696 
697 template<class T1, class T2, class OP, unsigned D>
698 struct OTBinary<AntiSymTensor<T1, D>, T2, OP>
699 {
701  inline static AntiSymTensor<Type_t, D> apply(const AntiSymTensor<T1, D>& lhs, T2 rhs, OP op)
702  {
704  for (unsigned d = 0; d < D * (D - 1) / 2; ++d)
705  ret[d] = op(lhs[d], rhs);
706  return ret;
707  }
708 };
709 
710 template<class T1, class T2, class OP, unsigned D>
711 struct OTBinary<T1, AntiSymTensor<T2, D>, OP>
712 {
714  inline static AntiSymTensor<Type_t, D> apply(T1 lhs, const AntiSymTensor<T2, D>& rhs, OP op)
715  {
717  for (unsigned d = 0; d < D * (D - 1) / 2; ++d)
718  ret[d] = op(lhs, rhs[d]);
719  return ret;
720  }
721 };
722 
723 //////////////////////////////////////////////////////////////////////
724 //
725 // Specializations of OTBinary for AntiSymTensors with D=1.
726 //
727 //////////////////////////////////////////////////////////////////////
728 
729 template<class T1, class T2, class OP>
730 struct OTBinary<AntiSymTensor<T1, 1>, AntiSymTensor<T2, 1>, OP>
731 {
733  inline static AntiSymTensor<Type_t, 1> apply(const AntiSymTensor<T1, 1>& lhs, const AntiSymTensor<T2, 1>& rhs, OP op)
734  {
736  }
737 };
738 
739 template<class T1, class T2, class OP>
740 struct OTBinary<AntiSymTensor<T1, 1>, T2, OP>
741 {
743  inline static AntiSymTensor<Type_t, 1> apply(const AntiSymTensor<T1, 1>& lhs, T2 rhs, OP op)
744  {
746  }
747 };
748 
749 template<class T1, class T2, class OP>
750 struct OTBinary<T1, AntiSymTensor<T2, 1>, OP>
751 {
753  inline static AntiSymTensor<Type_t, 1> apply(T1 lhs, const AntiSymTensor<T2, 1>& rhs, OP op)
754  {
756  }
757 };
758 
759 //////////////////////////////////////////////////////////////////////
760 //
761 // Specializations of OTBinary for AntiSymTensors with D=2.
762 //
763 //////////////////////////////////////////////////////////////////////
764 
765 template<class T1, class T2, class OP>
766 struct OTBinary<AntiSymTensor<T1, 2>, AntiSymTensor<T2, 2>, OP>
767 {
769  inline static AntiSymTensor<Type_t, 2> apply(const AntiSymTensor<T1, 2>& lhs, const AntiSymTensor<T2, 2>& rhs, OP op)
770  {
771  return AntiSymTensor<Type_t, 2>(op(lhs[0], rhs[0]));
772  }
773 };
774 
775 template<class T1, class T2, class OP>
776 struct OTBinary<AntiSymTensor<T1, 2>, T2, OP>
777 {
779  inline static AntiSymTensor<Type_t, 2> apply(const AntiSymTensor<T1, 2>& lhs, T2 rhs, OP op)
780  {
781  return AntiSymTensor<Type_t, 2>(op(lhs[0], rhs));
782  }
783 };
784 
785 template<class T1, class T2, class OP>
786 struct OTBinary<T1, AntiSymTensor<T2, 2>, OP>
787 {
789  inline static AntiSymTensor<Type_t, 2> apply(T1 lhs, const AntiSymTensor<T2, 2>& rhs, OP op)
790  {
791  return AntiSymTensor<Type_t, 2>(op(lhs, rhs[0]));
792  }
793 };
794 
795 //////////////////////////////////////////////////////////////////////
796 //
797 // Specializations of OTBinary for AntiSymTensors with D=3.
798 //
799 //////////////////////////////////////////////////////////////////////
800 
801 template<class T1, class T2, class OP>
802 struct OTBinary<AntiSymTensor<T1, 3>, AntiSymTensor<T2, 3>, OP>
803 {
805  inline static AntiSymTensor<Type_t, 3> apply(const AntiSymTensor<T1, 3>& lhs, const AntiSymTensor<T2, 3>& rhs, OP op)
806  {
807  return AntiSymTensor<Type_t, 3>(op(lhs[0], rhs[0]), op(lhs[1], rhs[1]), op(lhs[2], rhs[2]));
808  }
809 };
810 
811 template<class T1, class T2, class OP>
812 struct OTBinary<AntiSymTensor<T1, 3>, T2, OP>
813 {
815  inline static AntiSymTensor<Type_t, 3> apply(const AntiSymTensor<T1, 3>& lhs, T2 rhs, OP op)
816  {
817  return AntiSymTensor<Type_t, 3>(op(lhs[0], rhs), op(lhs[1], rhs), op(lhs[2], rhs));
818  }
819 };
820 
821 template<class T1, class T2, class OP>
822 struct OTBinary<T1, AntiSymTensor<T2, 3>, OP>
823 {
825  inline static AntiSymTensor<Type_t, 3> apply(T1 lhs, const AntiSymTensor<T2, 3>& rhs, OP op)
826  {
827  return AntiSymTensor<Type_t, 3>(op(lhs, rhs[0]), op(lhs, rhs[1]), op(lhs, rhs[2]));
828  }
829 };
830 
831 
832 //////////////////////////////////////////////////////
833 //
834 // determinant: generalized
835 //
836 //////////////////////////////////////////////////////
837 template<class T, unsigned D>
838 inline typename Tensor<T, D>::Type_t det(const Tensor<T, D>& a)
839 {
840  // to implement the general case here
841  return 0;
842 }
843 
844 //////////////////////////////////////////////////////
845 // specialized for D=1
846 //////////////////////////////////////////////////////
847 template<class T>
848 inline typename Tensor<T, 1>::Type_t det(const Tensor<T, 1>& a)
849 {
850  return a(0, 0);
851 }
852 
853 //////////////////////////////////////////////////////
854 // specialized for D=2
855 //////////////////////////////////////////////////////
856 template<class T>
857 inline typename Tensor<T, 2>::Type_t det(const Tensor<T, 2>& a)
858 {
859  return a(0, 0) * a(1, 1) - a(0, 1) * a(1, 0);
860 }
861 
862 //////////////////////////////////////////////////////
863 // specialized for D=3
864 //////////////////////////////////////////////////////
865 template<class T>
866 inline typename Tensor<T, 3>::Type_t det(const Tensor<T, 3>& a)
867 {
868  return a(0, 0) * (a(1, 1) * a(2, 2) - a(1, 2) * a(2, 1)) + a(0, 1) * (a(1, 2) * a(2, 0) - a(1, 0) * a(2, 2)) +
869  a(0, 2) * (a(1, 0) * a(2, 1) - a(1, 1) * a(2, 0));
870 }
871 
872 //////////////////////////////////////////////////////
873 //
874 // inverse: generalized
875 // A*B = I, * being the matrix multiplication I(i,j) = sum_k A(i,k)*B(k,j)
876 //
877 //////////////////////////////////////////////////////
878 template<class T, unsigned D>
880 {
881  return Tensor<T, D>();
882 }
883 
884 //////////////////////////////////////////////////////
885 // specialized for D=1
886 //////////////////////////////////////////////////////
887 template<class T>
889 {
890  return Tensor<T, 1>(1.0 / a(0, 0));
891 }
892 
893 //////////////////////////////////////////////////////
894 // specialized for D=2
895 //////////////////////////////////////////////////////
896 template<class T>
898 {
899  T vinv = 1 / det(a);
900  return Tensor<T, 2>(vinv * a(1, 1), -vinv * a(0, 1), -vinv * a(1, 0), vinv * a(0, 0));
901 }
902 
903 //////////////////////////////////////////////////////
904 // specialized for D=3
905 //////////////////////////////////////////////////////
906 template<class T>
908 {
909  T vinv = 1 / det(a);
910  // return Tensor<T,3>(vinv*(a(1,1)*a(2,2)-a(1,2)*a(2,1)),
911  // vinv*(a(1,2)*a(2,0)-a(1,0)*a(2,2)),
912  // vinv*(a(1,0)*a(2,1)-a(1,1)*a(2,0)),
913  // vinv*(a(2,1)*a(0,2)-a(2,2)*a(0,1)),
914  // vinv*(a(2,2)*a(0,0)-a(2,0)*a(0,2)),
915  // vinv*(a(2,0)*a(0,1)-a(2,1)*a(0,0)),
916  // vinv*(a(0,1)*a(1,2)-a(0,2)*a(1,1)),
917  // vinv*(a(0,2)*a(1,0)-a(0,0)*a(1,2)),
918  // vinv*(a(0,0)*a(1,1)-a(0,1)*a(1,0)));
919  return Tensor<T, 3>(vinv * (a(1, 1) * a(2, 2) - a(1, 2) * a(2, 1)), vinv * (a(2, 1) * a(0, 2) - a(2, 2) * a(0, 1)),
920  vinv * (a(0, 1) * a(1, 2) - a(0, 2) * a(1, 1)), vinv * (a(1, 2) * a(2, 0) - a(1, 0) * a(2, 2)),
921  vinv * (a(2, 2) * a(0, 0) - a(2, 0) * a(0, 2)), vinv * (a(0, 2) * a(1, 0) - a(0, 0) * a(1, 2)),
922  vinv * (a(1, 0) * a(2, 1) - a(1, 1) * a(2, 0)), vinv * (a(2, 0) * a(0, 1) - a(2, 1) * a(0, 0)),
923  vinv * (a(0, 0) * a(1, 1) - a(0, 1) * a(1, 0)));
924  // int i,j,i1,i2,j1,j2;
925  // int cyclic[]={1,2,0};
926  // for(i=0;i<3;i++){
927  // i1 = cyclic[i];
928  // i2 = cyclic[i1];
929  // for(j=0;j<3;j++){
930  // j1 = cyclic[j];
931  // j2 = cyclic[j1];
932  // x(i,j) = a(i1,j1)*a(i2,j2) - a(i1,j2)*a(i2,j1);
933  // }
934  // }
935  // typename T_t::Element_t
936  // detinv= 1.0e0/(a(0,0)*x(0,0)+a(1,0)*x(1,0)+a(2,0)*x(2,0));
937  // return detinv*x;
938 }
939 
940 //////////////////////////////////////////////////////////
941 //
942 // cholesky factorization: not general, only 3D supported
943 //
944 //////////////////////////////////////////////////////////
945 
946 //////////////////////////////////////////////////////
947 // specialized for D=3
948 //////////////////////////////////////////////////////
949 template<class T>
951 {
952  Tensor<T, 3> L;
953  T L00Inv;
954  //L = T(0); // already done by default constructor
955  L(0, 0) = sqrt(a(0, 0));
956  L00Inv = 1.0 / L(0, 0);
957  L(1, 0) = a(1, 0) * L00Inv;
958  L(2, 0) = a(2, 0) * L00Inv;
959  L(1, 1) = sqrt(a(1, 1) - L(1, 0) * L(1, 0));
960  L(2, 1) = (a(2, 1) - L(2, 0) * L(1, 0)) / L(1, 1);
961  L(2, 2) = sqrt(a(2, 2) - (L(2, 0) * L(2, 0) + L(2, 1) * L(2, 1)));
962  return L;
963 }
964 
965 //////////////////////////////////////////////////////////////////////
966 //
967 // Specializations for Tensor dot Tensor
968 //
969 //////////////////////////////////////////////////////////////////////
970 
971 template<class T1, class T2, unsigned D>
972 struct OTDot<Tensor<T1, D>, Tensor<T2, D>>
973 {
975  inline static Tensor<Type_t, D> apply(const Tensor<T1, D>& lhs, const Tensor<T2, D>& rhs)
976  {
978  for (unsigned int i = 0; i < D; ++i)
979  for (unsigned int j = 0; j < D; ++j)
980  {
981  Type_t sum = lhs(i, 0) * rhs(0, j);
982  for (unsigned int k = 1; k < D; ++k)
983  sum += lhs(i, k) * rhs(k, j);
984  res(i, j) = sum;
985  }
986  return res;
987  }
988 };
989 
990 template<class T1, class T2>
991 struct OTDot<Tensor<T1, 1>, Tensor<T2, 1>>
992 {
994  inline static Tensor<Type_t, 1> apply(const Tensor<T1, 1>& lhs, const Tensor<T2, 1>& rhs)
995  {
996  return Tensor<Type_t, 1>(lhs[0] * rhs[0]);
997  }
998 };
999 
1000 template<class T1, class T2>
1001 struct OTDot<Tensor<T1, 2>, Tensor<T2, 2>>
1002 {
1004  inline static Tensor<Type_t, 2> apply(const Tensor<T1, 2>& lhs, const Tensor<T2, 2>& rhs)
1005  {
1006  return Tensor<Type_t, 2>(lhs(0, 0) * rhs(0, 0) + lhs(0, 1) * rhs(1, 0),
1007  lhs(0, 0) * rhs(0, 1) + lhs(0, 1) * rhs(1, 1),
1008  lhs(1, 0) * rhs(0, 0) + lhs(1, 1) * rhs(1, 0),
1009  lhs(1, 0) * rhs(0, 1) + lhs(1, 1) * rhs(1, 1));
1010  }
1011 };
1012 
1013 template<class T1, class T2>
1014 struct OTDot<Tensor<T1, 3>, Tensor<T2, 3>>
1015 {
1017  inline static Tensor<Type_t, 3> apply(const Tensor<T1, 3>& lhs, const Tensor<T2, 3>& rhs)
1018  {
1019  return Tensor<Type_t, 3>(lhs(0, 0) * rhs(0, 0) + lhs(0, 1) * rhs(1, 0) + lhs(0, 2) * rhs(2, 0),
1020  lhs(0, 0) * rhs(0, 1) + lhs(0, 1) * rhs(1, 1) + lhs(0, 2) * rhs(2, 1),
1021  lhs(0, 0) * rhs(0, 2) + lhs(0, 1) * rhs(1, 2) + lhs(0, 2) * rhs(2, 2),
1022  lhs(1, 0) * rhs(0, 0) + lhs(1, 1) * rhs(1, 0) + lhs(1, 2) * rhs(2, 0),
1023  lhs(1, 0) * rhs(0, 1) + lhs(1, 1) * rhs(1, 1) + lhs(1, 2) * rhs(2, 1),
1024  lhs(1, 0) * rhs(0, 2) + lhs(1, 1) * rhs(1, 2) + lhs(1, 2) * rhs(2, 2),
1025  lhs(2, 0) * rhs(0, 0) + lhs(2, 1) * rhs(1, 0) + lhs(2, 2) * rhs(2, 0),
1026  lhs(2, 0) * rhs(0, 1) + lhs(2, 1) * rhs(1, 1) + lhs(2, 2) * rhs(2, 1),
1027  lhs(2, 0) * rhs(0, 2) + lhs(2, 1) * rhs(1, 2) + lhs(2, 2) * rhs(2, 2));
1028  }
1029 };
1030 
1031 //////////////////////////////////////////////////////////////////////
1032 //
1033 // Specializations for SymTensor dot SymTensor
1034 //
1035 //////////////////////////////////////////////////////////////////////
1036 
1037 template<class T1, class T2, unsigned D>
1038 struct OTDot<SymTensor<T1, D>, SymTensor<T2, D>>
1039 {
1041  inline static Tensor<Type_t, D> apply(const SymTensor<T1, D>& lhs, const SymTensor<T2, D>& rhs)
1042  {
1044  for (unsigned int i = 0; i < D; ++i)
1045  for (unsigned int j = i; j < D; ++j)
1046  {
1047  Type_t sum = lhs.HL(i, 0) * rhs.HL(j, 0);
1048  int k = 1;
1049  for (; k < i; ++k)
1050  sum += lhs.HL(i, k) * rhs.HL(j, k);
1051  for (; k < j; ++k)
1052  sum += lhs.HL(k, i) * rhs.HL(j, k);
1053  for (; k < D; ++k)
1054  sum += lhs.HL(k, i) * rhs.HL(k, j);
1055  res(i, j) = sum;
1056  }
1057  return res;
1058  }
1059 };
1060 
1061 template<class T1, class T2>
1062 struct OTDot<SymTensor<T1, 1>, SymTensor<T2, 1>>
1063 {
1065  inline static Tensor<Type_t, 1> apply(const SymTensor<T1, 1>& lhs, const SymTensor<T2, 1>& rhs)
1066  {
1067  return Tensor<Type_t, 1>(lhs[0] * rhs[0]);
1068  }
1069 };
1070 
1071 template<class T1, class T2>
1072 struct OTDot<SymTensor<T1, 2>, SymTensor<T2, 2>>
1073 {
1075  inline static Tensor<Type_t, 2> apply(const SymTensor<T1, 2>& lhs, const SymTensor<T2, 2>& rhs)
1076  {
1077  return Tensor<Type_t, 2>(lhs(0, 0) * rhs(0, 0) + lhs(0, 1) * rhs(1, 0),
1078  lhs(0, 0) * rhs(0, 1) + lhs(0, 1) * rhs(1, 1),
1079  lhs(1, 0) * rhs(0, 0) + lhs(1, 1) * rhs(1, 0),
1080  lhs(1, 0) * rhs(0, 1) + lhs(1, 1) * rhs(1, 1));
1081  }
1082 };
1083 
1084 template<class T1, class T2>
1085 struct OTDot<SymTensor<T1, 3>, SymTensor<T2, 3>>
1086 {
1088  inline static Tensor<Type_t, 3> apply(const SymTensor<T1, 3>& lhs, const SymTensor<T2, 3>& rhs)
1089  {
1090  return Tensor<Type_t, 3>(lhs(0, 0) * rhs(0, 0) + lhs(0, 1) * rhs(1, 0) + lhs(0, 2) * rhs(2, 0),
1091  lhs(0, 0) * rhs(0, 1) + lhs(0, 1) * rhs(1, 1) + lhs(0, 2) * rhs(2, 1),
1092  lhs(0, 0) * rhs(0, 2) + lhs(0, 1) * rhs(1, 2) + lhs(0, 2) * rhs(2, 2),
1093  lhs(1, 0) * rhs(0, 0) + lhs(1, 1) * rhs(1, 0) + lhs(1, 2) * rhs(2, 0),
1094  lhs(1, 0) * rhs(0, 1) + lhs(1, 1) * rhs(1, 1) + lhs(1, 2) * rhs(2, 1),
1095  lhs(1, 0) * rhs(0, 2) + lhs(1, 1) * rhs(1, 2) + lhs(1, 2) * rhs(2, 2),
1096  lhs(2, 0) * rhs(0, 0) + lhs(2, 1) * rhs(1, 0) + lhs(2, 2) * rhs(2, 0),
1097  lhs(2, 0) * rhs(0, 1) + lhs(2, 1) * rhs(1, 1) + lhs(2, 2) * rhs(2, 1),
1098  lhs(2, 0) * rhs(0, 2) + lhs(2, 1) * rhs(1, 2) + lhs(2, 2) * rhs(2, 2));
1099  }
1100 };
1101 } // namespace qmcplusplus
1102 
1103 #endif // OHMMS_TENSOR_OPERATORS_H
static AntiSymTensor< Type_t, D > apply(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:688
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:778
static SymTensor< Type_t, 3 > apply(const SymTensor< T1, 3 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:620
static void apply(Tensor< T1, 2 > &lhs, const Tensor< T2, 2 > &rhs, OP op)
Definition: TensorOps.h:67
static void apply(SymTensor< T1, 3 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:224
typename Promote< T1, T2 >::Type_t Type_t
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:592
static void apply(AntiSymTensor< T1, 2 > &lhs, const AntiSymTensor< T2, 2 > &rhs, OP op)
Definition: TensorOps.h:288
static Tensor< Type_t, 3 > apply(T1 lhs, const Tensor< T2, 3 > &rhs, OP op)
Definition: TensorOps.h:475
static void apply(Tensor< T1, 1 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:55
static Tensor< Type_t, D > apply(T1 lhs, const Tensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:361
static void apply(Tensor< T1, D > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:33
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:389
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:360
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
static Tensor< Type_t, 3 > apply(const SymTensor< T1, 3 > &lhs, const SymTensor< T2, 3 > &rhs)
Definition: TensorOps.h:1088
static void apply(AntiSymTensor< T1, 1 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:276
Tensor< T, D >::Type_t det(const Tensor< T, D > &a)
Definition: TensorOps.h:838
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:713
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:752
static Tensor< Type_t, 2 > apply(T1 lhs, const Tensor< T2, 2 > &rhs, OP op)
Definition: TensorOps.h:436
static void apply(Tensor< T1, 3 > &lhs, const Tensor< T2, 3 > &rhs, OP op)
Definition: TensorOps.h:97
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:536
static Tensor< Type_t, D > apply(const Tensor< T1, D > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:348
static Tensor< Type_t, 2 > apply(const Tensor< T1, 2 > &lhs, const Tensor< T2, 2 > &rhs, OP op)
Definition: TensorOps.h:416
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
Definition: TensorOps.h:1064
static void apply(AntiSymTensor< T1, 3 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:317
static SymTensor< Type_t, 2 > apply(const SymTensor< T1, 2 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:583
static SymTensor< Type_t, 1 > apply(const SymTensor< T1, 1 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:547
static AntiSymTensor< Type_t, 3 > apply(const AntiSymTensor< T1, 3 > &lhs, const AntiSymTensor< T2, 3 > &rhs, OP op)
Definition: TensorOps.h:805
static AntiSymTensor< Type_t, 2 > apply(const AntiSymTensor< T1, 2 > &lhs, const AntiSymTensor< T2, 2 > &rhs, OP op)
Definition: TensorOps.h:769
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:788
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:630
Tensor< T, 3 > cholesky(const Tensor< T, 3 > &a)
Definition: TensorOps.h:950
static void apply(SymTensor< T1, 1 > &lhs, const SymTensor< T2, 1 > &rhs, OP op)
Definition: TensorOps.h:164
static AntiSymTensor< Type_t, 3 > apply(T1 lhs, const AntiSymTensor< T2, 3 > &rhs, OP op)
Definition: TensorOps.h:825
static void apply(Tensor< T1, 1 > &lhs, const Tensor< T2, 1 > &rhs, OP op)
Definition: TensorOps.h:49
static Tensor< Type_t, D > apply(const Tensor< T1, D > &lhs, const Tensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:335
static Tensor< Type_t, 3 > apply(const Tensor< T1, 3 > &lhs, const Tensor< T2, 3 > &rhs)
Definition: TensorOps.h:1017
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:700
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:572
static SymTensor< Type_t, 2 > apply(T1 lhs, const SymTensor< T2, 2 > &rhs, OP op)
Definition: TensorOps.h:593
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:608
static void apply(SymTensor< T1, 1 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:170
static AntiSymTensor< Type_t, D > apply(const AntiSymTensor< T1, D > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:701
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
Definition: TensorOps.h:993
static AntiSymTensor< Type_t, 2 > apply(T1 lhs, const AntiSymTensor< T2, 2 > &rhs, OP op)
Definition: TensorOps.h:789
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
Definition: TensorOps.h:1003
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:647
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:619
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:504
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:546
static SymTensor< Type_t, 3 > apply(T1 lhs, const SymTensor< T2, 3 > &rhs, OP op)
Definition: TensorOps.h:631
static Tensor< Type_t, 1 > apply(T1 lhs, const Tensor< T2, 1 > &rhs, OP op)
Definition: TensorOps.h:400
static void apply(SymTensor< T1, D > &lhs, const SymTensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:138
static Tensor< Type_t, D > apply(const SymTensor< T1, D > &lhs, const SymTensor< T2, D > &rhs)
Definition: TensorOps.h:1041
static SymTensor< Type_t, D > apply(T1 lhs, const SymTensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:518
static Tensor< Type_t, 1 > apply(const SymTensor< T1, 1 > &lhs, const SymTensor< T2, 1 > &rhs)
Definition: TensorOps.h:1065
Tensor<T,D> class for D by D tensor.
Definition: OhmmsTinyMeta.h:32
static Tensor< Type_t, 2 > apply(const SymTensor< T1, 2 > &lhs, const SymTensor< T2, 2 > &rhs)
Definition: TensorOps.h:1075
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
Definition: TensorOps.h:1074
static AntiSymTensor< Type_t, D > apply(T1 lhs, const AntiSymTensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:714
static void apply(Tensor< T1, 2 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:79
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:582
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:556
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:474
static AntiSymTensor< Type_t, 1 > apply(const AntiSymTensor< T1, 1 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:743
static Tensor< Type_t, 1 > apply(const Tensor< T1, 1 > &lhs, const Tensor< T2, 1 > &rhs, OP op)
Definition: TensorOps.h:380
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:463
static Tensor< Type_t, D > apply(const Tensor< T1, D > &lhs, const SymTensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:668
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
Definition: TensorOps.h:1016
static SymTensor< Type_t, 2 > apply(const SymTensor< T1, 2 > &lhs, const SymTensor< T2, 2 > &rhs, OP op)
Definition: TensorOps.h:573
static void apply(AntiSymTensor< T1, D > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:254
static void apply(SymTensor< T1, 2 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:193
static SymTensor< Type_t, 1 > apply(T1 lhs, const SymTensor< T2, 1 > &rhs, OP op)
Definition: TensorOps.h:557
static void apply(AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:244
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:517
static void apply(AntiSymTensor< T1, 1 > &lhs, const AntiSymTensor< T2, 1 > &rhs, OP op)
Definition: TensorOps.h:270
static SymTensor< Type_t, D > apply(const SymTensor< T1, D > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:505
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:491
static SymTensor< Type_t, D > apply(const SymTensor< T1, D > &lhs, const SymTensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:492
static AntiSymTensor< Type_t, 3 > apply(const AntiSymTensor< T1, 3 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:815
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:399
static Tensor< Type_t, 3 > apply(const Tensor< T1, 3 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:464
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
Definition: TensorOps.h:974
static Tensor< Type_t, 2 > apply(const Tensor< T1, 2 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:426
static void apply(SymTensor< T1, 3 > &lhs, const SymTensor< T2, 3 > &rhs, OP op)
Definition: TensorOps.h:210
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
static void apply(SymTensor< T1, 2 > &lhs, const SymTensor< T2, 2 > &rhs, OP op)
Definition: TensorOps.h:182
static AntiSymTensor< Type_t, 2 > apply(const AntiSymTensor< T1, 2 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:779
Tensor< T, D > inverse(const Tensor< T, D > &a)
Definition: TensorOps.h:879
static AntiSymTensor< Type_t, 1 > apply(const AntiSymTensor< T1, 1 > &lhs, const AntiSymTensor< T2, 1 > &rhs, OP op)
Definition: TensorOps.h:733
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:334
static void apply(Tensor< T1, D > &lhs, const Tensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:23
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:814
Type_t HL(unsigned int hi, unsigned int lo) const
Definition: SymTensor.h:243
static Tensor< Type_t, D > apply(const Tensor< T1, D > &lhs, const Tensor< T2, D > &rhs)
Definition: TensorOps.h:975
static void apply(AntiSymTensor< T1, 3 > &lhs, const AntiSymTensor< T2, 3 > &rhs, OP op)
Definition: TensorOps.h:306
static Tensor< Type_t, 3 > apply(const Tensor< T1, 3 > &lhs, const Tensor< T2, 3 > &rhs, OP op)
Definition: TensorOps.h:452
static void apply(AntiSymTensor< T1, 2 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:294
static SymTensor< Type_t, 3 > apply(const SymTensor< T1, 3 > &lhs, const SymTensor< T2, 3 > &rhs, OP op)
Definition: TensorOps.h:609
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:435
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:824
static Tensor< Type_t, D > apply(const SymTensor< T1, D > &lhs, const Tensor< T2, D > &rhs, OP op)
Definition: TensorOps.h:648
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:742
static AntiSymTensor< Type_t, 1 > apply(T1 lhs, const AntiSymTensor< T2, 1 > &rhs, OP op)
Definition: TensorOps.h:753
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
Definition: TensorOps.h:1087
static Tensor< Type_t, 1 > apply(const Tensor< T1, 1 > &lhs, const Tensor< T2, 1 > &rhs)
Definition: TensorOps.h:994
static void apply(SymTensor< T1, D > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:148
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:379
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:415
static SymTensor< Type_t, 1 > apply(const SymTensor< T1, 1 > &lhs, const SymTensor< T2, 1 > &rhs, OP op)
Definition: TensorOps.h:537
typename BinaryReturn< T1, T2, OpMultiply >::Type_t Type_t
Definition: TensorOps.h:1040
static Tensor< Type_t, 2 > apply(const Tensor< T1, 2 > &lhs, const Tensor< T2, 2 > &rhs)
Definition: TensorOps.h:1004
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:667
static void apply(Tensor< T1, 3 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:114
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:451
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:425
typename BinaryReturn< T1, T2, OP >::Type_t Type_t
Definition: TensorOps.h:347
static Tensor< Type_t, 1 > apply(const Tensor< T1, 1 > &lhs, T2 rhs, OP op)
Definition: TensorOps.h:390