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 //********************************************************************************
26 TVector<double> lu_solve(const F_Matrix<double>& A, const Vector<double>& B, int overwriteA);
27 F_TMatrix<double> lu_solve(const F_Matrix<double>& A, const F_Matrix<double>& B, int overwriteA);
28 
29 F_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 //********************************************************************************
87 int eig(const F_Matrix<double>& A, Vector<double>& EW);
88 
89 int eig(const F_Matrix<double>& A, Vector<double>& EW, F_Matrix<double>& EV);
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 
320 template class tbci_memalloc<doublecomplex>;
322 
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)
const Vector< T > const Vector< T > & x
Definition: LM_fit.h:97
provides basic Vector functionality but arithmetic operators (+=, - , *, /...).
Definition: bvector.h:67
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...
F_TMatrix< double > inv(const F_Matrix< double > &A, int overwriteA=0)
Definition: lapack.cpp:181
#define NAMESPACE_TBCI
Definition: basics.h:317
F_TMatrix< double > lu_solve(const F_Matrix< double > &A, const F_Matrix< double > &B, int overwriteA=0)
Definition: lapack.cpp:156
F_Matrix< T > & resize(const unsigned r, const unsigned c)
Definition: f_matrix.h:1234
T * get_fortran_matrix() const
Definition: f_matrix.h:1209
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) –
T * get_fortran_matrix() const
Definition: f_matrix.h:181
doublereal r
Definition: f2c.h:34
void setval(const T val, const unsigned int r, const unsigned int c)
Definition: f_matrix.h:206
#define NEW(t, s)
Definition: malloc_cache.h:633
TVector< double > lu_solve_expert(const F_BandMatrix< double > &A, const Vector< double > &B, int equilibrate=1)
Solution of linear eqution systems, partial pivoting.
Definition: lapack.cpp:24
For specializations of the memory allocator:
Definition: malloc_cache.h:279
double doublereal
Definition: f2c.h:32
doublereal i
Definition: f2c.h:34
int integer
barf [ba:rf] 2.
Definition: f2c.h:27
T *const & get_fortran_vector() const
Definition: bvector.h:164
C++ class for banded matrices using band storage in a one-dimensional array.
Definition: f_bandmatrix.h:46
#define CPLX__
Definition: basics.h:341
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)
Temporary Base Class (non referable!) (acc.
Definition: bvector.h:50
int i
Definition: LM_fit.h:71
#define real
BVector< T > & resize(const BVector< T > &)
Actually it&#39;s a resize and copy (some people would expect the assignment op to do this) ...
Definition: bvector.h:361
int zgesv_(int *n, int *nrhs, __complex__ double *a, int *lda, int *ipiv, __complex__ double *b, int *ldb, int *info)
#define STD__
Definition: basics.h:338
#define TBCIDELETE(t, v, sz)
Definition: malloc_cache.h:634
Temporary Base Class Idiom: Class TVector is used for temporary variables.
Definition: bvector.h:52
#define NAMESPACE_END
Definition: basics.h:323
Definition: bvector.h:54
const Vector< T > Vector< T > Vector< T > Vector< T > & y
Definition: LM_fit.h:172
Definition: f2c.h:33
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
int imag(const int d)
Definition: basics.h:1068