KIDS  ver-0.0.1
KIDS : Kernel Integrated Dynamics Simulator
Loading...
Searching...
No Matches
linalg_1.cpp
Go to the documentation of this file.
1#include <cmath>
2#include <complex>
3
4#define EIGEN_NO_STATIC_ASSERT
5
6#include "Eigen/Dense"
7#include "Eigen/QR"
8#include "kids/Types.h"
9#include "kids/linalg.h"
10
11#define EigMajor Eigen::RowMajor
12
13namespace PROJECT_NS {
14
15template <class T>
16using EigVX = Eigen::Matrix<T, Eigen::Dynamic, 1, EigMajor>;
17
18template <class T>
19using EigMX = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, EigMajor>;
20
21template <class T>
22using EigAX = Eigen::Array<T, Eigen::Dynamic, Eigen::Dynamic, EigMajor>;
23
30using MapVXr = Eigen::Map<EigVXr>;
31using MapVXc = Eigen::Map<EigVXc>;
32using MapMXr = Eigen::Map<EigMXr>;
33using MapMXc = Eigen::Map<EigMXc>;
34using MapAXr = Eigen::Map<EigAXr>;
35using MapAXc = Eigen::Map<EigAXc>;
36
37void LinearSolve(kids_real* x, kids_real* A, kids_real* b, size_t N) {
38 MapMXr Mapx(x, N, 1);
39 MapMXr MapA(A, N, N);
40 MapMXr Mapb(b, N, 1);
41 Mapx = MapA.householderQr().solve(Mapb);
42}
43
44void EigenSolve(kids_real* E, kids_real* T, kids_real* A, size_t N) {
45 MapMXr MapE(E, N, 1);
46 MapMXr MapT(T, N, N);
47 MapMXr MapA(A, N, N);
48 Eigen::SelfAdjointEigenSolver<EigMXr> eig(MapA);
49 MapE = eig.eigenvalues().real();
50 MapT = eig.eigenvectors().real();
51}
52
53void EigenSolve(kids_real* E, kids_complex* T, kids_complex* A, size_t N) {
54 MapMXr MapE(E, N, 1);
55 MapMXc MapT(T, N, N);
56 MapMXc MapA(A, N, N);
57 Eigen::SelfAdjointEigenSolver<EigMXc> eig(MapA);
58 MapE = eig.eigenvalues().real();
59 MapT = eig.eigenvectors();
60}
61
63 MapMXc MapE(E, N, 1);
64 MapMXc MapT(T, N, N);
65 MapMXc MapA(A, N, N);
66 Eigen::ComplexEigenSolver<EigMXc> eig(MapA);
67 MapE = eig.eigenvalues();
68 MapT = eig.eigenvectors();
69}
70
71void PseudoInverse(kids_real* A, kids_real* invA, size_t N, kids_real e) {
72 MapMXr MapA(A, N, N);
73 MapMXr MapInvA(invA, N, N);
74 MapInvA = MapA.completeOrthogonalDecomposition().pseudoInverse();
75 // Eigen::JacobiSVD<EigMXr> svd = MapA.jacobiSvd(Eigen::ComputeFullU|Eigen::ComputeFullV);
76 // EigMXr invS = EigMXr::Zero(N, N);
77 // for (int i = 0; i < N; ++i) {
78 // if (svd.singularValues()(i) > e || svd.singularValues()(i) < -e) {
79 // invS(i, i) = 1 / svd.singularValues()(i);
80 // }
81 // }
82 // MapInvA = svd.matrixV()*invS*svd.matrixU().transpose();
83}
84
85void ARRAY_INV_MAT(kids_real* invA, kids_real* A, size_t N) {
86 MapMXr Map_invA(invA, N, N);
87 MapMXr Map_A(A, N, N);
88 Map_invA = Map_A.lu().inverse();
89}
90
91void ARRAY_INV_MAT(kids_complex* invA, kids_complex* A, size_t N) {
92 MapMXc Map_invA(invA, N, N);
93 MapMXc Map_A(A, N, N);
94 Map_invA = Map_A.lu().inverse();
95}
96
98 // MapMXc Map_A(A, N, N);
99 // MapMXc Map_expkA(expkA, N, N);
100 // auto eigr = Eigen::ComplexEigenSolver<EigMXc>(Map_A);
101 // auto Er = eigr.eigenvalues();
102 // auto Vr = eigr.eigenvectors();
103 // auto eigl = Eigen::ComplexEigenSolver<EigMXc>(Map_A.adjoint());
104 // auto El = eigl.eigenvalues();
105 // auto Vl = eigl.eigenvectors();
106 // auto Slr = (Vl.adjoint() * Vr).diagonal();
107 // Map_expkA = Vr * ((k * Er.array()).exp() / Slr.array()).matrix().asDiagonal() * Vl.adjoint();
108
109 kids_complex* Vr_ptr = new kids_complex[N * N];
110 kids_complex* Vl_ptr = new kids_complex[N * N];
111 kids_complex* At_ptr = new kids_complex[N * N];
112 kids_complex* Slr_ptr = new kids_complex[N * N];
113 kids_complex* lamb_ptr = new kids_complex[N];
114
115 for (int i = 0; i < N * N; ++i) At_ptr[i] = A[i];
116 ARRAY_TRANSPOSE(At_ptr, N, N);
117 EigenSolve(lamb_ptr, Vl_ptr, At_ptr, N);
118 EigenSolve(lamb_ptr, Vr_ptr, A, N);
119 ARRAY_MATMUL_TRANS1(Slr_ptr, Vl_ptr, Vr_ptr, N, N, N);
120 for (int i = 0, ii = 0; i < N; ++i, ii += (N + 1)) { //
121 lamb_ptr[i] = std::exp(k * lamb_ptr[i]) / Slr_ptr[ii];
122 }
123 ARRAY_MATMUL3_TRANS2(expkA, Vr_ptr, lamb_ptr, Vl_ptr, N, N, 0, N);
124
125 delete[] Vr_ptr;
126 delete[] Vl_ptr;
127 delete[] At_ptr;
128 delete[] Slr_ptr;
129 delete[] lamb_ptr;
130}
131
132void ARRAY_CORRECT_U(kids_complex* U, size_t N) {
133 // MapMXc Map_U(U, N, N);
134 // auto eigr = Eigen::SelfAdjointEigenSolver<EigMXc>(-0.5e0 * kids_complex(0, 1) * (Map_U - Map_U.adjoint()));
135 // auto Er = eigr.eigenvalues().real();
136 // auto Vr = eigr.eigenvectors();
137 // Map_U = Vr * ((kids_complex(0, 1) * Er.array()).exp()).matrix().asDiagonal() * Vr.adjoint();
138
139 kids_complex* V_ptr = new kids_complex[N * N];
140 kids_complex* A_ptr = new kids_complex[N * N];
141 kids_real* lamb_ptr = new kids_real[N];
142 kids_complex* lamb2_ptr = new kids_complex[N];
143
144 for (int i = 0, ik = 0; i < N; ++i) {
145 for (int k = 0, ki = i; k < N; ++k, ++ik, ki += N) {
146 A_ptr[ik] = -0.5e0 * kids_complex(0, 1) * (U[ik] - std::conj(U[ki]));
147 }
148 }
149 EigenSolve(lamb_ptr, V_ptr, A_ptr, N);
150 for (int i = 0; i < N; ++i) lamb2_ptr[i] = std::exp(kids_complex(0, 1) * lamb_ptr[i]);
151 ARRAY_MATMUL3_TRANS2(U, V_ptr, lamb2_ptr, V_ptr, N, N, 0, N);
152 delete[] V_ptr;
153 delete[] A_ptr;
154 delete[] lamb_ptr;
155}
156
157}; // namespace PROJECT_NS
definition of types in the project and some utiles for types
#define ARRAY_MATMUL3_TRANS2(_A, _B, _C, _D, _n1, _n2, _n0, _n3)
#define ARRAY_MATMUL_TRANS1(_A, _B, _C, _n1, _n2, _n3)
Provide linalg APIs.
EigMX< kids_real > EigMXr
Definition linalg_tpl.h:55
EigMX< kids_complex > EigAXc
Definition linalg_tpl.h:58
Eigen::Map< EigMXr > MapMXr
Definition linalg_tpl.h:61
Eigen::Map< EigMXc > MapMXc
Definition linalg_tpl.h:62
Eigen::Map< EigAXr > MapAXr
Definition linalg_tpl.h:63
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, EigMajor > EigMX
Definition linalg_tpl.h:48
Eigen::Map< EigVXr > MapVXr
Definition linalg_tpl.h:59
EigMX< kids_real > EigAXr
Definition linalg_tpl.h:57
Eigen::Map< EigAXc > MapAXc
Definition linalg_tpl.h:64
EigVX< kids_complex > EigVXc
Definition linalg_tpl.h:54
Eigen::Matrix< T, Eigen::Dynamic, 1, EigMajor > EigVX
Definition linalg_tpl.h:45
Eigen::Array< T, Eigen::Dynamic, Eigen::Dynamic, EigMajor > EigAX
Definition linalg_tpl.h:51
EigVX< kids_real > EigVXr
Definition linalg_tpl.h:53
EigMX< kids_complex > EigMXc
Definition linalg_tpl.h:56
Eigen::Map< EigVXc > MapVXc
Definition linalg_tpl.h:60
< http://warp.povusers.org/FunctionParser/fparser.html
Definition Context.h:39
void PseudoInverse(kids_real *A, kids_real *invA, size_t N, kids_real e=1E-5)
Compute the pseudo-inverse of a matrix for real numbers.
Definition linalg_1.cpp:71
void ARRAY_CORRECT_U(kids_complex *U, size_t N)
Definition linalg_1.cpp:132
void ARRAY_INV_MAT(kids_complex *invA, kids_complex *A, size_t N)
Compute the inverse of a matrix for complex numbers.
Definition linalg_1.cpp:91
void ARRAY_TRANSPOSE(kids_real *A, size_t N1, size_t N2)
Definition linalg.cpp:500
double kids_real
Alias for real number type.
Definition Types.h:59
std::complex< double > kids_complex
Alias for complex number type.
Definition Types.h:60
Eigen::Map< EigMXc > MapMXc
Definition linalg.cpp:34
Eigen::Map< EigMXr > MapMXr
Definition linalg.cpp:33
void EigenSolve(kids_real *E, kids_real *T, kids_real *A, size_t N)
Solve the eigenvalue problem for real matrices.
Definition linalg_1.cpp:44
void ARRAY_EXP_MAT_GENERAL(kids_complex *expkA, kids_complex *A, kids_complex k, size_t N)
Definition linalg_1.cpp:97
void LinearSolve(kids_real *x, kids_real *A, kids_real *b, size_t N)
Solve a linear system Ax = b for real matrices.
Definition linalg_1.cpp:37