v0.14.0
Loading...
Searching...
No Matches
Tensor4_times_Tensor2.hpp
Go to the documentation of this file.
1/* This file has all of the declarations for expressions like
2 Tensor4*Tensor2 and Tensor2*Tensor4, yielding a
3 Tensor2. */
4
5#pragma once
6
7namespace FTensor
8{
9 /* A(i,j,k,l)*B(k,l) */
10
11 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
12 int Dim3, char i, char j, char k, char l>
14 {
17
18 template <int Current_Dim0, int Current_Dim1>
19 typename promote<T, U>::V
20 eval(const int N1, const int N2, const Number<Current_Dim0> &,
21 const Number<Current_Dim1> &) const
22 {
23 return iterA(N1, N2, Current_Dim0 - 1, Current_Dim1 - 1)
24 * iterB(Current_Dim0 - 1, Current_Dim1 - 1)
27 }
28 template <int Current_Dim1>
29 typename promote<T, U>::V
30 eval(const int N1, const int N2, const Number<1> &,
31 const Number<Current_Dim1> &) const
32 {
33 return iterA(N1, N2, 0, Current_Dim1 - 1) * iterB(0, Current_Dim1 - 1)
35 }
36 typename promote<T, U>::V eval(const int N1, const int N2,
37 const Number<1> &, const Number<1> &) const
38 {
39 return iterA(N1, N2, 0, 0) * iterB(0, 0);
40 }
41
42 public:
43 typename promote<T, U>::V operator()(const int N1, const int N2) const
44 {
45 return eval(N1, N2, Number<Dim2>(), Number<Dim3>());
46 }
47
51 : iterA(a), iterB(b)
52 {}
53 };
54
55 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
56 int Dim3, char i, char j, char k, char l>
57 inline Tensor2_Expr<const Tensor4_times_Tensor2_23<A, B, T, U, Dim0, Dim1,
58 Dim2, Dim3, i, j, k, l>,
59 typename promote<T, U>::V, Dim0, Dim1, i, j>
62 {
63 typedef const Tensor4_times_Tensor2_23<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
64 i, j, k, l>
65 TensorExpr;
67 j>(TensorExpr(a, b));
68 }
69
70 /* B(k,l)*A(i,j,k,l) */
71
72 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
73 int Dim3, char i, char j, char k, char l>
74 inline Tensor2_Expr<const Tensor4_times_Tensor2_23<A, B, T, U, Dim0, Dim1,
75 Dim2, Dim3, i, j, k, l>,
76 typename promote<T, U>::V, Dim0, Dim1, i, j>
79 {
80 typedef const Tensor4_times_Tensor2_23<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
81 i, j, k, l>
82 TensorExpr;
84 j>(TensorExpr(a, b));
85 }
86
87 /* A(i,j,k,l)*B(l,k) */
88
89 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
90 int Dim3, char i, char j, char k, char l>
92 {
95
96 template <int Current_Dim0, int Current_Dim1>
97 typename promote<T, U>::V
98 eval(const int N1, const int N2, const Number<Current_Dim0> &,
99 const Number<Current_Dim1> &) const
100 {
101 return iterA(N1, N2, Current_Dim0 - 1, Current_Dim1 - 1)
102 * iterB(Current_Dim1 - 1, Current_Dim0 - 1)
105 }
106 template <int Current_Dim1>
107 typename promote<T, U>::V
108 eval(const int N1, const int N2, const Number<1> &,
109 const Number<Current_Dim1> &) const
110 {
111 return iterA(N1, N2, 0, Current_Dim1 - 1) * iterB(Current_Dim1 - 1, 0)
113 }
114 typename promote<T, U>::V eval(const int N1, const int N2,
115 const Number<1> &, const Number<1> &) const
116 {
117 return iterA(N1, N2, 0, 0) * iterB(0, 0);
118 }
119
120 public:
121 typename promote<T, U>::V operator()(const int N1, const int N2) const
122 {
123 return eval(N1, N2, Number<Dim2>(), Number<Dim3>());
124 }
125
129 : iterA(a), iterB(b)
130 {}
131 };
132
133 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
134 int Dim3, char i, char j, char k, char l>
135 inline Tensor2_Expr<const Tensor4_times_Tensor2_32<A, B, T, U, Dim0, Dim1,
136 Dim2, Dim3, i, j, k, l>,
137 typename promote<T, U>::V, Dim0, Dim1, i, j>
140 {
141 typedef const Tensor4_times_Tensor2_32<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
142 i, j, k, l>
143 TensorExpr;
145 j>(TensorExpr(a, b));
146 }
147
148 /* B(l,k)*A(i,j,k,l) */
149
150 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
151 int Dim3, char i, char j, char k, char l>
152 inline Tensor2_Expr<const Tensor4_times_Tensor2_32<A, B, T, U, Dim0, Dim1,
153 Dim2, Dim3, i, j, k, l>,
154 typename promote<T, U>::V, Dim0, Dim1, i, j>
157 {
158 typedef const Tensor4_times_Tensor2_32<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
159 i, j, k, l>
160 TensorExpr;
162 j>(TensorExpr(a, b));
163 }
164
165 /* A(i,j,k,l)*B(i,l) */
166
167 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
168 int Dim3, char i, char j, char k, char l>
170 {
173
174 template <int Current_Dim0, int Current_Dim1>
175 typename promote<T, U>::V
176 eval(const int N1, const int N2, const Number<Current_Dim0> &,
177 const Number<Current_Dim1> &) const
178 {
179 return iterA(Current_Dim0 - 1, N1, N2, Current_Dim1 - 1)
180 * iterB(Current_Dim0 - 1, Current_Dim1 - 1)
183 }
184 template <int Current_Dim1>
185 typename promote<T, U>::V
186 eval(const int N1, const int N2, const Number<1> &,
187 const Number<Current_Dim1> &) const
188 {
189 return iterA(0, N1, N2, Current_Dim1 - 1) * iterB(0, Current_Dim1 - 1)
191 }
192 typename promote<T, U>::V eval(const int N1, const int N2,
193 const Number<1> &, const Number<1> &) const
194 {
195 return iterA(0, N1, N2, 0) * iterB(0, 0);
196 }
197
198 public:
199 typename promote<T, U>::V operator()(const int N1, const int N2) const
200 {
201 return eval(N1, N2, Number<Dim0>(), Number<Dim3>());
202 }
203
207 : iterA(a), iterB(b)
208 {}
209 };
210
211 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
212 int Dim3, char i, char j, char k, char l>
213 inline Tensor2_Expr<const Tensor4_times_Tensor2_03<A, B, T, U, Dim0, Dim1,
214 Dim2, Dim3, i, j, k, l>,
215 typename promote<T, U>::V, Dim1, Dim2, j, k>
218 {
219 typedef const Tensor4_times_Tensor2_03<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
220 i, j, k, l>
221 TensorExpr;
223 k>(TensorExpr(a, b));
224 }
225
226 /* B(i,l)*A(i,j,k,l) */
227
228 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
229 int Dim3, char i, char j, char k, char l>
230 inline Tensor2_Expr<const Tensor4_times_Tensor2_03<A, B, T, U, Dim0, Dim1,
231 Dim2, Dim3, i, j, k, l>,
232 typename promote<T, U>::V, Dim1, Dim2, j, k>
235 {
236 typedef const Tensor4_times_Tensor2_03<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
237 i, j, k, l>
238 TensorExpr;
240 k>(TensorExpr(a, b));
241 }
242
243 /* A(i,j,k,l)*B(l,i) */
244
245 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
246 int Dim3, char i, char j, char k, char l>
248 {
251
252 template <int Current_Dim0, int Current_Dim1>
253 typename promote<T, U>::V
254 eval(const int N1, const int N2, const Number<Current_Dim0> &,
255 const Number<Current_Dim1> &) const
256 {
257 return iterA(Current_Dim0 - 1, N1, N2, Current_Dim1 - 1)
258 * iterB(Current_Dim1 - 1, Current_Dim0 - 1)
261 }
262 template <int Current_Dim1>
263 typename promote<T, U>::V
264 eval(const int N1, const int N2, const Number<1> &,
265 const Number<Current_Dim1> &) const
266 {
267 return iterA(0, N1, N2, Current_Dim1 - 1) * iterB(Current_Dim1 - 1, 0)
269 }
270 typename promote<T, U>::V eval(const int N1, const int N2,
271 const Number<1> &, const Number<1> &) const
272 {
273 return iterA(0, N1, N2, 0) * iterB(0, 0);
274 }
275
276 public:
277 typename promote<T, U>::V operator()(const int N1, const int N2) const
278 {
279 return eval(N1, N2, Number<Dim0>(), Number<Dim3>());
280 }
281
285 : iterA(a), iterB(b)
286 {}
287 };
288
289 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
290 int Dim3, char i, char j, char k, char l>
291 inline Tensor2_Expr<const Tensor4_times_Tensor2_30<A, B, T, U, Dim0, Dim1,
292 Dim2, Dim3, i, j, k, l>,
293 typename promote<T, U>::V, Dim1, Dim2, j, k>
296 {
297 typedef const Tensor4_times_Tensor2_30<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
298 i, j, k, l>
299 TensorExpr;
301 k>(TensorExpr(a, b));
302 }
303
304 /* B(l,i)*A(i,j,k,l) */
305
306 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
307 int Dim3, char i, char j, char k, char l>
308 inline Tensor2_Expr<const Tensor4_times_Tensor2_30<A, B, T, U, Dim0, Dim1,
309 Dim2, Dim3, i, j, k, l>,
310 typename promote<T, U>::V, Dim1, Dim2, j, k>
313 {
314 typedef const Tensor4_times_Tensor2_30<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
315 i, j, k, l>
316 TensorExpr;
318 k>(TensorExpr(a, b));
319 }
320
321 /* A(i,j,k,l)*B(j,l) */
322
323 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
324 int Dim3, char i, char j, char k, char l>
326 {
329
330 template <int Current_Dim0, int Current_Dim1>
331 typename promote<T, U>::V
332 eval(const int N1, const int N2, const Number<Current_Dim0> &,
333 const Number<Current_Dim1> &) const
334 {
335 return iterA(N1, Current_Dim0 - 1, N2, Current_Dim1 - 1)
336 * iterB(Current_Dim0 - 1, Current_Dim1 - 1)
339 }
340 template <int Current_Dim1>
341 typename promote<T, U>::V
342 eval(const int N1, const int N2, const Number<1> &,
343 const Number<Current_Dim1> &) const
344 {
345 return iterA(N1, 0, N2, Current_Dim1 - 1) * iterB(0, Current_Dim1 - 1)
347 }
348 typename promote<T, U>::V eval(const int N1, const int N2,
349 const Number<1> &, const Number<1> &) const
350 {
351 return iterA(N1, 0, N2, 0) * iterB(0, 0);
352 }
353
354 public:
355 typename promote<T, U>::V operator()(const int N1, const int N2) const
356 {
357 return eval(N1, N2, Number<Dim0>(), Number<Dim3>());
358 }
359
363 : iterA(a), iterB(b)
364 {}
365 };
366
367 /* B(j,l)*A(i,j,k,l) */
368
369 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
370 int Dim3, char i, char j, char k, char l>
371 inline Tensor2_Expr<const Tensor4_times_Tensor2_13<A, B, T, U, Dim0, Dim1,
372 Dim2, Dim3, i, j, k, l>,
373 typename promote<T, U>::V, Dim0, Dim2, i, k>
376 {
377 typedef const Tensor4_times_Tensor2_13<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
378 i, j, k, l>
379 TensorExpr;
381 k>(TensorExpr(a, b));
382 }
383
384 /* This file has all of the declarations for expressions like
385 Tensor4*Tensor2 and Tensor2*Tensor4, yielding a
386 Tensor4. */
387
388 // TODO: Check dimensions could be errors
389
390 /* A(i,j,k,l)*B(l,m) */
391
392 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
393 int Dim3, int Dim4, char i, char j, char k, char l, char m>
395 {
398
399 template <int Current_Dim0>
400 typename promote<T, U>::V
401 eval(const int N1, const int N2, const int N3, const int N4,
402 const Number<Current_Dim0> &) const
403 {
404 return iterA(N1, N2, N3, Current_Dim0 - 1) * iterB(Current_Dim0 - 1, N4)
405 + eval(N1, N2, N3, N4, Number<Current_Dim0 - 1>());
406 }
407 typename promote<T, U>::V eval(const int N1, const int N2, const int N3,
408 const int N4, const Number<1> &) const
409 {
410 return iterA(N1, N2, N3, 0) * iterB(0, N4);
411 }
412
413 public:
417 : iterA(a), iterB(b)
418 {}
419 typename promote<T, U>::V
420 operator()(const int N1, const int N2, const int N3, const int N4) const
421 {
422 return eval(N1, N2, N3, N4, Number<Dim3>());
423 }
424 };
425
426 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
427 int Dim3, int Dim4, char i, char j, char k, char l, char m>
428 inline const Tensor4_Expr<
429 const Tensor4_times_Tensor2_3_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
430 i, j, k, l, m>,
431 typename promote<T, U>::V, Dim0, Dim1, Dim2, Dim4, i, j, k, m>
434 {
435 typedef const Tensor4_times_Tensor2_3_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
436 Dim4, i, j, k, l, m>
437 TensorExpr;
439 Dim2, Dim4, i, j, k, m>(TensorExpr(a, b));
440 }
441
442 /* B(l,m)*A(i,j,k,l) */
443
444 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
445 int Dim3, int Dim4, char i, char j, char k, char l, char m>
446 inline const Tensor4_Expr<
447 const Tensor4_times_Tensor2_3_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
448 i, j, k, l, m>,
449 typename promote<T, U>::V, Dim0, Dim1, Dim2, Dim4, i, j, k, m>
452 {
453 typedef const Tensor4_times_Tensor2_3_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
454 Dim4, i, j, k, l, m>
455 TensorExpr;
457 Dim2, Dim4, i, j, k, m>(TensorExpr(a, b));
458 }
459
460 /* A(i,j,k,l)*B(m,l) */
461
462 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
463 int Dim3, int Dim4, char i, char j, char k, char l, char m>
465 {
468
469 template <int Current_Dim0>
470 typename promote<T, U>::V
471 eval(const int N1, const int N2, const int N3, const int N4,
472 const Number<Current_Dim0> &) const
473 {
474 return iterA(N1, N2, N3, Current_Dim0 - 1) * iterB(N4, Current_Dim0 - 1)
475 + eval(N1, N2, N3, N4, Number<Current_Dim0 - 1>());
476 }
477 typename promote<T, U>::V eval(const int N1, const int N2, const int N3,
478 const int N4, const Number<1> &) const
479 {
480 return iterA(N1, N2, N3, 0) * iterB(N4, 0);
481 }
482
483 public:
487 : iterA(a), iterB(b)
488 {}
489 typename promote<T, U>::V
490 operator()(const int N1, const int N2, const int N3, const int N4) const
491 {
492 return eval(N1, N2, N3, N4, Number<Dim3>());
493 }
494 };
495
496 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
497 int Dim3, int Dim4, char i, char j, char k, char l, char m>
498 inline const Tensor4_Expr<
499 const Tensor4_times_Tensor2_3_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
500 i, j, k, l, m>,
501 typename promote<T, U>::V, Dim0, Dim1, Dim2, Dim4, i, j, k, m>
504 {
505 typedef const Tensor4_times_Tensor2_3_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
506 Dim4, i, j, k, l, m>
507 TensorExpr;
509 Dim2, Dim4, i, j, k, m>(TensorExpr(a, b));
510 }
511
512 /* B(m,l)*A(i,j,k,l) */
513
514 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
515 int Dim3, int Dim4, char i, char j, char k, char l, char m>
516 inline const Tensor4_Expr<
517 const Tensor4_times_Tensor2_3_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
518 i, j, k, l, m>,
519 typename promote<T, U>::V, Dim0, Dim1, Dim2, Dim4, i, j, k, m>
522 {
523 typedef const Tensor4_times_Tensor2_3_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
524 Dim4, i, j, k, l, m>
525 TensorExpr;
527 Dim2, Dim4, i, j, k, m>(TensorExpr(a, b));
528 }
529
530 /* A(i,j,k,l)*B(j,m) */
531
532 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
533 int Dim3, int Dim4, char i, char j, char k, char l, char m>
535 {
538
539 template <int Current_Dim0>
540 typename promote<T, U>::V
541 eval(const int N1, const int N2, const int N3, const int N4,
542 const Number<Current_Dim0> &) const
543 {
544 return iterA(N1, Current_Dim0 - 1, N3, N4) * iterB(Current_Dim0 - 1, N2)
545 + eval(N1, N2, N3, N4, Number<Current_Dim0 - 1>());
546 }
547 typename promote<T, U>::V eval(const int N1, const int N2, const int N3,
548 const int N4, const Number<1> &) const
549 {
550 return iterA(N1, 0, N3, N4) * iterB(0, N2);
551 }
552
553 public:
557 : iterA(a), iterB(b)
558 {}
559 typename promote<T, U>::V
560 operator()(const int N1, const int N2, const int N3, const int N4) const
561 {
562 return eval(N1, N2, N3, N4, Number<Dim1>());
563 }
564 };
565
566 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
567 int Dim3, int Dim4, char i, char j, char k, char l, char m>
568 inline const Tensor4_Expr<
569 const Tensor4_times_Tensor2_1_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
570 i, j, k, l, m>,
571 typename promote<T, U>::V, Dim0, Dim4, Dim2, Dim3, i, m, k, l>
574 {
575 typedef const Tensor4_times_Tensor2_1_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
576 Dim4, i, j, k, l, m>
577 TensorExpr;
579 Dim4, Dim3, i, m, k, l>(TensorExpr(a, b));
580 }
581
582 /* B(j,m)*A(i,j,k,l) */
583
584 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
585 int Dim3, int Dim4, char i, char j, char k, char l, char m>
586 inline const Tensor4_Expr<
587 const Tensor4_times_Tensor2_1_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
588 i, j, k, l, m>,
589 typename promote<T, U>::V, Dim0, Dim4, Dim2, Dim3, i, m, k, l>
592 {
593 typedef const Tensor4_times_Tensor2_1_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
594 Dim4, i, j, k, l, m>
595 TensorExpr;
597 Dim4, Dim3, i, m, k, l>(TensorExpr(a, b));
598 }
599
600 /* A(i,j,k,l)*B(m,j) */
601
602 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
603 int Dim3, int Dim4, char i, char j, char k, char l, char m>
605 {
608
609 template <int Current_Dim0>
610 typename promote<T, U>::V
611 eval(const int N1, const int N2, const int N3, const int N4,
612 const Number<Current_Dim0> &) const
613 {
614 return iterA(N1, Current_Dim0 - 1, N3, N4) * iterB(N2, Current_Dim0 - 1)
615 + eval(N1, N2, N3, N4, Number<Current_Dim0 - 1>());
616 }
617 typename promote<T, U>::V eval(const int N1, const int N2, const int N3,
618 const int N4, const Number<1> &) const
619 {
620 return iterA(N1, 0, N3, N4) * iterB(N2, 0);
621 }
622
623 public:
627 : iterA(a), iterB(b)
628 {}
629 typename promote<T, U>::V
630 operator()(const int N1, const int N2, const int N3, const int N4) const
631 {
632 return eval(N1, N2, N3, N4, Number<Dim1>());
633 }
634 };
635
636 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
637 int Dim3, int Dim4, char i, char j, char k, char l, char m>
638 inline const Tensor4_Expr<
639 const Tensor4_times_Tensor2_1_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
640 i, j, k, l, m>,
641 typename promote<T, U>::V, Dim0, Dim4, Dim2, Dim3, i, m, k, l>
644 {
645 typedef const Tensor4_times_Tensor2_1_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
646 Dim4, i, j, k, l, m>
647 TensorExpr;
649 Dim2, Dim3, i, m, k, l>(TensorExpr(a, b));
650 }
651
652 /* B(m,j)*A(i,j,k,l) */
653
654 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
655 int Dim3, int Dim4, char i, char j, char k, char l, char m>
656 inline const Tensor4_Expr<
657 const Tensor4_times_Tensor2_1_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
658 i, j, k, l, m>,
659 typename promote<T, U>::V, Dim0, Dim4, Dim2, Dim3, i, m, k, l>
662 {
663 typedef const Tensor4_times_Tensor2_1_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
664 Dim4, i, j, k, l, m>
665 TensorExpr;
667 Dim2, Dim3, i, m, k, l>(TensorExpr(a, b));
668 }
669
670 /* A(i,j,k,l)*B(i,m) */
671
672 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
673 int Dim3, int Dim4, char i, char j, char k, char l, char m>
675 {
678
679 template <int Current_Dim0>
680 typename promote<T, U>::V
681 eval(const int N1, const int N2, const int N3, const int N4,
682 const Number<Current_Dim0> &) const
683 {
684 return iterA(Current_Dim0 - 1, N2, N3, N4) * iterB(Current_Dim0 - 1, N1)
685 + eval(N1, N2, N3, N4, Number<Current_Dim0 - 1>());
686 }
687 typename promote<T, U>::V eval(const int N1, const int N2, const int N3,
688 const int N4, const Number<1> &) const
689 {
690 return iterA(0, N2, N3, N4) * iterB(0, N1);
691 }
692
693 public:
697 : iterA(a), iterB(b)
698 {}
699 typename promote<T, U>::V
700 operator()(const int N1, const int N2, const int N3, const int N4) const
701 {
702 return eval(N1, N2, N3, N4, Number<Dim0>());
703 }
704 };
705
706 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
707 int Dim3, int Dim4, char i, char j, char k, char l, char m>
708 inline const Tensor4_Expr<
709 const Tensor4_times_Tensor2_0_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
710 i, j, k, l, m>,
711 typename promote<T, U>::V, Dim1, Dim1, Dim2, Dim3, m, j, k, l>
714 {
715 typedef const Tensor4_times_Tensor2_0_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
716 Dim4, i, j, k, l, m>
717 TensorExpr;
719 Dim2, Dim3, m, j, k, l>(TensorExpr(a, b));
720 }
721
722 /* B(i,m)*A(i,j,k,l) */
723
724 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
725 int Dim3, int Dim4, char i, char j, char k, char l, char m>
726 inline const Tensor4_Expr<
727 const Tensor4_times_Tensor2_0_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
728 i, j, k, l, m>,
729 typename promote<T, U>::V, Dim1, Dim1, Dim2, Dim3, m, j, k, l>
732 {
733 typedef const Tensor4_times_Tensor2_0_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
734 Dim4, i, j, k, l, m>
735 TensorExpr;
737 Dim2, Dim3, m, j, k, l>(TensorExpr(a, b));
738 }
739
740 /* A(i,j,k,l)*B(m,i) */
741
742 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
743 int Dim3, int Dim4, char i, char j, char k, char l, char m>
745 {
748
749 template <int Current_Dim0>
750 typename promote<T, U>::V
751 eval(const int N1, const int N2, const int N3, const int N4,
752 const Number<Current_Dim0> &) const
753 {
754 return iterA(Current_Dim0 - 1, N2, N3, N4) * iterB(N1, Current_Dim0 - 1)
755 + eval(N1, N2, N3, N4, Number<Current_Dim0 - 1>());
756 }
757 typename promote<T, U>::V eval(const int N1, const int N2, const int N3,
758 const int N4, const Number<1> &) const
759 {
760 return iterA(0, N2, N3, N4) * iterB(N1, 0);
761 }
762
763 public:
767 : iterA(a), iterB(b)
768 {}
769 typename promote<T, U>::V
770 operator()(const int N1, const int N2, const int N3, const int N4) const
771 {
772 return eval(N1, N2, N3, N4, Number<Dim0>());
773 }
774 };
775
776 // FIXME: Template is ambiguous
777 // template<
778 // class A, class B, class T, class U, int Dim0,int Dim1, int Dim2,int Dim3,
779 // int Dim4,char i, char j, char k, char l,char m> inline const Tensor4_Expr
780 // <const
781 // Tensor4_times_Tensor2_0_1<A,B,T,U,Dim0,Dim1,Dim2,Dim3,Dim4,i,j,k,l,m>,typename
782 // promote<T,U>::V,Dim4,Dim1,Dim2,Dim3,m,j,k,l> operator*(
783 // const Tensor4_Expr<A,T,Dim0,Dim1,Dim2,Dim3,i,j,k,l> &a,
784 // const Tensor2_Expr<B,U,Dim4,Dim1,m,i> &b
785 // ) {
786 // typedef const
787 // Tensor4_times_Tensor2_0_1<A,B,T,U,Dim0,Dim1,Dim2,Dim3,Dim4,i,j,k,l,m>
788 // TensorExpr; return Tensor4_Expr<TensorExpr,typename
789 // promote<T,U>::V,Dim4,Dim1,Dim2,Dim3,m,j,k,l> (TensorExpr(a,b));
790 // }
791
792 /* B(i,m)*A(i,j,k,l) */
793
794 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
795 int Dim3, int Dim4, char i, char j, char k, char l, char m>
796 inline const Tensor4_Expr<
797 const Tensor4_times_Tensor2_0_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
798 i, j, k, l, m>,
799 typename promote<T, U>::V, Dim4, Dim1, Dim2, Dim3, m, j, k, l>
802 {
803 typedef const Tensor4_times_Tensor2_0_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
804 Dim4, i, j, k, l, m>
805 TensorExpr;
807 Dim2, Dim3, m, j, k, l>(TensorExpr(a, b));
808 }
809
810 /* A(i,j,k,l)*B(k,m) */
811
812 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
813 int Dim3, int Dim4, char i, char j, char k, char l, char m>
815 {
818
819 template <int Current_Dim0>
820 typename promote<T, U>::V
821 eval(const int N1, const int N2, const int N3, const int N4,
822 const Number<Current_Dim0> &) const
823 {
824 return iterA(N1, N2, Current_Dim0 - 1, N4) * iterB(Current_Dim0 - 1, N3)
825 + eval(N1, N2, N3, N4, Number<Current_Dim0 - 1>());
826 }
827 typename promote<T, U>::V eval(const int N1, const int N2, const int N3,
828 const int N4, const Number<1> &) const
829 {
830 return iterA(N1, N2, 0, N4) * iterB(0, N3);
831 }
832
833 public:
837 : iterA(a), iterB(b)
838 {}
839 typename promote<T, U>::V
840 operator()(const int N1, const int N2, const int N3, const int N4) const
841 {
842 return eval(N1, N2, N3, N4, Number<Dim3>());
843 }
844 };
845
846 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
847 int Dim3, int Dim4, char i, char j, char k, char l, char m>
848 inline const Tensor4_Expr<
849 const Tensor4_times_Tensor2_2_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
850 i, j, k, l, m>,
851 typename promote<T, U>::V, Dim0, Dim1, Dim4, Dim3, i, j, m, l>
854 {
855 typedef const Tensor4_times_Tensor2_2_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
856 Dim4, i, j, k, l, m>
857 TensorExpr;
859 Dim4, Dim3, i, j, m, l>(TensorExpr(a, b));
860 }
861
862 /* B(k,m)*A(i,j,k,l) */
863
864 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
865 int Dim3, int Dim4, char i, char j, char k, char l, char m>
866 inline const Tensor4_Expr<
867 const Tensor4_times_Tensor2_2_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
868 i, j, k, l, m>,
869 typename promote<T, U>::V, Dim0, Dim1, Dim4, Dim3, i, j, m, l>
872 {
873 typedef const Tensor4_times_Tensor2_2_0<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
874 Dim4, i, j, k, l, m>
875 TensorExpr;
877 Dim4, Dim3, i, j, m, l>(TensorExpr(a, b));
878 }
879
880 /* A(i,j,k,l)*B(m,k) */
881
882 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
883 int Dim3, int Dim4, char i, char j, char k, char l, char m>
885 {
888
889 template <int Current_Dim0>
890 typename promote<T, U>::V
891 eval(const int N1, const int N2, const int N3, const int N4,
892 const Number<Current_Dim0> &) const
893 {
894 return iterA(N1, N2, Current_Dim0 - 1, N4) * iterB(N3, Current_Dim0 - 1)
895 + eval(N1, N2, N3, N4, Number<Current_Dim0 - 1>());
896 }
897 typename promote<T, U>::V eval(const int N1, const int N2, const int N3,
898 const int N4, const Number<1> &) const
899 {
900 return iterA(N1, N2, 0, N4) * iterB(N3, 0);
901 }
902
903 public:
907 : iterA(a), iterB(b)
908 {}
909 typename promote<T, U>::V
910 operator()(const int N1, const int N2, const int N3, const int N4) const
911 {
912 return eval(N1, N2, N3, N4, Number<Dim3>());
913 }
914 };
915
916 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
917 int Dim3, int Dim4, char i, char j, char k, char l, char m>
918 inline const Tensor4_Expr<
919 const Tensor4_times_Tensor2_2_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
920 i, j, k, l, m>,
921 typename promote<T, U>::V, Dim0, Dim1, Dim4, Dim3, i, j, m, l>
924 {
925 typedef const Tensor4_times_Tensor2_2_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
926 Dim4, i, j, k, l, m>
927 TensorExpr;
929 Dim4, Dim3, i, j, m, l>(TensorExpr(a, b));
930 }
931
932 /* B(m,k)*A(i,j,k,l) */
933
934 template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim2,
935 int Dim3, int Dim4, char i, char j, char k, char l, char m>
936 inline const Tensor4_Expr<
937 const Tensor4_times_Tensor2_2_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3, Dim4,
938 i, j, k, l, m>,
939 typename promote<T, U>::V, Dim0, Dim1, Dim4, Dim3, i, j, m, l>
942 {
943 typedef const Tensor4_times_Tensor2_2_1<A, B, T, U, Dim0, Dim1, Dim2, Dim3,
944 Dim4, i, j, k, l, m>
945 TensorExpr;
947 Dim4, Dim3, i, j, m, l>(TensorExpr(a, b));
948 }
949
950} // namespace FTensor
static Number< 2 > N2
static Number< 1 > N1
constexpr double a
promote< T, U >::V operator()(const int N1, const int N2) const
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &, const Number< 1 > &) const
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &, const Number< Current_Dim1 > &) const
Tensor4_times_Tensor2_03(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim0, Dim3, i, l > &b)
const Tensor2_Expr< B, U, Dim0, Dim3, i, l > iterB
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
promote< T, U >::V eval(const int N1, const int N2, const Number< Current_Dim0 > &, const Number< Current_Dim1 > &) const
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< 1 > &) const
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< Current_Dim0 > &) const
Tensor4_times_Tensor2_0_0(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim0, Dim4, i, m > &b)
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
const Tensor2_Expr< B, U, Dim0, Dim4, i, m > iterB
Tensor4_times_Tensor2_0_1(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim4, Dim1, m, i > &b)
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< 1 > &) const
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< Current_Dim0 > &) const
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
const Tensor2_Expr< B, U, Dim4, Dim0, m, i > iterB
promote< T, U >::V operator()(const int N1, const int N2) const
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
const Tensor2_Expr< B, U, Dim2, Dim3, j, l > iterB
promote< T, U >::V eval(const int N1, const int N2, const Number< Current_Dim0 > &, const Number< Current_Dim1 > &) const
Tensor4_times_Tensor2_13(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim2, Dim3, j, l > &b)
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &, const Number< 1 > &) const
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &, const Number< Current_Dim1 > &) const
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< 1 > &) const
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const
const Tensor2_Expr< B, U, Dim1, Dim4, j, m > iterB
Tensor4_times_Tensor2_1_0(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim1, Dim4, j, m > &b)
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< Current_Dim0 > &) const
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< 1 > &) const
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
const Tensor2_Expr< B, U, Dim4, Dim1, m, j > iterB
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< Current_Dim0 > &) const
Tensor4_times_Tensor2_1_1(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim4, Dim1, m, j > &b)
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &, const Number< 1 > &) const
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &, const Number< Current_Dim1 > &) const
promote< T, U >::V eval(const int N1, const int N2, const Number< Current_Dim0 > &, const Number< Current_Dim1 > &) const
Tensor4_times_Tensor2_23(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim2, Dim3, k, l > &b)
promote< T, U >::V operator()(const int N1, const int N2) const
const Tensor2_Expr< B, U, Dim2, Dim3, k, l > iterB
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
const Tensor2_Expr< B, U, Dim2, Dim4, k, m > iterB
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< 1 > &) const
Tensor4_times_Tensor2_2_0(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim2, Dim4, k, m > &b)
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< Current_Dim0 > &) const
Tensor4_times_Tensor2_2_1(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim4, Dim2, m, k > &b)
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< Current_Dim0 > &) const
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< 1 > &) const
const Tensor2_Expr< B, U, Dim4, Dim2, m, k > iterB
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
Tensor4_times_Tensor2_30(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim3, Dim0, l, i > &b)
promote< T, U >::V operator()(const int N1, const int N2) const
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &, const Number< Current_Dim1 > &) const
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &, const Number< 1 > &) const
promote< T, U >::V eval(const int N1, const int N2, const Number< Current_Dim0 > &, const Number< Current_Dim1 > &) const
const Tensor2_Expr< B, U, Dim3, Dim0, l, i > iterB
const Tensor2_Expr< B, U, Dim3, Dim2, l, k > iterB
Tensor4_times_Tensor2_32(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim3, Dim2, l, k > &b)
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &, const Number< Current_Dim1 > &) const
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
promote< T, U >::V operator()(const int N1, const int N2) const
promote< T, U >::V eval(const int N1, const int N2, const Number< Current_Dim0 > &, const Number< Current_Dim1 > &) const
promote< T, U >::V eval(const int N1, const int N2, const Number< 1 > &, const Number< 1 > &) const
Tensor4_times_Tensor2_3_0(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim4, Dim3, m, l > &b)
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< 1 > &) const
const Tensor2_Expr< B, U, Dim4, Dim3, m, l > iterB
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< Current_Dim0 > &) const
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
promote< T, U >::V operator()(const int N1, const int N2, const int N3, const int N4) const
const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > iterA
const Tensor2_Expr< B, U, Dim3, Dim4, l, m > iterB
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< Current_Dim0 > &) const
Tensor4_times_Tensor2_3_1(const Tensor4_Expr< A, T, Dim0, Dim1, Dim2, Dim3, i, j, k, l > &a, const Tensor2_Expr< B, U, Dim3, Dim4, l, m > &b)
promote< T, U >::V eval(const int N1, const int N2, const int N3, const int N4, const Number< 1 > &) const
FTensor::Index< 'm', SPACE_DIM > m
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
const double T
Tensors class implemented by Walter Landry.
Definition: FTensor.hpp:51
promote< T, U >::V operator*(const Ddg_Expr< A, T, Dim, Dim, i, j, k, l > &a, const Ddg_Expr< B, U, Dim, Dim, i, k, j, l > &b)
constexpr AssemblyType A