HILA
Loading...
Searching...
No Matches
levi_civita.h
1#ifndef LEVI_CIVITA_H_
2#define LEVI_CIVITA_H_
3
4#include "hila.h"
5
6
7template <int N>
8struct Factorial {
9 enum { value=N*Factorial<N-1>::value };
10};
11
12template <>
13struct Factorial<0> {
14 enum { value=1 };
15};
16
17
18template<int N,int Nfac=Factorial<N>::value>
19class levi_civita {
20 // template class to provide the non-zero elements of the N-dimensional
21 // Levi-Civita symbol.
22 // (would be nice to make a[Nfac][N+1] static constexpr, but haven't
23 // figured out yet how to do it with C++17)
24public:
25 static constexpr int n=N;
26 static constexpr int nfac=Nfac;
27
28 int a[Nfac][N+1];
29
30 constexpr levi_civita() {
31 int tarr0[N+1]; // inital sequence and permutation sign :
32 // sequence {0,1,2,...,N-1} :
33 for(int i=0; i<N; ++i) {
34 tarr0[i]=i;
35 }
36 // sign 1 :
37 tarr0[N]=1;
38
39 int ind[N]{0}; //initial permutation vector is zero
40 for(int j=0; j<Nfac; ++j) {
41 // initialize a[j][]=tarr0[] :
42 for(int i=0; i<n+1; ++i) {
43 a[j][i]=tarr0[i];
44 }
45 // apply permutation given by ind[] to a[j][] :
46 for(int i=0; i<n-1; ++i) {
47 if(ind[i]!=0) {
48 // swap a[j][i] with a[j][i+ind[i]]:
49 int te=a[j][i];
50 int ti=i+ind[i];
51 a[j][i]=a[j][ti];
52 a[j][ti]=te;
53 // flip sign on a[j][]:
54 a[j][N]=-a[j][N];
55 }
56 }
57
58 // next permuation vector:
59 ++ind[N-1];
60 for(int i=n-1; i>=1; --i) {
61 if(ind[i]>n-1-i) {
62 ind[i]=0;
63 ++ind[i-1];
64 }
65 }
66 }
67
68 }
69
70};
71#endif