22#ifdef MAIA_GCC_COMPILER
23#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-Wduplicated-branches"
25#pragma GCC diagnostic ignored "-Wfloat-equal"
26#pragma GCC diagnostic ignored "-Wuseless-cast"
27#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
28#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
29#pragma GCC diagnostic ignored "-Wunused-result"
30#pragma GCC diagnostic ignored "-Wnull-dereference"
32#ifdef MAIA_CLANG_COMPILER
33#pragma clang diagnostic push
34#pragma clang diagnostic ignored "-Wc99-extensions"
35#pragma clang diagnostic ignored "-Wextra-semi-stmt"
36#pragma clang diagnostic ignored "-Wfloat-equal"
38#include <Eigen/Eigen/Eigen>
39#ifdef MAIA_GCC_COMPILER
40#pragma GCC diagnostic pop
42#ifdef MAIA_CLANG_COMPILER
43#pragma clang diagnostic pop
65template <
typename T, std::
size_t N>
67 Eigen::Matrix<T, N, N> m;
68 for(std::size_t i = 0; i < N; ++i) {
69 m.row(i) = Eigen::VectorXd::Map(&data[i][0], N);
81template <
typename T, std::
size_t N>
82void adjointRow(std::array<std::array<T, N>, N>& m, std::array<T, N>& A,
const MInt r) {
84 Eigen::Matrix<T, N, N> adjMatrix(m2.adjoint());
85 for(std::size_t i = 0; i < N; i++) {
86 A[i] = adjMatrix.row(r)[i];
98 A[0] = m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] + m[1][3] * m[2][1] * m[3][2]
99 - m[1][3] * m[2][2] * m[3][1] - m[1][2] * m[2][1] * m[3][3] - m[1][1] * m[2][3] * m[3][2];
100 A[1] = -m[0][1] * m[2][2] * m[3][3] - m[0][2] * m[2][3] * m[3][1] - m[0][3] * m[2][1] * m[3][2]
101 + m[0][3] * m[2][2] * m[3][1] + m[0][2] * m[2][1] * m[3][3] + m[0][1] * m[2][3] * m[3][2];
102 A[2] = m[0][1] * m[1][2] * m[3][3] + m[0][2] * m[1][3] * m[3][1] + m[0][3] * m[1][1] * m[3][2]
103 - m[0][3] * m[1][2] * m[3][1] - m[0][2] * m[1][1] * m[3][3] - m[0][1] * m[1][3] * m[3][2];
104 A[3] = -m[0][1] * m[1][2] * m[2][3] - m[0][2] * m[1][3] * m[2][1] - m[0][3] * m[1][1] * m[2][2]
105 + m[0][3] * m[1][2] * m[2][1] + m[0][2] * m[1][1] * m[2][3] + m[0][1] * m[1][3] * m[2][2];
113template <
typename T, std::
size_t N>
114void adjoint1stRow(std::array<std::array<T, N>, N>& m, std::array<T, N>& A) {
115 if constexpr(N == 4) {
129template <
typename T, std::
size_t N>
131 constexpr MInt dim = N == 2 ? 1 : 2;
132 Eigen::Matrix<T, dim, dim> matrix(m.data());
133 return matrix.determinant();
144template <
typename T, std::
size_t N>
146 Eigen::Matrix<T, N, N> matrix(&m[0][0]);
147 return matrix.determinant();
172 Eigen::Map<Eigen::MatrixXd> mA(A, m, n);
190 if(n == 0 || m == 0) {
191 std::cerr <<
globalDomainId() <<
" Warning: empty eq. sys. (" << m <<
"x" << n <<
"), skip." << std::endl;
194 Eigen::Matrix<MFloat, Eigen::Dynamic, Eigen::Dynamic> B(m, n);
195 Eigen::Matrix<MFloat, Eigen::Dynamic, Eigen::Dynamic> inv(n, m);
196 for(
MInt i = 0; i < m; i++) {
197 for(
MInt j = 0; j < n; j++) {
203 Eigen::CompleteOrthogonalDecomposition<Eigen::MatrixXd> orth(B);
204 inv = orth.pseudoInverse();
210 for(
MInt i = 0; i < m; i++) {
211 for(
MInt j = 0; j < n; j++) {
212 AInv(i, j) = inv(i, j);
236 if(n == 0 || m == 0) {
237 std::cerr <<
globalDomainId() <<
" Warning: empty eq. sys. (" << m <<
"x" << n <<
"), skip." << std::endl;
240 Eigen::Matrix<MFloat, Eigen::Dynamic, Eigen::Dynamic> B(m, n);
241 Eigen::Matrix<MFloat, Eigen::Dynamic, Eigen::Dynamic> inv(n, m);
242 for(
MInt i = 0; i < m; i++) {
243 for(
MInt j = 0; j < n; j++) {
244 B(i, j) = weights[i] * A(i, j);
249 Eigen::CompleteOrthogonalDecomposition<Eigen::MatrixXd> orth(B);
250 inv = orth.pseudoInverse();
254 for(
MInt k = 0; k < n; ++k) {
255 for(
MInt i = 0; i < m; ++i) {
256 AInv(k, i) = inv(k, i) * weights(i);
281 if(n == 0 || m == 0) {
282 std::cerr <<
globalDomainId() <<
" Warning: empty eq. sys. (" << m <<
"x" << n <<
"), skip." << std::endl;
285 Eigen::Matrix<MFloat, Eigen::Dynamic, Eigen::Dynamic> B(m, n);
286 Eigen::Matrix<MFloat, Eigen::Dynamic, Eigen::Dynamic> inv(n, m);
287 for(
MInt i = 0; i < m; i++) {
288 for(
MInt j = 0; j < n; j++) {
289 B(i, j) = weights[i] * A(i, j);
293 Eigen::CompleteOrthogonalDecomposition<Eigen::MatrixXd> orth(B);
294 inv = orth.pseudoInverse();
295 const MInt rank = orth.rank();
297 for(
MInt k = 0; k < n; ++k) {
298 for(
MInt i = 0; i < m; ++i) {
299 AInv(k, i) = inv(k, i) * weights(i);
316 std::vector<MTriplet> coefficients;
317 Eigen::Map<MFloatVectorXd> B(
b, m);
318 Eigen::Map<MFloatVectorXd> X(x, m);
320 coefficients.reserve(n);
321 for(
MInt i = 0; i < n; i++) {
322 coefficients.emplace_back(
MTriplet(pos[i][0], pos[i][1], A_coeff[i]));
326 Eigen::SparseMatrix<MFloat, Eigen::ColMajor> A(m, m);
327 A.setFromTriplets(coefficients.begin(), coefficients.end());
329 Eigen::SparseLU<Eigen::SparseMatrix<MFloat, Eigen::ColMajor>, Eigen::COLAMDOrdering<MInt>> slu;
333 MBool a_solution_exists = (A * X).isApprox(B, 1e-10);
335 MFloat resultA = F1B2 * X.transpose() * A * X;
336 MFloat resultB = X.transpose() * B;
338 MFloat result = resultA - resultB;
340 std::cout <<
"Energie norm is " << resultA <<
" " << resultB <<
" " << result << std::endl;
342 if(a_solution_exists) {
343 std::cerr <<
"SOLUTION IS CORRECT" << std::endl;
345 std::cerr <<
"SOLUTION IS NOT CORRECT" << std::endl;
358 std::vector<MTriplet> coefficients;
359 Eigen::Map<MFloatVectorXd> B(
b, m);
360 Eigen::Map<MFloatVectorXd> X(x, m);
362 coefficients.reserve(n);
363 for(
MInt i = 0; i < n; i++) {
364 coefficients.emplace_back(
MTriplet(pos[i][0], pos[i][1], A_coeff[i]));
368 Eigen::SparseMatrix<MFloat, Eigen::ColMajor> A(m, m);
369 A.setFromTriplets(coefficients.begin(), coefficients.end());
371 Eigen::BiCGSTAB<Eigen::SparseMatrix<MFloat, Eigen::ColMajor>> BCGST;
376 MBool a_solution_exists = (A * X).isApprox(B, 1e-10);
378 MFloat resultA = F1B2 * X.transpose() * A * X;
379 MFloat resultB = X.transpose() * B;
381 MFloat result = resultA - resultB;
383 std::cout <<
"Energie norm is " << resultA <<
" " << resultB <<
" " << result << std::endl;
385 if(a_solution_exists) {
386 std::cout <<
"SOLUTION IS CORRECT" << std::endl;
388 std::cout <<
"SOLUTION IS NOT CORRECT" << std::endl;
401 Eigen::Map<MFloatVectorXd> B(
b, m);
402 Eigen::Map<MFloatVectorXd> X(x, m);
406 for(
MInt i = 0; i < n; i++) {
407 A(pos[i][0], pos[i][1]) = A_coeff[i];
410 Eigen::FullPivLU<MFloatMatrixXd> lu;
414 MBool a_solution_exists = (A * X).isApprox(B, 1e-10);
416 if(a_solution_exists) {
417 std::cout <<
"SOLUTION IS CORRECT" << std::endl;
419 std::cout <<
"SOLUTION IS NOT CORRECT" << std::endl;
432 Eigen::Map<MFloatVectorXd> B(
b, m);
433 Eigen::Map<MFloatVectorXd> X(x, m);
437 for(
MInt i = 0; i < n; i++) {
438 A(pos[i][0], pos[i][1]) = A_coeff[i];
449void solveQR(std::array<std::array<MFloat, nDim>, nDim>& A_, std::array<MFloat, nDim>& b_) {
452 Eigen::Matrix<MFloat, nDim, nDim> A(&A_[0][0]);
453 Eigen::Vector<MFloat, nDim>
b(&b_[0]);
454 b = A.colPivHouseholderQr().solve(
b);
455 std::memcpy(&b_[0],
b.data(), nDim *
sizeof(
MFloat));
457template void solveQR<2>(std::array<std::array<MFloat, 2>, 2>&, std::array<MFloat, 2>&);
458template void solveQR<3>(std::array<std::array<MFloat, 3>, 3>&, std::array<MFloat, 3>&);
476 Eigen::Map<Eigen::Matrix<MFloat, 3, 3>> mA(&A[0][0]);
477 Eigen::Map<Eigen::Matrix<MFloat, 3, 1>> _w(w);
480 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<MFloat, 3, 3>> es(mA, Eigen::EigenvaluesOnly);
481 _w = es.eigenvalues().real();
490 Eigen::Map<Eigen::MatrixXd> A(&A_in[0][0], m, m);
491 Eigen::Map<Eigen::VectorXd> lambda(lambda_in, m);
494 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(A, Eigen::EigenvaluesOnly);
495 lambda = es.eigenvalues().real();
504 Eigen::Map<Eigen::Matrix<MFloat, 3, 3>> mA(&A[0][0]);
505 Eigen::Map<Eigen::Matrix<MFloat, 3, 3>> mQ(&Q[0][0]);
506 Eigen::Map<Eigen::Matrix<MFloat, 3, 1>> _w(w);
509 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<MFloat, 3, 3>> es(mA);
510 mQ = es.eigenvectors().real();
511 _w = es.eigenvalues().real();
515 Eigen::Map<Eigen::Matrix<MFloat, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> A_eigen(A, m, n);
517 Eigen::Map<MFloatVectorXd> b_eigen(
b, m);
521 Eigen::BDCSVD<Eigen::Matrix<MFloat, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> SVD =
522 A_eigen.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV);
524 Eigen::BDCSVD<Eigen::Matrix<MFloat, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>,
525 Eigen::ComputeThinU | Eigen::ComputeThinV>
526 SVD = A_eigen.bdcSvd<Eigen::ComputeThinU | Eigen::ComputeThinV>();
535 for(
MInt i = 0; i < n; i++) {
539 std::vector<MFloat> singularValues(S.size());
540 for(
MInt i = 0; i < S.size(); i++) {
541 singularValues[i] = S[i];
543 return singularValues;
This class is a ScratchSpace.
Provides a lightweight and fast class for accessing 1D arrays as multi-dimensional tensors (up to 4D)...
MInt globalDomainId()
Return global domain id.
Eigen::Vector< MFloat, Eigen::Dynamic > MFloatVectorXd
Eigen::Vector< MFloat, 2 > MFloatVector2d
void adjoint1stRow(std::array< std::array< T, N >, N > &m, std::array< T, N > &A)
std::vector< MFloat > svd(MFloat *const A, MFloat *const b, const MInt m, const MInt n, MFloat *const x)
Eigen::Matrix< MFloat, nDim, nDim > MFloatMatrix
MFloat determinant(std::array< T, N > &m)
void multiplySparseMatrixVector(MFloat *A_coeff, MInt **pos, const MInt n, const MInt m, MFloat *b, MFloat *x)
Eigen::Matrix< MFloat, Eigen::Dynamic, Eigen::Dynamic > MFloatMatrixXd
Eigen::Vector< MFloat, nDim > MFloatVector
void adjoint1stRow4x4(std::array< std::array< T, 4 >, 4 > &m, std::array< T, 4 > &A)
template MFloat determinant< MFloat, 3ul >(std::array< MFloat, 3ul > &)
Eigen::Matrix< MFloat, 2, 2 > MFloatMatrix2d
all assume dense matrix calculations
void invert(MFloat *A, const MInt m, const MInt n)
void solveQR(std::array< std::array< MFloat, nDim >, nDim > &A_, std::array< MFloat, nDim > &b_)
Eigen::Triplet< MFloat > MTriplet
template MFloat determinant< MFloat, 2ul >(std::array< MFloat, 2ul > &)
template void solveQR< 2 >(std::array< std::array< MFloat, 2 >, 2 > &, std::array< MFloat, 2 > &)
template void adjoint1stRow4x4< MFloat >(std::array< std::array< MFloat, 4 >, 4 > &m, std::array< MFloat, 4 > &A)
Eigen::Matrix< MFloat, 3, 3 > MFloatMatrix3d
void calcEigenVectors(MFloat A[3][3], MFloat Q[3][3], MFloat w[3])
template MFloat determinant< MFloat, 4ul >(std::array< MFloat, 4ul > &)
void solveSparseMatrix(MFloat *A_coeff, MInt **pos, const MInt n, const MInt m, MFloat *b, MFloat *x)
void solveSparseMatrixIterative(MFloat *A_coeff, MInt **pos, const MInt n, const MInt m, MFloat *b, MFloat *x)
template void adjointRow< MFloat, 3 >(std::array< std::array< MFloat, 3 >, 3 > &m, std::array< MFloat, 3 > &A, const MInt)
template void solveQR< 3 >(std::array< std::array< MFloat, 3 >, 3 > &, std::array< MFloat, 3 > &)
void calcEigenValues(MFloat A[3][3], MFloat w[3])
template void adjoint1stRow< MFloat, 3 >(std::array< std::array< MFloat, 3 >, 3 > &m, std::array< MFloat, 3 > &A)
void adjointRow(std::array< std::array< T, N >, N > &m, std::array< T, N > &A, const MInt r)
Eigen::Vector< MFloat, 3 > MFloatVector3d
void solveDenseMatrix(MFloat *A_coeff, MInt **pos, const MInt n, const MInt m, MFloat *b, MFloat *x)
template void adjoint1stRow< MFloat, 4 >(std::array< std::array< MFloat, 4 >, 4 > &m, std::array< MFloat, 4 > &A)
Eigen::MatrixXd ConvertToEigenMatrix(std::array< std::array< T, N >, N > data)
convert array to eigen matrix
MInt invertR(T &A, T &weights, T &AInv, const MInt m, const MInt n)
Namespace for auxiliary functions/classes.