NESSi  v1.0.2
The NonEquilibrium Systems Simulation Library
linalg_eigen.cpp
Go to the documentation of this file.
1 // interface to simple linear algebra routines:
3 // implementation using EIGEN library, ans a lot of copying back and forth
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include "eigen_typedef.h"
9 
10 namespace linalg {
11 
12 // Consider using Eigen:Map instead of doing copying back and forth
13 
14 void set_cdmatrix(int n,void *a,cdmatrix &A){
15  cdouble *aa=(cdouble*)a;
16  A=Eigen::Map<cdmatrix>(aa,n,n).transpose();
17 }
18 void set_dmatrix(int n,void *a,dmatrix &A){
19  double *aa=(double*)a;
20  A=Eigen::Map<dmatrix>(aa,n,n).transpose();
21 }
22 void set_cdvector(int n,void *a,cdvector &A){
23  cdouble *aa=(cdouble*)a;
24  A=Eigen::Map<cdvector>(aa,n);
25 }
26 
27 void set_dvector(int n,void *a,dvector &A){
28  double *aa=(double*)a;
29  A=Eigen::Map<dvector>(aa,n);
30 }
31 
32 void get_cdvector(int n,void *a,cdvector &A){
33  int i;
34  cdouble *aa=(cdouble*)a;
35  for(i=0;i<n;i++) aa[i]=A(i);
36 }
37 void get_dvector(int n,void *a,dvector &A){
38  int i;
39  double *aa=(double*)a;
40  for(i=0;i<n;i++) aa[i]=A(i);
41 }
42 void get_cdmatrix(int n,void *a,cdmatrix &A){
43  int i,j;
44  cdouble *aa=(cdouble*)a;
45  for(i=0;i<n;i++) for(j=0;j<n;j++) aa[i*n+j]=A(i,j);
46 }
47 void get_dmatrix(int n,void *a, const dmatrix &A){
48  int i,j;
49  double *aa=(double*)a;
50  for(i=0;i<n;i++) for(j=0;j<n;j++) aa[i*n+j]=A(i,j);
51 }
52 
53 //old loop style
54 
55 //void set_cdmatrix(int n,void *a,cdmatrix &A){
56 // int i,j;
57 // cdouble *aa=(cdouble*)a;
58 // A.resize(n,n);
59 // for(i=0;i<n;i++) for(j=0;j<n;j++) A(i,j)=aa[i*n+j];
60 //}
61 //void set_dmatrix(int n,void *a,dmatrix &A){
62 // int i,j;
63 // double *aa=(double*)a;
64 // A.resize(n,n);
65 // for(i=0;i<n;i++) for(j=0;j<n;j++) A(i,j)=aa[i*n+j];
66 //}
67 //void set_cdvector(int n,void *a,cdvector &A){
68 // int i;
69 // cdouble *aa=(cdouble*)a;
70 // A.resize(n);
71 // for(i=0;i<n;i++) A(i)=aa[i];
72 //}
73 //void set_dvector(int n,void *a,dvector &A){
74 // int i;
75 // double *aa=(double*)a;
76 // A.resize(n);
77 // for(i=0;i<n;i++) A(i)=aa[i];
78 //}
79 
80 void cplx_sq_solve(void *a,void *b,void *x,int n)
81 {
82  cdmatrix A_eigen;
83  cdvector b_eigen,X_eigen;
84  set_cdmatrix(n,a,A_eigen);
85  set_cdvector(n,b,b_eigen);
86  Eigen::FullPivLU<cdmatrix> lu(A_eigen);
87  X_eigen=lu.solve(b_eigen);
88  get_cdvector(n,x,X_eigen);
89 }
90 // solve d mXm problems, n=m*d
91 void cplx_sq_solve_many(void *a,void *b,void *x,int n,int d)
92 {
93  int l;
94  cdouble *b1=(cdouble*)b;
95  cdouble *x1=(cdouble*)x;
96  cdmatrix A_eigen;
97  cdvector b_eigen,X_eigen;
98  set_cdmatrix(n,a,A_eigen);
99  Eigen::FullPivLU<cdmatrix> lu(A_eigen);
100  for(l=0;l<d;l++){
101  set_cdvector(n,b1+n*l,b_eigen);
102  X_eigen=lu.solve(b_eigen);
103  get_cdvector(n,x1+n*l,X_eigen);
104  }
105 }
106 void real_sq_solve(double *a,double *b,double *x,int n)
107 {
108  dmatrix A_eigen;
109  dvector b_eigen,X_eigen;
110  set_dmatrix(n,a,A_eigen);
111  set_dvector(n,b,b_eigen);
112  Eigen::FullPivLU<dmatrix> lu(A_eigen);
113  X_eigen=lu.solve(b_eigen);
114  get_dvector(n,x,X_eigen);
115 }
116 void cplx_matrix_inverse(void *a,void *x,int n)
117 {
118  cdmatrix A_eigen;
119  cdmatrix X_eigen;
120  set_cdmatrix(n,a,A_eigen);
121  Eigen::FullPivLU<cdmatrix> lu(A_eigen);
122  X_eigen=lu.inverse();
123  get_cdmatrix(n,x,X_eigen);
124 }
125 void linalg_matrix_inverse(double *a,double *x,int n)
126 {
127  dmatrix A_eigen;
128  dmatrix X_eigen;
129  set_dmatrix(n,a,A_eigen);
130  Eigen::FullPivLU<dmatrix> lu(A_eigen);
131  X_eigen=lu.inverse();
132  get_dmatrix(n,x,X_eigen);
133 }
134 void eigen_hermv(int n,std::complex<double> *A,double *eval,std::complex<double> *evec){
135  cdmatrix A_eigen;
136  cdmatrix evec_eigen;
137  dvector eval_eigen;
138  set_cdmatrix(n,A,A_eigen);
139  Eigen::SelfAdjointEigenSolver<cdmatrix> eigensolver(A_eigen);
140  eval_eigen=eigensolver.eigenvalues();
141  evec_eigen=eigensolver.eigenvectors();
142  get_cdmatrix(n,evec,evec_eigen);
143  get_dvector(n,eval,eval_eigen);
144 }
145 
146 //void QR_decomposition(double *aa,double *qq,double *rr,int n,int m) {
147 //
148 // assert( n == m );
149 //
150 // dmatrix mat_aa;
151 // set_dmatrix(n, aa, mat_aa);
152 // Eigen::ColPivHouseholderQR<dmatrix> qr(mat_aa);
153 //
154 // dmatrix mat_r = qr.matrixQR().triangularView<Eigen::Upper>();
155 // dmatrix mat_q = qr.householderQ();
156 //
157 // get_dmatrix(n, qq, mat_q);
158 // get_dmatrix(n, rr, mat_r);
159 //
160 //}
161 
162 } // end namespace linalg
void get_dvector(int n, void *a, dvector &A)
void cplx_matrix_inverse(void *a, void *x, int n)
Evaluate the inverse matrix of a complex matrix .
void cplx_sq_solve(void *a, void *b, void *x, int dim)
Solve a linear equation ax=b.
void eigen_hermv(int size, std::complex< double > *A, double *eval, std::complex< double > *evec)
Evaluate the eigen set of a given Hermitian matrix .
std::complex< double > cdouble
void set_cdmatrix(int n, void *a, cdmatrix &A)
void set_dmatrix(int n, void *a, dmatrix &A)
void set_dvector(int n, void *a, dvector &A)
void linalg_matrix_inverse(double *a, double *x, int n)
Evaluate the inverse matrix of a real matrix .
void real_sq_solve(double *ad, double *bd, double *xd, int dim)
Solve a linear equation ax=b.
void set_cdvector(int n, void *a, cdvector &A)
void get_cdvector(int n, void *a, cdvector &A)
void get_dmatrix(int n, void *a, const dmatrix &A)
void cplx_sq_solve_many(void *a, void *b, void *x, int dim, int d)
Solve a linear equation .
void get_cdmatrix(int n, void *a, cdmatrix &A)