TBCI Numerical high perf. C++ Library 2.8.0
lapack_stdcplx.cpp
Go to the documentation of this file.
1
5/* $Id: lapack_stdcplx.cpp,v 1.1.2.15 2019/05/28 11:13:02 garloff Exp $ */
6
7//#define NO_NS
8
10#define LAPACK_INLINE inline
11
12#include "tbci/std_cplx.h"
13#include "tbci/f_matrix.h"
14#include "tbci/f_bandmatrix.h"
15#include "tbci/lapack/lapack_lib.h"
16
17
19
20//********************************************************************************
21// Solution of linear eqution systems, partial pivoting
22//********************************************************************************
26TVector<double> lu_solve(const F_Matrix<double>& A, const Vector<double>& B, int overwriteA);
27F_TMatrix<double> lu_solve(const F_Matrix<double>& A, const F_Matrix<double>& B, int overwriteA);
28
29F_TMatrix<double> inv(const F_Matrix<double>& A, int overwriteA);
30
31
33{
34 integer info = 0;
35 integer n=A.columns(); // Dimension des Problems
36 BVector<integer> ipiv(n);
38 if (!overwriteA)
39 {
40 temp.resize(n,n);
41 temp=A;
42 }
43 // Rechte Seite ist die Einheitsmatrix!
44 F_TMatrix<CPLX__ complex<double> > invA(0.0, n, n);
45 for (int i=0; i<n; i++)
46 invA.setval(CPLX__ complex<double>(1.0), i, i);
47
48 if (overwriteA)
49 zgesv_(&n, &n, (doublecomplex*) A.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
50 (doublecomplex*) invA.get_fortran_matrix(), &n, &info);
51 else
52 zgesv_(&n, &n, (doublecomplex*) temp.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
53 (doublecomplex*) invA.get_fortran_matrix(), &n, &info);
54 if (info)
55 STD__ cerr << "Error inverting Matrix A!" << STD__ endl;
56 return invA;
57}
58
60{
61 integer info = 0;
62 integer n=A.columns(); // Dimension des Problems
63 BVector<integer> ipiv(n);
65 if (!overwriteA)
66 {
67 temp.resize(n,n);
68 temp=A;
69 }
71
72 if (overwriteA)
73 zgesv_(&n, &n, (doublecomplex*) A.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
74 (doublecomplex*) invA.get_fortran_matrix(), &n, &info);
75 else
76 zgesv_(&n, &n, (doublecomplex*) temp.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
77 (doublecomplex*) invA.get_fortran_matrix(), &n, &info);
78 if (info)
79 STD__ cerr << "Error inverting Matrix A!" << STD__ endl;
80 return invA;
81}
82
83
84//********************************************************************************
85// eigenvalues (and eigenvectors) \a A*EV=EW*EV of symmetric double Matrix \a A
86//********************************************************************************
87int eig(const F_Matrix<double>& A, Vector<double>& EW);
88
90
91//symmtric Band Matrix
93
95 double ew_min, double ew_max);
96
97//********************************************************************************
99//********************************************************************************
101{
102 char jobvl='N'; //linke Eigenwerte und Eigenvektoren
103 char jobvr='N'; //rechte Eigenwerte und Eigenvektoren
104 integer N=A.columns(); // Dimension des Problems
105 doublecomplex* vl=0; // Keine linken Eigenvektoren
106 doublecomplex* vr=0; // Keine linken Eigenvektoren
107 integer lwork=2*N;
108 doublecomplex* work =NEW(doublecomplex,lwork);
109 doublereal* rwork=NEW(doublereal,lwork);
110 integer info = 0;
111 zgeev_(&jobvl, &jobvr, &N,
112 (doublecomplex*) A.get_fortran_matrix(), &N,
113 (doublecomplex*) EW.get_fortran_vector(), vl,
114 &N, vr, &N, work, &lwork, rwork, &info);
115 TBCIDELETE(doublecomplex, work, lwork);
116 TBCIDELETE(doublereal, rwork, lwork);
117 return (int) info;
118}
119
120
122{
123 char jobvl='N'; //linke Eigenwerte und Eigenvektoren
124 char jobvr='V'; //rechte Eigenwerte und Eigenvektoren
125 integer N=A.columns(); // Dimension des Problems
126 doublecomplex* vl=0; // Keine linken Eigenvektoren
127 integer lwork=2*N;
128 doublecomplex* work =NEW(doublecomplex,lwork);
129 doublereal* rwork=NEW(doublereal,lwork);
130 integer info = 0;
131 zgeev_(&jobvl, &jobvr, &N, (doublecomplex*) A.get_fortran_matrix(), &N,
132 (doublecomplex*) EW.get_fortran_vector(), vl,
133 &N, (doublecomplex*) EV.get_fortran_matrix(), &N, work, &lwork, rwork, &info);
134 TBCIDELETE(doublecomplex, work, lwork);
135 TBCIDELETE(doublereal, rwork, lwork);
136 return (int) info;
137}
138
139
140
141
142//********************************************************************************
144//********************************************************************************
147 double EW_min, double EW_max, Vector<double>& Eigenwerte,
148 F_Matrix<CPLX__ complex<double> >& Eigenvectoren)
149{
150 // Benutzt wird nur die obere Haelfte der Bandmatrix A!!!!
151 long uplo=1;
152 // Ordnung des EWP bestimmen
153 long n=A.columns();
154 // Anzahl der Oberen Diagonalen der Matrizen A und B bestimmen
155 long ldab=A.numSuper()+1;
156 long ldbb=B.numSuper()+1;
157 // Allg. Variablen
158 long Anzahl_Eigenwerte;
159 long BerechneEV=1; // Eigenvektoren sollen berechnet werden
160
161 // Laufvariablen
162 int i,j, x,y;
163
164
165 // *****************************************************************************
166 // Arrays im Fortran-Stil deklarieren,
167 // diese Arrays werden mit den Werten aus den Matrizen besetzt
168 //cout << "ab.bb..." << flush;
169 // *****************************************************************************
170 doublecomplex *ab = new doublecomplex[ldab*n];
171 doublecomplex *bb = new doublecomplex[ldbb*n];
172
173 // Arrays kopieren
174 for (i=0; i<n; i++)
175 {
176 // Array A nach ab kopieren
177 for (j=i; j<i+ldab && j<n; j++)
178 {
179 // x und y sind die Koordinaten in Lapack-Bandstruktur
180 x=ldab+i-j-1;
181 y=j;
182 ab[x+ldab*y].r = CPLX__ real(A(i,j));
183 ab[x+ldab*y].i = CPLX__ imag(A(i,j));
184 }
185
186 // Array B nach bb kopieren
187 for (j=i; j<i+ldbb && j<n; j++)
188 {
189 // x und y sind die Koordinaten in Lapack-Bandstruktur
190 x=ldbb+i-j-1;
191 y=j;
192 bb[x+ldbb*y].r = CPLX__ real(B(i,j));
193 bb[x+ldbb*y].i = CPLX__ imag(B(i,j));
194 }
195 }
196
197 // *******************************************************************************
198 // Hilfsvariablen fuer die Eigenwertroutine deklarieren
199
200 double* ew = new double[n]; // Temporaerer Eigenwertspeicher
201 long *iwork = new long[5*n];
202 double *rwork = new double[7*n];
203 doublecomplex *work = new doublecomplex[n];
204 doublecomplex *q = new doublecomplex[n*n];
205
206 // *******************************************************************************
207 // Eigenwertroutine aufrufen:
208 long info=own_ew_(&BerechneEV, &uplo, &n, &Anzahl_Eigenwerte, ab, &ldab, bb, &ldbb,
209 &EW_min, &EW_max, ew, q, &n, work, rwork, iwork);
210 if (!info==0)
211 {
212 STD__ cerr << " Error calculating eigenvalues: (status " << info << ")" << STD__ endl;
213 return info;
214 }
215 delete [] ab ;
216 delete [] bb ;
217 // Wenn Eigenvektoren berechnen
218 if (BerechneEV==1 && Anzahl_Eigenwerte>0)
219 {
220 // neue Hilfsvariablen initialisieren
221 doublecomplex *EV = new doublecomplex[n*Anzahl_Eigenwerte];
222 long *ifail = new long[Anzahl_Eigenwerte];
223 // Eigenvektoren zu 0 setzen
224 for (i=0;i<n*Anzahl_Eigenwerte;i++)
225 {
226 EV[i].r=0;
227 EV[i].i=0;
228 }
229 info=own_ev_(&n, &Anzahl_Eigenwerte, ew, EV, &n, q, &n, work, rwork, iwork, ifail);
230 if (!info==0)
231 {
232 STD__ cerr << " Error calculating eigenvectors" << STD__ endl;
233 return info;
234 }
235 // *******************************************************************************
236 // Eigenvektoren in die Matrix Eigenvektoren eintragen
237 Eigenvectoren.resize(n,Anzahl_Eigenwerte);
238 for (j=0;j<Anzahl_Eigenwerte;j++)
239 {
240 for (int i=0; i<n; i++)
241 {
242 Eigenvectoren(i,j) = CPLX__ complex<double> (EV[i+n*j].r, EV[i+n*j].i);
243 }
244 }
245 delete[] ifail;
246 delete[] EV;
247 } //endif Eigenvektorberechnung
248
249 // Eigenwerte in Eigenwertvektor eintragen
250 Eigenwerte.resize(Anzahl_Eigenwerte);
251 for(i=0; i<Anzahl_Eigenwerte; i++) Eigenwerte(i) = ew[i];
252
253 delete[] ew;
254 delete[] q;
255 delete[] iwork;
256 delete[] rwork;
257 delete[] work;
258 return 0;
259}
260
261
262
263// ***************************************************************************
265// ***************************************************************************
267{
268 char jobz='V'; // Eigenvektoren berechnen
269 char uplo='U'; // obere Haelfte der Matrix wird gespeichert
270 integer n=A.rows(); // Ordnung des EWP bestimmen
271
272 integer lwork =2*n-1;
273 doublecomplex *work = new doublecomplex[lwork];
274 double *rwork = new double[3*n-2];
275 integer info=0;
276
277 EVec=A;
278 zheev_(&jobz, &uplo, &n, (doublecomplex*) EVec.get_fortran_matrix(), &n,
279 EW.get_fortran_vector(), work, &lwork, rwork, &info);
280
281 if (!info==0)
282 {
283 STD__ cerr << " Error calculating eigenvalues: (status " << info << ")" << STD__ endl;
284 return info;
285 }
286
287 // Alle alten Arrays loeschen
288 delete[] work;
289 delete[] rwork;
290 return 0;
291}
292
293
295{
296 char jobz='N'; // Eigenvektoren berechnen
297 char uplo='U'; // obere Haelfte der Matrix wird gespeichert
298 integer n=A.rows(); // Ordnung des EWP bestimmen
299
300 integer lwork =2*n-1;
301 doublecomplex *work = new doublecomplex[lwork];
302 double *rwork = new double[3*n-2];
303 integer info=0;
304
305 zheev_(&jobz, &uplo, &n, (doublecomplex*) A.get_fortran_matrix(), &n,
306 EW.get_fortran_vector(), work, &lwork, rwork, &info);
307
308 if (!info==0)
309 {
310 STD__ cerr << " Error calculating eigenvalues: (status " << info << ")" << STD__ endl;
311 return info;
312 }
313
314 // Alle alten Arrays loeschen
315 delete[] work;
316 delete[] rwork;
317 return 0;
318}
319
320template class tbci_memalloc<doublecomplex>;
322
const Vector< T > const Vector< T > & x
Definition LM_fit.h:97
int i
Definition LM_fit.h:71
doublereal y
Definition TOMS_707.C:27
#define STD__
Definition basics.h:338
#define NAMESPACE_END
Definition basics.h:323
#define NAMESPACE_TBCI
Definition basics.h:317
provides basic Vector functionality but arithmetic operators (+=, - , *, /...).
Definition bvector.h:68
T *const & get_fortran_vector() const
Definition bvector.h:164
BVector< T > & resize(const BVector< T > &)
Actually it's a resize and copy (some people would expect the assignment op to do this).
Definition bvector.h:361
C++ class for banded matrices using band storage in a one-dimensional array.
T * get_fortran_matrix() const
Definition f_matrix.h:1209
F_Matrix< T > & resize(const unsigned r, const unsigned c)
Definition f_matrix.h:1234
Temporary Base Class (non referable!) (acc.
Definition f_matrix.h:71
T * get_fortran_matrix() const
Definition f_matrix.h:181
void setval(const T val, const unsigned int r, const unsigned int c)
Definition f_matrix.h:206
Temporary Base Class Idiom: Class TVector is used for temporary variables.
Definition vector.h:73
T imag(const TBCI__ cplx< T > &z)
Definition cplx.h:674
int zheev_(const char *jobz, const char *uplo, int *n, __complex__ double *a, int *lda, double *w, __complex__ double *work, int *lwork, double *rwork, int *info)
int zgeev_(const char *jobvl, const char *jobvr, int *n, __complex__ double *a, int *lda, __complex__ double *w, __complex__ double *vl, int *ldvl, __complex__ double *vr, int *ldvr, __complex__ double *work, int *lwork, double *rwork, int *info)
int zgesv_(int *n, int *nrhs, __complex__ double *a, int *lda, int *ipiv, __complex__ double *b, int *ldb, int *info)
NAMESPACE_TBCI TVector< double > lu_solve_expert(const F_BandMatrix< double > &A, const Vector< double > &B, int equi)
Solution of linear eqution systems, partial pivoting.
Definition lapack.cpp:24
F_TMatrix< double > inv(const F_Matrix< double > &A, int overwriteA)
Definition lapack.cpp:181
TVector< double > lu_solve(const F_BandMatrix< double > &A, const Vector< double > &B)
Definition lapack.cpp:74
int eig(const F_Matrix< double > &A, Vector< double > &EW)
eigenvalues (and eigenvectors) A*EV=EW*EV of symmetric double Matrix A
Definition lapack.cpp:263
#define TBCIDELETE(t, v, sz)
#define NEW(t, s)
#define complex
#define doublereal
#define integer
long int own_ev_(long int *n, long int *m, double *w, __complex__ double *z, long int *ldz, __complex__ double *q, long int *ldq, __complex__ double *work, double *rwork, long int *iwork, long int *ifail)
– AHLAND driver routine (version 2.0) –
#define real
long int own_ew_(long int *job, long int *up, long int *n, long int *m, __complex__ double *ab, long int *ldab, __complex__ double *bb, long int *ldbb, double *vl, double *vu, double *w, __complex__ double *q, long int *ldq, __complex__ double *work, double *rwork, long int *iwork)
– AHLAND driver routine (version 2.0) – Modified LAPACK-ROUTINE for the calculation of selected Eigen...
#define doublecomplex
doublereal i
Definition f2c.h:34
doublereal r
Definition f2c.h:34
For specializations of the memory allocator: