16 return (N1 == N2) ? T(0) : ((N1 == 0) ? T(1) : T(-1));
19 template <
char i,
char j,
int Dim0,
int Dim1>
21 (Dim0 <= 2 && Dim1 <= 2),
28 template <
char i,
int Dim0>
33 "Index dimension exceeds the maximum for Rank 2 Levi-Civita Tensor");
36 throw std::out_of_range(
37 "Bad index in Levi_Civita<T>::operator()(Index<"
38 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
39 + std::to_string(N1) +
")\n");
42 = [
this, N1](
const int &N0) {
return this->
operator()(N0, N1); };
46 template <
char j,
int Dim1>
51 "Index dimension exceeds the maximum for Rank 2 Levi-Civita Tensor");
54 throw std::out_of_range(
"Bad index in Levi_Civita<T>::operator()("
55 + std::to_string(N0) +
", Index<"
56 + std::basic_string<char>{
j} +
", "
57 + std::to_string(Dim1) +
">)\n");
60 = [
this, N0](
const int &N1) {
return this->
operator()(N0, N1); };
61 return Tensor1_Expr<decltype(TensorExpr), T, Dim1,
j>{TensorExpr};
65 constexpr T
operator()(
const int N1,
const int N2,
const int N3)
const
67 return (N1 == N2 || N1 == N3 || N2 == N3)
69 : (((N1 + 1) % 3 == N2) ? T(1) : T(-1));
72 template <
char i,
char j,
char k,
int Dim0,
int Dim1,
int Dim2>
74 (Dim0 <= 3 && Dim1 <= 3 && Dim2 <= 3),
82 template <
char i,
char j,
int Dim0,
int Dim1>
87 Dim0 <= 3 && Dim1 <= 3,
88 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
91 throw std::out_of_range(
92 "Bad index in Levi_Civita<T>::operator()("
94 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0)
97 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
98 + std::to_string(N2) +
")\n");
100 auto TensorExpr = [
this, N2](
const int &N0,
const int &N1) {
107 template <
char i,
char k,
int Dim0,
int Dim2>
112 Dim0 <= 3 && Dim2 <= 3,
113 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
115 if(N1 >= 3 || N1 < 0)
116 throw std::out_of_range(
117 "Bad index in Levi_Civita<T>::operator()("
119 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
123 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">)\n");
125 auto TensorExpr = [
this, N1](
const int &N0,
const int &N2) {
132 template <
char j,
char k,
int Dim1,
int Dim2>
137 Dim1 <= 3 && Dim2 <= 3,
138 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
140 if(N0 >= 3 || N0 < 0)
141 throw std::out_of_range(
142 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(N0)
145 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1)
148 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">)\n");
150 auto TensorExpr = [
this, N0](
const int &N1,
const int &N2) {
157 template <
char i,
int Dim0>
162 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
164 if(N1 >= 3 || N1 < 0 || N2 >= 3 || N2 < 0)
165 throw std::out_of_range(
166 "Bad index in Levi_Civita<T>::operator()("
168 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
169 + std::to_string(N1) +
", " + std::to_string(N2) +
")\n");
171 auto TensorExpr = [
this, N1, N2](
const int &N0) {
174 return Tensor1_Expr<decltype(TensorExpr), T, Dim0,
i>{TensorExpr};
177 template <
char j,
int Dim1>
182 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
184 if(N0 >= 3 || N0 < 0 || N2 >= 3 || N2 < 0)
185 throw std::out_of_range(
186 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(N0)
189 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
190 + std::to_string(N2) +
")\n");
192 auto TensorExpr = [
this, N0, N2](
const int &N1) {
195 return Tensor1_Expr<decltype(TensorExpr), T, Dim1,
j>{TensorExpr};
198 template <
char k,
int Dim2>
203 "Index dimension exceeds the maximum for Rank 3 Levi-Civita Tensor");
205 if(N0 >= 3 || N0 < 0 || N1 >= 3 || N1 < 0)
206 throw std::out_of_range(
207 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(N0)
208 +
", " + std::to_string(N1)
211 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">)\n");
213 auto TensorExpr = [
this, N0, N1](
const int &N2) {
216 return Tensor1_Expr<decltype(TensorExpr), T, Dim2,
k>{TensorExpr};
221 operator()(
const int N1,
const int N2,
const int N3,
const int N4)
const
223 return (N1 == N2 || N1 == N3 || N1 == N4 || N2 == N3 || N2 == N4
226 : ((N1 + N2 == 1 || N1 + N2 == 5)
227 ? (((N2 + N3) % 4 == 3) ? T(1) : T(-1))
228 : ((N1 + N2 == 2 || N1 + N2 == 4)
229 ? (((N2 + N3) % 4 == 1) ? T(1) : T(-1))
231 ? (((N2 + N3) % 4 != 1) ? T(1) : T(-1))
235 template <
char i,
char j,
char k,
char l,
int Dim0,
int Dim1,
int Dim2,
238 (Dim0 <= 4 && Dim1 <= 4 && Dim2 <= 4 && Dim3 <= 4),
247 template <
char i,
char j,
char k,
int Dim0,
int Dim1,
int Dim2>
252 Dim0 <= 4 && Dim1 <= 4 && Dim2 <= 4,
253 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
255 if(N3 >= 4 || N3 < 0)
256 throw std::out_of_range(
257 "Bad index in Levi_Civita<T>::operator()("
259 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0)
262 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1)
265 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">, "
266 + std::to_string(N3) +
")\n");
269 = [
this, N3](
const int &N0,
const int &N1,
const int &N2) {
272 return Tensor3_Expr<decltype(TensorExpr), T, Dim0, Dim1, Dim2,
i,
j,
k>{
276 template <
char i,
char j,
char l,
int Dim0,
int Dim1,
int Dim3>
281 Dim0 <= 4 && Dim1 <= 4 && Dim3 <= 4,
282 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
284 if(N2 >= 4 || N2 < 0)
285 throw std::out_of_range(
286 "Bad index in Levi_Civita<T>::operator()("
288 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0)
291 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
295 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
298 = [
this, N2](
const int &N0,
const int &N1,
const int &N3) {
301 return Tensor3_Expr<decltype(TensorExpr), T, Dim0, Dim1, Dim3,
i,
j,
l>{
305 template <
char i,
char k,
char l,
int Dim0,
int Dim2,
int Dim3>
310 Dim0 <= 4 && Dim2 <= 4 && Dim3 <= 4,
311 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
313 if(N1 >= 4 || N1 < 0)
314 throw std::out_of_range(
315 "Bad index in Levi_Civita<T>::operator()("
317 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
321 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2)
324 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
327 = [
this, N1](
const int &N0,
const int &N2,
const int &N3) {
330 return Tensor3_Expr<decltype(TensorExpr), T, Dim0, Dim2, Dim3,
i,
k,
l>{
334 template <
char j,
char k,
char l,
int Dim1,
int Dim2,
int Dim3>
339 Dim1 <= 4 && Dim2 <= 4 && Dim3 <= 4,
340 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
342 if(N0 >= 4 || N0 < 0)
343 throw std::out_of_range(
344 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(N0)
347 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1)
350 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2)
353 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
356 = [
this, N0](
const int &N1,
const int &N2,
const int &N3) {
359 return Tensor3_Expr<decltype(TensorExpr), T, Dim1, Dim2, Dim3,
j,
k,
l>{
363 template <
char i,
char j,
int Dim0,
int Dim1>
365 const int &N2,
const int &N3)
368 Dim0 <= 4 && Dim1 <= 4,
369 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
371 if(N2 >= 4 || N2 < 0 || N3 >= 4 || N3 < 0)
372 throw std::out_of_range(
373 "Bad index in Levi_Civita<T>::operator()("
375 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0)
378 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
379 + std::to_string(N2) +
", " + std::to_string(N3) +
")\n");
381 auto TensorExpr = [
this, N2, N3](
const int &N0,
const int &N1) {
388 template <
char i,
char k,
int Dim0,
int Dim2>
393 Dim0 <= 4 && Dim2 <= 4,
394 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
396 if(N1 >= 4 || N1 < 0 || N3 >= 4 || N3 < 0)
397 throw std::out_of_range(
398 "Bad index in Levi_Civita<T>::operator()("
400 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
404 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">, "
405 + std::to_string(N3) +
")\n");
407 auto TensorExpr = [
this, N1, N3](
const int &N0,
const int &N2) {
414 template <
char j,
char k,
int Dim1,
int Dim2>
419 Dim1 <= 4 && Dim2 <= 4,
420 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
422 if(N0 >= 4 || N0 < 0 || N3 >= 4 || N3 < 0)
423 throw std::out_of_range(
424 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(N0)
427 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1)
430 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">, "
431 + std::to_string(N3) +
")\n");
433 auto TensorExpr = [
this, N0, N3](
const int &N1,
const int &N2) {
440 template <
char i,
char l,
int Dim0,
int Dim3>
445 Dim0 <= 4 && Dim3 <= 4,
446 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
448 if(N1 >= 4 || N1 < 0 || N2 >= 4 || N2 < 0)
449 throw std::out_of_range(
450 "Bad index in Levi_Civita<T>::operator()("
452 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
453 + std::to_string(N1) +
", " + std::to_string(N2)
456 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
458 auto TensorExpr = [
this, N1, N2](
const int &N0,
const int &N3) {
465 template <
char j,
char l,
int Dim1,
int Dim3>
470 Dim1 <= 4 && Dim3 <= 4,
471 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
473 if(N0 >= 4 || N0 < 0 || N2 >= 4 || N2 < 0)
474 throw std::out_of_range(
475 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(N0)
478 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
482 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
484 auto TensorExpr = [
this, N0, N2](
const int &N1,
const int &N3) {
491 template <
char k,
char l,
int Dim2,
int Dim3>
496 Dim2 <= 4 && Dim3 <= 4,
497 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
499 if(N0 >= 4 || N0 < 0 || N1 >= 4 || N1 < 0)
500 throw std::out_of_range(
501 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(N0)
502 +
", " + std::to_string(N1)
505 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2)
508 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
510 auto TensorExpr = [
this, N0, N1](
const int &N2,
const int &N3) {
517 template <
char i,
int Dim0>
519 const int &N2,
const int &N3)
523 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
525 if(N1 >= 4 || N1 < 0 || N2 >= 4 || N2 < 0 || N3 >= 4 || N3 < 0)
526 throw std::out_of_range(
527 "Bad index in Levi_Civita<T>::operator()("
529 + std::basic_string<char>{
i} +
", " + std::to_string(Dim0) +
">, "
530 + std::to_string(N1) +
", " + std::to_string(N2) +
", "
531 + std::to_string(N3) +
")\n");
533 auto TensorExpr = [
this, N1, N2, N3](
const int &N0) {
536 return Tensor1_Expr<decltype(TensorExpr), T, Dim0,
i>{TensorExpr};
539 template <
char j,
int Dim1>
541 const int &N2,
const int &N3)
545 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
547 if(N0 >= 4 || N0 < 0 || N2 >= 4 || N2 < 0 || N3 >= 4 || N3 < 0)
548 throw std::out_of_range(
549 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(N0)
552 + std::basic_string<char>{
j} +
", " + std::to_string(Dim1) +
">, "
553 + std::to_string(N2) +
", " + std::to_string(N3) +
")\n");
555 auto TensorExpr = [
this, N0, N2, N3](
const int &N1) {
558 return Tensor1_Expr<decltype(TensorExpr), T, Dim1,
j>{TensorExpr};
561 template <
char k,
int Dim2>
567 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
569 if(N0 >= 4 || N0 < 0 || N1 >= 4 || N1 < 0 || N3 >= 4 || N3 < 0)
570 throw std::out_of_range(
571 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(N0)
572 +
", " + std::to_string(N1)
575 + std::basic_string<char>{
k} +
", " + std::to_string(Dim2) +
">, "
576 + std::to_string(N3) +
")\n");
578 auto TensorExpr = [
this, N0, N1, N3](
const int &N2) {
581 return Tensor1_Expr<decltype(TensorExpr), T, Dim2,
k>{TensorExpr};
584 template <
char l,
int Dim3>
585 constexpr
auto operator()(
const int &N0,
const int &N1,
const int &N2,
590 "Index dimension exceeds the maximum for Rank 4 Levi-Civita Tensor");
592 if(N0 >= 4 || N0 < 0 || N1 >= 4 || N1 < 0 || N2 >= 4 || N2 < 0)
593 throw std::out_of_range(
594 "Bad index in Levi_Civita<T>::operator()(" + std::to_string(N0)
595 +
", " + std::to_string(N1) +
", " + std::to_string(N2)
598 + std::basic_string<char>{
l} +
", " + std::to_string(Dim3) +
">)\n");
600 auto TensorExpr = [
this, N0, N1, N2](
const int &N3) {
603 return Tensor1_Expr<decltype(TensorExpr), T, Dim3,
l>{TensorExpr};
613 template <
class T =
int,
char i,
char j,
int Dim0,
int Dim1>
615 (Dim0 <= 2 && Dim1 <= 2),
616 Tensor2_Expr<Levi_Civita<T>, T, Dim0, Dim1,
i,
j>>::
type
622 template <
class T =
int,
char i,
int Dim0>
628 template <
class T =
int,
char j,
int Dim1>
635 template <
class T =
int,
char i,
char j,
char k,
int Dim0,
int Dim1,
int Dim2>
637 (Dim0 <= 3 && Dim1 <= 3 && Dim2 <= 3),
638 Tensor3_Expr<Levi_Civita<T>, T, Dim0, Dim1, Dim2,
i,
j,
k>>::
type
646 template <
class T =
int,
char i,
char j,
int Dim0,
int Dim1>
653 template <
class T =
int,
char i,
char k,
int Dim0,
int Dim2>
660 template <
class T =
int,
char j,
char k,
int Dim1,
int Dim2>
667 template <
class T =
int,
char i,
int Dim0>
674 template <
class T =
int,
char j,
int Dim1>
681 template <
class T =
int,
char k,
int Dim2>
689 template <
class T =
int,
char i,
char j,
char k,
char l,
int Dim0,
int Dim1,
692 (Dim0 <= 4 && Dim1 <= 4 && Dim2 <= 4 && Dim3 <= 4),
693 Tensor4_Expr<Levi_Civita<T>, T, Dim0, Dim1, Dim2, Dim3,
i,
j,
k,
l>>::
type
701 template <
class T =
int,
char i,
char j,
char k,
int Dim0,
int Dim1,
int Dim2>
709 template <
class T =
int,
char i,
char j,
char l,
int Dim0,
int Dim1,
int Dim3>
717 template <
class T =
int,
char i,
char k,
char l,
int Dim0,
int Dim2,
int Dim3>
725 template <
class T =
int,
char j,
char k,
char l,
int Dim1,
int Dim2,
int Dim3>
733 template <
class T =
int,
char i,
char j,
int Dim0,
int Dim1>
735 const int &N2,
const int &N3)
740 template <
class T =
int,
char i,
char k,
int Dim0,
int Dim2>
747 template <
class T =
int,
char j,
char k,
int Dim1,
int Dim2>
754 template <
class T =
int,
char i,
char l,
int Dim0,
int Dim3>
761 template <
class T =
int,
char j,
char l,
int Dim1,
int Dim3>
768 template <
class T =
int,
char k,
char l,
int Dim2,
int Dim3>
775 template <
class T =
int,
char i,
int Dim0>
777 const int &N2,
const int &N3)
782 template <
class T =
int,
char j,
int Dim1>
784 const int &N2,
const int &N3)
789 template <
class T =
int,
char k,
int Dim2>
796 template <
class T =
int,
char l,
int Dim3>
797 constexpr
auto levi_civita(
const int &N0,
const int &N1,
const int &N2,