20 #ifndef EXTERIOR_ALGEBRA_HPP
21 #define EXTERIOR_ALGEBRA_HPP
28 #include <unordered_map>
34 #include <Eigen/Dense>
35 #include <unsupported/Eigen/KroneckerProduct>
61 template<
size_t l,
size_t d>
66 static void init() noexcept {
67 static_assert(0 <= l && l <= d,
"Error: Tried to generate the exterior algebra basis outside the range [0,d]");
68 if (initialized == 1)
return;
71 std::array<size_t, l> cbasis;
72 for (
size_t i = 0; i < l; ++i) {
75 _basis.try_emplace(acc,cbasis);
76 while (_find_next_tuple(cbasis)) {
78 _basis.try_emplace(acc,cbasis);
85 assert(initialized==1 &&
"ExteriorBasis was not initialized");
91 auto found = std::find_if(_basis.begin(), _basis.end(), [&tuple](
const auto& p)
92 {return p.second == tuple;});
93 if (found != _basis.end()) {
102 static inline std::unordered_map<size_t, std::array<size_t, l>> _basis;
103 static inline int initialized = 0;
105 static bool _find_next_tuple(std::array<size_t, l> &basis) noexcept {
106 for (
size_t i = 0; i < l; ++i) {
107 size_t nval = basis[l - i - 1] + 1;
109 basis[l - i - 1] = nval;
110 for (
size_t j = 1; j <= i ; ++j){
111 basis[l - i - 1 + j] = nval + j;
123 template<
size_t l,
size_t d>
131 static int _get_basis_sign(std::array<size_t,l>
const &ori_basis, std::array<size_t,d-l>
const &star_basis) {
133 size_t star_rem = d-l;
136 for (
size_t c_t = 0; c_t < d; ++c_t) {
137 if (ori_rem > 0 && ori_basis[l-ori_rem] == c_t) {
139 if (star_rem > 0 && star_basis[d-l-star_rem] == c_t) {
145 if (star_rem > 0 && star_basis[d-l-star_rem] == c_t) {
147 sign *= (ori_rem%2 == 0)? 1 : -1;
157 if constexpr (l == 0 || l == d) {
158 return Eigen::Matrix<double,1,1>{1.};
165 rv(i_l,i_r) = _get_basis_sign(ori_basis,star_basis);
181 template<
typename V,
typename Derived>
183 constexpr
size_t N = std::tuple_size<V>::value;
184 if constexpr (N==0) {
186 }
else if constexpr (N == 1) {
187 return A(a1[0],a2[0]);
191 std::array<
typename V::value_type,N-1> b1,b2;
192 std::copy(a1.cbegin()+1,a1.cend(),b1.begin());
193 std::copy(a2.cbegin()+1,a2.cend(),b2.begin());
194 for (
size_t i = 0; i < N-1;++i){
208 template<
size_t l,
size_t d1,
size_t d2>
210 template<
typename Derived>
222 template<
size_t d1,
size_t d2>
224 template<
typename Derived>
225 static Eigen::Matrix<double,1,1>
compute(Eigen::MatrixBase<Derived>
const & A) {
226 return Eigen::Matrix<double,1,1>{1.};
230 template<
size_t d1,
size_t d2>
232 template<
typename Derived>
233 static Eigen::Matrix<double,d1,d2>
compute(Eigen::MatrixBase<Derived>
const & A) {
234 return A.transpose();
240 template<
typename Derived>
241 static Eigen::Matrix<double,1,1>
compute(Eigen::MatrixBase<Derived>
const & A) {
242 return Eigen::Matrix<double,1,1>{A.determinant()};
248 template<
typename Derived>
249 static Eigen::Matrix<double,1,1>
compute(Eigen::MatrixBase<Derived>
const & A) {
250 return Eigen::Matrix<double,1,1>{A(0,0)};
256 template<
typename Derived>
257 static Eigen::Matrix<double,1,3>
compute(Eigen::MatrixBase<Derived>
const & A) {
258 return Eigen::Matrix<double,1,3>{{A(0,0)*A(1,1) - A(0,1)*A(1,0), A(0,0)*A(2,1) - A(0,1)*A(2,0), A(1,0)*A(2,1) - A(1,1)*A(2,0)}};
263 template<
typename Derived>
264 static Eigen::Matrix<double,3,1>
compute(Eigen::MatrixBase<Derived>
const & A) {
265 return Eigen::Matrix<double,3,1>{A(0,0)*A(1,1) - A(0,1)*A(1,0), A(0,0)*A(1,2) - A(0,2)*A(1,0), A(0,1)*A(1,2) - A(0,2)*A(1,1)};
270 template<
typename Derived>
271 static Eigen::Matrix<double,3,3>
compute(Eigen::MatrixBase<Derived>
const & A) {
272 return Eigen::Matrix<double,3,3>{
273 {A(0,0)*A(1,1) - A(0,1)*A(1,0), A(0,0)*A(2,1) - A(0,1)*A(2,0), A(1,0)*A(2,1) - A(1,1)*A(2,0)},
274 {A(0,0)*A(1,2) - A(0,2)*A(1,0), A(0,0)*A(2,2) - A(0,2)*A(2,0), A(1,0)*A(2,2) - A(1,2)*A(2,0)},
275 {A(0,1)*A(1,2) - A(0,2)*A(1,1), A(0,1)*A(2,2) - A(0,2)*A(2,1), A(1,1)*A(2,2) - A(1,2)*A(2,1)}
284 template<
typename Derived>
285 static Eigen::Matrix<double,
Dimension::ExtDim(l,Eigen::internal::traits< Derived >::RowsAtCompileTime),
287 compute(Eigen::MatrixBase<Derived>
const & g) {
288 constexpr
auto N = Eigen::internal::traits< Derived >::RowsAtCompileTime;
289 static_assert(N == Eigen::internal::traits< Derived >::ColsAtCompileTime);
290 static_assert(N > 0);
306 static std::vector<std::array<size_t, d>>
const &
homogeneous(
const int r) {
307 assert(r <= _init_deg &&
"Error: Monomial_powers must be initialized first");
312 static std::vector<std::array<size_t,d>>
const &
complete(
const int r) {
313 assert(r <= _init_deg &&
"Error: Monomial_powers must be initialized first");
314 return _powers_full[r];
318 static void init(
const int r) {
319 static_assert(d > 0,
"Error: Tried to construct a monomial basis in dimension 0");
320 assert(r <= _max_deg &&
"Maximum degree reached, increase _max_deg if needed");
322 for (
int h_r = _init_deg + 1; h_r <= r; ++h_r) {
323 std::vector<std::array<size_t,d>> powers;
324 std::array<size_t,d> current;
325 inner_loop(0,h_r,current,powers);
326 _powers[h_r] = powers;
328 _powers_full[0] = powers;
330 _powers_full[h_r] = _powers_full[h_r-1];
331 for (
size_t j = 0; j < powers.size(); ++j) {
332 _powers_full[h_r].emplace_back(powers[j]);
341 static constexpr
int _max_deg = 20;
342 static inline int _init_deg = -1;
343 static inline std::array<std::vector<std::array<size_t,d>>,_max_deg+1> _powers;
344 static inline std::array<std::vector<std::array<size_t,d>>,_max_deg+1> _powers_full;
346 static void inner_loop(
size_t cindex,
int max, std::array<size_t,d> & current, std::vector<std::array<size_t,d>> & powers) {
348 current[cindex] = max;
349 powers.emplace_back(current);
351 for(
int i = 0; i <= max; ++i) {
353 inner_loop(cindex+1,max-i,current,powers);
Return a mapping from the basis of l-forms in dimension d to the basis of (d-l)-forms.
Definition: exterior_algebra.hpp:124
static Eigen::Matrix< double, Dimension::ExtDim(d-l, d), Dimension::ExtDim(l, d)> const & compute()
Definition: exterior_algebra.hpp:126
Class to handle the exterior algebra basis.
Definition: exterior_algebra.hpp:63
static const size_t index_from_tuple(const std::array< size_t, l > &tuple)
Search the index corresponding to the given tuple. Throw if not found.
Definition: exterior_algebra.hpp:90
static const std::array< size_t, l > & expand_basis(size_t i)
Return the coefficient of the basis at the given index.
Definition: exterior_algebra.hpp:83
static void init() noexcept
Initialize the exterior algebra basis. Must be called at least once before use.
Definition: exterior_algebra.hpp:66
constexpr functions to compute the dimension of various polynomial spaces
constexpr size_t ExtDim(size_t l, size_t d)
Dimension of the exterior algebra .
Definition: exterior_dimension.hpp:37
double Compute_partial_det(const V &a1, const V &a2, const Eigen::MatrixBase< Derived > &A)
Generic determinant computation.
Definition: exterior_algebra.hpp:182
Definition: maxwell.hpp:21
Wrapper for the product on the exterior algebra.
Definition: exterior_algebra.hpp:283
static Eigen::Matrix< double, Dimension::ExtDim(l, Eigen::internal::traits< Derived >::RowsAtCompileTime), Dimension::ExtDim(l, Eigen::internal::traits< Derived >::RowsAtCompileTime)> compute(Eigen::MatrixBase< Derived > const &g)
Definition: exterior_algebra.hpp:287
static Eigen::Matrix< double, 1, 1 > compute(Eigen::MatrixBase< Derived > const &A)
Definition: exterior_algebra.hpp:225
static Eigen::Matrix< double, 1, 1 > compute(Eigen::MatrixBase< Derived > const &A)
Definition: exterior_algebra.hpp:249
static Eigen::Matrix< double, d1, d2 > compute(Eigen::MatrixBase< Derived > const &A)
Definition: exterior_algebra.hpp:233
static Eigen::Matrix< double, 1, 3 > compute(Eigen::MatrixBase< Derived > const &A)
Definition: exterior_algebra.hpp:257
static Eigen::Matrix< double, 3, 1 > compute(Eigen::MatrixBase< Derived > const &A)
Definition: exterior_algebra.hpp:264
static Eigen::Matrix< double, 3, 3 > compute(Eigen::MatrixBase< Derived > const &A)
Definition: exterior_algebra.hpp:271
static Eigen::Matrix< double, 1, 1 > compute(Eigen::MatrixBase< Derived > const &A)
Definition: exterior_algebra.hpp:241
Generic pullback computation.
Definition: exterior_algebra.hpp:209
static Eigen::Matrix< double, Dimension::ExtDim(l, d1), Dimension::ExtDim(l, d2)> compute(Eigen::MatrixBase< Derived > const &A)
Definition: exterior_algebra.hpp:211
Generate a basis of monomial powers of degree r.
Definition: exterior_algebra.hpp:304
static std::vector< std::array< size_t, d > > const & homogeneous(const int r)
Basis of homogeneous polynomial of degree r.
Definition: exterior_algebra.hpp:306
static void init(const int r)
Initialise the basis for degree up to r. Must be called at least once before use.
Definition: exterior_algebra.hpp:318
static std::vector< std::array< size_t, d > > const & complete(const int r)
Basis of polynomial of at most degree r.
Definition: exterior_algebra.hpp:312