15#include <unordered_map>
22#include <unsupported/Eigen/KroneckerProduct>
45 template<
size_t l,
size_t d>
49 static void init() noexcept {
50 static_assert(0 <= l && l <= d,
"Error: Tried to generate the exterior algebra basis outside the range [0,d]");
51 if (initialized == 1)
return;
54 std::array<size_t, l> cbasis;
55 for (
size_t i = 0; i < l; ++i) {
58 _basis.try_emplace(acc,cbasis);
59 while (_find_next_tuple(cbasis)) {
61 _basis.try_emplace(acc,cbasis);
67 assert(initialized==1 &&
"ExteriorBasis was not initialized");
72 auto found = std::find_if(_basis.begin(), _basis.end(), [&tuple](
const auto& p)
73 {return p.second == tuple;});
74 if (found != _basis.end()) {
83 static inline std::unordered_map<size_t, std::array<size_t, l>> _basis;
84 static inline int initialized = 0;
86 static bool _find_next_tuple(std::array<size_t, l> &basis)
noexcept {
87 for (
size_t i = 0; i < l; ++i) {
88 size_t nval = basis[l - i - 1] + 1;
90 basis[l - i - 1] = nval;
91 for (
size_t j = 1; j <= i ; ++j){
92 basis[l - i - 1 + j] = nval + j;
107 template<
size_t l,
size_t d>
113 return _transforms.at(i);
117 static_assert(0 < l && l <= d,
"Error: Tried to generate Koszul basis outside the range [1,d]");
118 if (initialized == 1)
return;
122 for (
size_t i = 0; i < d; ++i) {
123 _transforms[i].setZero();
126 for (
size_t i = 0; i < d; ++i) {
127 _transforms[i](0,i) = 1;
135 std::array<size_t,l> basis_cp;
136 std::copy(cbasis.cbegin(),cbasis.cend(),basis_cp.begin()+1);
138 for (
size_t j = 0; j < d; ++j) {
139 if (try_pos == l-1 || j < cbasis[try_pos]) {
140 basis_cp[try_pos] = j;
143 basis_cp[try_pos] = basis_cp[try_pos+1];
153 static inline int initialized = 0;
154 static inline std::array<ExtAlgMatType,d> _transforms;
157 template<
size_t l,
size_t d>
163 return _transforms.at(i);
167 static_assert(l < d,
"Error: Tried to generate diff basis outside the range [0,d-1]");
168 if (initialized == 1)
return;
171 for (
size_t i = 0; i < d; ++i) {
176 static inline int initialized = 0;
177 static inline std::array<ExtAlgMatType,d> _transforms;
188 template<
typename V,
typename Derived>
190 constexpr size_t N = std::tuple_size<V>::value;
191 if constexpr (N==0) {
193 }
else if constexpr (N == 1) {
194 return A(a1[0],a2[0]);
198 std::array<
typename V::value_type,N-1> b1,b2;
199 std::copy(a1.cbegin()+1,a1.cend(),b1.begin());
200 std::copy(a2.cbegin()+1,a2.cend(),b2.begin());
201 for (
size_t i = 0; i < N-1;++i){
214 template<
size_t l,
size_t d1,
size_t d2>
216 template<
typename Derived>
228 template<
size_t d1,
size_t d2>
230 template<
typename Derived>
231 static Eigen::Matrix<double,1,1>
compute(Eigen::MatrixBase<Derived>
const & A) {
232 return Eigen::Matrix<double,1,1>{1.};
236 template<
size_t d1,
size_t d2>
238 template<
typename Derived>
239 static Eigen::Matrix<double,d1,d2>
compute(Eigen::MatrixBase<Derived>
const & A) {
240 return A.transpose();
246 template<
typename Derived>
247 static Eigen::Matrix<double,1,1>
compute(Eigen::MatrixBase<Derived>
const & A) {
248 return Eigen::Matrix<double,1,1>{A.determinant()};
254 template<
typename Derived>
255 static Eigen::Matrix<double,1,1>
compute(Eigen::MatrixBase<Derived>
const & A) {
256 return Eigen::Matrix<double,1,1>{A(0,0)};
262 template<
typename Derived>
263 static Eigen::Matrix<double,1,3>
compute(Eigen::MatrixBase<Derived>
const & A) {
264 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)}};
269 template<
typename Derived>
270 static Eigen::Matrix<double,3,1>
compute(Eigen::MatrixBase<Derived>
const & A) {
271 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)};
276 template<
typename Derived>
277 static Eigen::Matrix<double,3,3>
compute(Eigen::MatrixBase<Derived>
const & A) {
278 return Eigen::Matrix<double,3,3>{
279 {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)},
280 {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)},
281 {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)}
294 static std::vector<std::array<size_t, d>>
const &
homogeneous(
const int r) {
295 assert(r <= _init_deg &&
"Error: Monomial_powers must be initialized first");
299 static std::vector<std::array<size_t,d>>
const &
complete(
const int r) {
300 assert(r <= _init_deg &&
"Error: Monomial_powers must be initialized first");
301 return _powers_full[r];
304 static void init(
const int r) {
305 static_assert(d > 0,
"Error: Tried to construct a monomial basis in dimension 0");
306 assert(r <= _max_deg &&
"Maximum degree reached, increase _max_deg if needed");
308 for (
int h_r = _init_deg + 1; h_r <= r; ++h_r) {
309 std::vector<std::array<size_t,d>> powers;
310 std::array<size_t,d> current;
311 inner_loop(0,h_r,current,powers);
312 _powers[h_r] = powers;
314 _powers_full[0] = powers;
316 _powers_full[h_r] = _powers_full[h_r-1];
317 for (
size_t j = 0; j < powers.size(); ++j) {
318 _powers_full[h_r].emplace_back(powers[j]);
327 static constexpr int _max_deg = 20;
328 static inline int _init_deg = -1;
329 static inline std::array<std::vector<std::array<size_t,d>>,_max_deg+1> _powers;
330 static inline std::array<std::vector<std::array<size_t,d>>,_max_deg+1> _powers_full;
332 static void inner_loop(
size_t cindex,
int max, std::array<size_t,d> & current, std::vector<std::array<size_t,d>> & powers) {
334 current[cindex] = max;
335 powers.emplace_back(current);
337 for(
int i = 0; i <= max; ++i) {
339 inner_loop(cindex+1,max-i,current,powers);
346 template<
size_t d,
size_t index>
348 static Eigen::MatrixXd
get (
const int r) {
349 static_assert(index < d,
"Error: Tried to take the koszul operator on a direction outside the dimension");
353 current.at(index) += 1;
363 template<
size_t d,
size_t index>
365 static Eigen::MatrixXd
get (
const int r) {
366 static_assert(index < d,
"Error: Tried to take the differential operator on a direction outside the dimension");
367 assert(r > 0 &&
"Error: Cannot generate a matrix for the differential on P_0");
371 size_t cval = current.at(index);
372 if (cval == 0)
continue;
373 current.at(index) -= 1;
389 template<
size_t l,
size_t d>
391 static Eigen::MatrixXd
get (
const int r) {
392 if constexpr (l==0 || l > d) {
393 return Eigen::MatrixXd(0,0);
399 init_loop_for<0>(r,scalar_part,M);
405 template<
size_t i,
typename T>
static void init_loop_for(
int r, T & scalar_part,T & M) {
406 if constexpr(i < d) {
407 scalar_part.setZero();
410 for (
int s = 0; s <= r; ++s) {
418 init_loop_for<i+1>(r,scalar_part,M);
424 template<
size_t l,
size_t d>
426 static Eigen::MatrixXd
get (
const int r) {
428 return Eigen::MatrixXd(0,0);
434 init_loop_for<0>(r,scalar_part,M);
446 template<
size_t i,
typename T>
static void init_loop_for(
int r,T &scalar_part,T &M) {
447 if constexpr (i < d) {
448 scalar_part.setZero();
451 for (
int s = 0; s < r; ++s) {
459 init_loop_for<i+1>(r,scalar_part,M);
469 init_loop_for<0,1>(r+1);
473 template<
size_t l,
size_t k>
static void init_loop_for(
int r) {
474 if constexpr(k <= d) {
475 if constexpr(l < k) {
477 init_loop_for<l+1,k>(r);
480 init_loop_for<0,k+1>(r);
Definition exterior.hpp:158
Eigen::Matrix< double, Dimension::ExtDim(l+1, d), Dimension::ExtDim(l, d)> ExtAlgMatType
Definition exterior.hpp:160
static const ExtAlgMatType & get_transform(size_t i)
Definition exterior.hpp:162
static void init() noexcept
Definition exterior.hpp:166
Class to handle the exterior algebra basis.
Definition exterior.hpp:47
static const std::array< size_t, l > & expand_basis(size_t i)
Definition exterior.hpp:65
static const size_t index_from_tuple(const std::array< size_t, l > &tuple)
Definition exterior.hpp:71
static void init() noexcept
Definition exterior.hpp:49
Compute the action of Kozsul and Diff on the exterior algebra.
Definition exterior.hpp:108
static void init() noexcept
Definition exterior.hpp:116
Eigen::Matrix< double, Dimension::ExtDim(l-1, d), Dimension::ExtDim(l, d)> ExtAlgMatType
Definition exterior.hpp:110
static const ExtAlgMatType & get_transform(size_t i)
Definition exterior.hpp:112
constexpr size_t ExtDim(size_t l, size_t d) noexcept
Dimension of the exterior algebra.
Definition exterior_dimension.hpp:19
constexpr size_t PolyDim(int r, size_t d) noexcept
Dimension of P^r(\Real^d)
Definition exterior_dimension.hpp:25
constexpr size_t PLDim(int r, size_t l, size_t d) noexcept
Dimension of $P_r\Lambda^l(R^d)$.
Definition exterior_dimension.hpp:37
constexpr size_t HDim(int r, size_t d) noexcept
Dimension of homogeneous polynomials.
Definition exterior_dimension.hpp:31
Definition exterior.hpp:24
double Compute_partial_det(const V &a1, const V &a2, const Eigen::MatrixBase< Derived > &A)
Generic determinant computation.
Definition exterior.hpp:189
static Eigen::Matrix< double, 1, 1 > compute(Eigen::MatrixBase< Derived > const &A)
Definition exterior.hpp:231
static Eigen::Matrix< double, 1, 1 > compute(Eigen::MatrixBase< Derived > const &A)
Definition exterior.hpp:255
static Eigen::Matrix< double, d1, d2 > compute(Eigen::MatrixBase< Derived > const &A)
Definition exterior.hpp:239
static Eigen::Matrix< double, 1, 3 > compute(Eigen::MatrixBase< Derived > const &A)
Definition exterior.hpp:263
static Eigen::Matrix< double, 3, 1 > compute(Eigen::MatrixBase< Derived > const &A)
Definition exterior.hpp:270
static Eigen::Matrix< double, 3, 3 > compute(Eigen::MatrixBase< Derived > const &A)
Definition exterior.hpp:277
static Eigen::Matrix< double, 1, 1 > compute(Eigen::MatrixBase< Derived > const &A)
Definition exterior.hpp:247
Definition exterior.hpp:215
static Eigen::Matrix< double, Dimension::ExtDim(l, d1), Dimension::ExtDim(l, d2)> compute(Eigen::MatrixBase< Derived > const &A)
Definition exterior.hpp:217
Differential operator from $P_r\Lambda^l(R^d)$ to $P_{r-1}\Lambda^{l+1}(R^d)$.
Definition exterior.hpp:425
static Eigen::MatrixXd get_as_degr(const int r)
Definition exterior.hpp:439
static Eigen::MatrixXd get(const int r)
Definition exterior.hpp:426
Generate the matrices for the Differential operator on homogeneous monomial.
Definition exterior.hpp:364
static Eigen::MatrixXd get(const int r)
Definition exterior.hpp:365
Initialize every class related to the polynomial degree r.
Definition exterior.hpp:466
static void init(int r)
Definition exterior.hpp:467
Koszul operator from $P_r\Lambda^l(R^d)$ to $P_{r+1}\Lambda^{l-1}(R^d)$.
Definition exterior.hpp:390
static Eigen::MatrixXd get(const int r)
Definition exterior.hpp:391
Generate the matrices for the Koszul operator on homogeneous monomial.
Definition exterior.hpp:347
static Eigen::MatrixXd get(const int r)
Definition exterior.hpp:348
Generate a basis of monomial powers of degree r.
Definition exterior.hpp:293
static std::vector< std::array< size_t, d > > const & complete(const int r)
Definition exterior.hpp:299
static void init(const int r)
Definition exterior.hpp:304
static std::vector< std::array< size_t, d > > const & homogeneous(const int r)
Definition exterior.hpp:294