00001
00005
00006
00007
00008
00010 #define LAPACK_INLINE inline
00011
00012 #include "cplx.h"
00013 #include "f_matrix.h"
00014 #include "f_bandmatrix.h"
00015 #include "lapack/lapack_lib.h"
00016
00017
00018 NAMESPACE_TBCI
00019
00020
00021
00023
00024 TVector<double> lu_solve_expert(const F_BandMatrix<double>& A, const Vector<double>& B, int equi)
00025 {
00026 char fact='E';
00027 if(!equi) fact='N';
00028 char trans='N';
00029 integer n=A.columns();
00030 integer kl=A.numSub();
00031 integer ku=A.numSuper();
00032 integer nrhs=1;
00033
00034 integer ldab=A.ldab();
00035 double* afb=new double[n*(2*kl+ku+1)];
00036 integer ldafb=2*kl+ku+1;
00037 integer* ipiv=new integer[n];
00038 char equed;
00039 double* r=new double[n];
00040 double* c=new double[n];
00041 TVector<double> x(B.size());
00042 double rcond;
00043 double ferr;
00044 double berr;
00045 double* work=new double[3*n];
00046 integer* iwork=new integer[n];
00047 integer info = 0;
00048
00049 dgbsvx_(&fact, &trans, &n, &kl, &ku, &nrhs, A.get_fortran_matrix(), &ldab,
00050 afb, &ldafb, ipiv, &equed,
00051 r, c, B.get_fortran_vector(), &n,
00052 x.get_fortran_vector(), &n,
00053 &rcond, &ferr, &berr, work, iwork, &info);
00054
00055 delete[] afb;
00056 delete[] ipiv;
00057 delete[] r;
00058 delete[] c;
00059 delete[] work;
00060 delete[] iwork;
00061
00062 if (info)
00063 {
00064 STD__ cerr << "Error inverting Matrix A! (" << info << ")" << STD__ endl;
00065 STD__ cerr << "\n Equalized= " << equed << STD__ endl;
00066 STD__ cerr << " 1/Cond= " << rcond << " epsilon= " << dlamch_ ("Epsilon")
00067 << " f_err= " << ferr
00068 << " b_err= " << berr << STD__ endl;
00069 }
00070 return x;
00071 }
00072
00073
00074 TVector<double> lu_solve(const F_BandMatrix<double>& A, const Vector<double>& B)
00075 {
00076 integer n=A.columns();
00077 integer kl=A.numSub();
00078 integer ku=A.numSuper();
00079 integer nrhs = 1;
00080 integer info = 0;
00081 TVector<double> invA(B);
00082 BVector<integer> ipiv(n);
00083
00084
00085 {
00086 F_BandMatrix<double> temp(n,2*ku,kl);
00087 temp.clear();
00088
00089 for(int i=0; i<n; i++)
00090 {
00091 temp(i,i)=A(i,i);
00092 for(int j=1; j<=kl; j++) {if(i-j>=0) temp(i,i-j)=A(i,i-j);}
00093 for(int k=1; k<=ku; k++) {if(i+k<n) temp(i,i+k)=A(i,i+k);}
00094 }
00095 integer ldab=temp.ldab();
00096 dgbsv_(&n, &kl, &ku,
00097 &nrhs, temp.get_fortran_matrix(), &ldab, ipiv.get_fortran_vector(),
00098 invA.get_fortran_vector(), &n, &info);
00099 }
00100 if (info)
00101 STD__ cerr << "Error inverting Matrix A! (" << info << ")" << STD__ endl;
00102 return invA;
00103 }
00104
00105 TVector<double> lu_solve(F_BandMatrix<double>& A, const Vector<double>& B, integer kl, integer ku)
00106 {
00107 integer n=A.columns();
00108
00109
00110 integer nrhs = 1;
00111 integer info = 0;
00112 TVector<double> invA(B);
00113 BVector<integer> ipiv(n);
00114
00115 {
00116 if (ku > (long)A.numSuper()/2)
00117 STD__ cerr << "Matrix too small to store fill_in" << STD__ endl;
00118 integer ldab=A.ldab();
00119 dgbsv_(&n, &kl, &ku,
00120 &nrhs, A.get_fortran_matrix(), &ldab, ipiv.get_fortran_vector(),
00121 invA.get_fortran_vector(), &n, &info);
00122 }
00123
00124 if (info)
00125 STD__ cerr << "Error inverting Matrix A! (" << info << ")" << STD__ endl;
00126 return invA;
00127 }
00128
00129 TVector<double> lu_solve(const F_Matrix<double>& A, const Vector<double>& B, int overwriteA)
00130 {
00131 integer n=A.columns();
00132 integer nrhs=1;
00133 integer info=0;
00134 TVector<double> invA(B);
00135 BVector<integer> ipiv(n);
00136
00137
00138 if (overwriteA)
00139 {
00140 dgesv_(&n, &nrhs, A.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
00141 invA.get_fortran_vector(), &n, &info);
00142 }
00143 else
00144 {
00145 F_Matrix<double> temp(A);
00146 dgesv_(&n, &nrhs, temp.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
00147 invA.get_fortran_vector(), &n, &info);
00148 }
00149
00150 if (info)
00151 STD__ cerr << "Error inverting Matrix A!" << STD__ endl;
00152 return invA;
00153 }
00154
00155
00156 F_TMatrix<double> lu_solve(const F_Matrix<double>& A, const F_Matrix<double>& B, int overwriteA)
00157 {
00158 integer n=A.columns();
00159 integer info;
00160 F_TMatrix<double> invA(B);
00161 BVector<integer> ipiv(n);
00162
00163 if (overwriteA)
00164 {
00165 dgesv_(&n, &n, A.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
00166 invA.get_fortran_matrix(), &n, &info);
00167 }
00168 else
00169 {
00170 F_Matrix<double> temp(A);
00171 dgesv_(&n, &n, temp.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
00172 invA.get_fortran_matrix(), &n, &info);
00173 }
00174
00175 if (info)
00176 STD__ cerr << "Error inverting Matrix A!" << STD__ endl;
00177 return invA;
00178 }
00179
00180
00181 F_TMatrix<double> inv(const F_Matrix<double>& A, int overwriteA)
00182 {
00183 integer n=A.columns();
00184 integer info=0;
00185
00186 F_TMatrix<double> invA(0.0, n, n);
00187 for (int i=0; i<n; i++)
00188 invA.setval(1.0,i,i);
00189 BVector<integer> ipiv(n);
00190 F_Matrix<double> temp;
00191 if (!overwriteA)
00192 {
00193 temp.resize(n,n);
00194 temp=A;
00195 }
00196
00197 if (overwriteA)
00198 dgesv_(&n, &n, A.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
00199 invA.get_fortran_matrix(), &n, &info);
00200 else
00201 dgesv_(&n, &n, temp.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
00202 invA.get_fortran_matrix(), &n, &info);
00203 if (info)
00204 STD__ cerr << "Error inverting Matrix A!" << STD__ endl;
00205 return invA;
00206 }
00207
00208 F_TMatrix<cplx<double> > inv(const F_Matrix<cplx<double> >& A, int overwriteA)
00209 {
00210 integer n=A.columns();
00211 integer info=0;
00212 BVector<integer> ipiv(n);
00213 F_Matrix<cplx<double> > temp;
00214 if (!overwriteA)
00215 {
00216 temp.resize(n,n);
00217 temp=A;
00218 }
00219
00220 F_TMatrix<cplx<double> > invA(0.0, n, n);
00221 for (int i=0; i<n; i++)
00222 invA.setval(cplx<double>(1.0), i,i);
00223
00224 if (overwriteA)
00225 zgesv_(&n, &n, (doublecomplex*) A.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
00226 (doublecomplex*) invA.get_fortran_matrix(), &n, &info);
00227 else
00228 zgesv_(&n, &n, (doublecomplex*) temp.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
00229 (doublecomplex*) invA.get_fortran_matrix(), &n, &info);
00230 if (info)
00231 STD__ cerr << "Error inverting Matrix A!" << STD__ endl;
00232 return invA;
00233 }
00234
00235 F_TMatrix<cplx<double> > lu_solve(const F_Matrix<cplx<double> >& A, const F_Matrix<cplx<double> >& B, int overwriteA)
00236 {
00237 integer n=A.columns();
00238 integer info=0;
00239 BVector<integer> ipiv(n);
00240 F_Matrix<cplx<double> > temp;
00241 if (!overwriteA)
00242 {
00243 temp.resize(n,n);
00244 temp=A;
00245 }
00246 F_TMatrix<cplx<double> > invA(B);
00247
00248 if (overwriteA)
00249 zgesv_(&n, &n, (doublecomplex*) A.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
00250 (doublecomplex*) invA.get_fortran_matrix(), &n, &info);
00251 else
00252 zgesv_(&n, &n, (doublecomplex*) temp.get_fortran_matrix(), &n, ipiv.get_fortran_vector(),
00253 (doublecomplex*) invA.get_fortran_matrix(), &n, &info);
00254 if (info)
00255 STD__ cerr << "Error inverting Matrix A!" << STD__ endl;
00256 return invA;
00257 }
00258
00259
00260
00262
00263 int eig(const F_Matrix<double>& A, Vector<double>& EW)
00264 {
00265 char jobz='N';
00266 char uplo='U';
00267 integer N=A.columns();
00268 integer lwork=3*N;
00269 BVector<double> work(lwork);
00270 integer info=0;
00271 F_Matrix<double> EV(A);
00272 dsyev_(&jobz, &uplo, &N, EV.get_fortran_matrix(),
00273 &N, EW.get_fortran_vector(), work.get_fortran_vector(), &lwork,
00274 &info);
00275 return (int) info;
00276 }
00277
00278
00279 int eig(const F_Matrix<double>& A, Vector<double>& EW, F_Matrix<double>& EV)
00280 {
00281 char jobz='V';
00282 char uplo='U';
00283 integer N=A.columns();
00284 integer lwork=3*N;
00285 BVector<double> work(lwork);
00286 integer info=0;
00287 EV = A;
00288 dsyev_(&jobz, &uplo, &N, EV.get_fortran_matrix(),
00289 &N, EW.get_fortran_vector(), work.get_fortran_vector(), &lwork,
00290 &info);
00291 return (int) info;
00292 }
00293
00294
00295
00296 int eig(const F_BandMatrix<double>& A, Vector<double>& EW, F_Matrix<double>& EV)
00297 {
00298 char jobz='V';
00299 char uplo='U';
00300 integer N=A.columns();
00301 integer kd=A.numSuper();
00302 integer lwork=3*N-2;
00303 integer lda=1+A.numSuper()+A.numSub();
00304 integer ldz =N;
00305 BVector<double> work(lwork);
00306 integer info=0;
00307
00308
00309
00310
00311
00312 dsbev_(&jobz, &uplo, & N, &kd, A.get_fortran_matrix(), &lda,
00313 EW.get_fortran_vector(), EV.get_fortran_matrix(),
00314 &ldz, work.get_fortran_vector(), &info);
00315
00316 return (int) info;
00317 }
00318
00319
00320 int eig(const F_BandMatrix<double>& A, Vector<double>& EW, F_Matrix<double>& EV,
00321 double ew_min, double ew_max)
00322 {
00323 char jobz='V';
00324 char uplo='U';
00325 char range='V';
00326 integer N=A.columns();
00327 integer kd=A.numSuper();
00328 integer lda=1+A.numSuper()+A.numSub();
00329
00330 integer ldz =N;
00331 BVector<double> work(7*N);
00332 BVector<integer> iwork(5*N);
00333 BVector<integer> ifail(N);
00334 integer ldq =N;
00335 BVector<double> q(N*ldq);
00336 integer info=0, dummy, m;
00337 double abstol=0;
00338
00339 Vector<double> EW_temp(N);
00340 F_Matrix<double> EV_temp(N,N);
00341
00342
00343
00344
00345
00346
00347
00348
00349 dsbevx_(&jobz, &range, &uplo, &N,
00350 &kd, A.get_fortran_matrix(), &lda,
00351 q.get_fortran_vector(), &ldq,
00352 &ew_min, &ew_max, &dummy, &dummy,
00353 &abstol, &m, EW_temp.get_fortran_vector(), EV_temp.get_fortran_matrix(), &ldz,
00354 work.get_fortran_vector(), iwork.get_fortran_vector(),
00355 ifail.get_fortran_vector(), &info);
00356
00357
00358 EV.resize(N,m);
00359 EW.resize(m);
00360 for(int i=0; i<m; i++)
00361 {
00362 EW(i)=EW_temp(i);
00363 EV.set_col(EV_temp.get_col(i), i);
00364 }
00365
00366 return (int) info;
00367 }
00368
00369
00370
00371
00373
00374 int eig(const F_Matrix<cplx<double> >& A, Vector<cplx<double> >& EW)
00375 {
00376 char jobvl='N';
00377 char jobvr='N';
00378 integer N=A.columns();
00379 doublecomplex* vl=0;
00380 doublecomplex* vr=0;
00381 integer lwork=2*N;
00382 doublecomplex* work =NEW(doublecomplex,lwork);
00383 doublereal* rwork=NEW(doublereal,lwork);
00384 integer info=0;
00385 zgeev_(&jobvl, &jobvr, &N,
00386 (doublecomplex*) A.get_fortran_matrix(), &N,
00387 (doublecomplex*) EW.get_fortran_vector(), vl,
00388 &N, vr, &N, work, &lwork, rwork, &info);
00389 TBCIDELETE(doublecomplex, work, lwork);
00390 TBCIDELETE(doublereal, rwork, lwork);
00391 return (int) info;
00392 }
00393
00394
00395 int eig(const F_Matrix<cplx<double> >& A, Vector<cplx<double> >& EW, F_Matrix<cplx<double> >& EV)
00396 {
00397 char jobvl='N';
00398 char jobvr='V';
00399 integer N=A.columns();
00400 doublecomplex* vl=0;
00401 integer lwork=2*N;
00402 doublecomplex* work =NEW(doublecomplex,lwork);
00403 doublereal* rwork=NEW(doublereal,lwork);
00404 integer info=0;
00405 zgeev_(&jobvl, &jobvr, &N, (doublecomplex*) A.get_fortran_matrix(), &N,
00406 (doublecomplex*) EW.get_fortran_vector(), vl,
00407 &N, (doublecomplex*) EV.get_fortran_matrix(), &N, work, &lwork, rwork, &info);
00408 TBCIDELETE(doublecomplex, work, lwork);
00409 TBCIDELETE(doublereal, rwork, lwork);
00410 return (int) info;
00411 }
00412
00413
00414
00415
00416
00418
00419 int eig(const F_BandMatrix<cplx<double> >& A, const F_BandMatrix<cplx<double> >& B,
00420 double EW_min, double EW_max,
00421 Vector<double>& Eigenwerte, F_Matrix<cplx<double> >& Eigenvectoren)
00422 {
00423
00424 long uplo=1;
00425
00426 long n=A.columns();
00427
00428 long ldab=A.numSuper()+1;
00429 long ldbb=B.numSuper()+1;
00430
00431 long Anzahl_Eigenwerte;
00432 long BerechneEV=1;
00433
00434
00435 int i,j, x,y;
00436
00437
00438
00439
00440
00441
00442
00443 doublecomplex *ab = new doublecomplex[ldab*n];
00444 doublecomplex *bb = new doublecomplex[ldbb*n];
00445
00446
00447 for (i=0; i<n; i++)
00448 {
00449
00450 for (j=i; j<i+ldab && j<n; j++)
00451 {
00452
00453 x=ldab+i-j-1;
00454 y=j;
00455 ab[x+ldab*y].r = CPLX__ real(A(i,j));
00456 ab[x+ldab*y].i = CPLX__ imag(A(i,j));
00457 }
00458
00459
00460 for (j=i; j<i+ldbb && j<n; j++)
00461 {
00462
00463 x=ldbb+i-j-1;
00464 y=j;
00465 bb[x+ldbb*y].r = CPLX__ real(B(i,j));
00466 bb[x+ldbb*y].i = CPLX__ imag(B(i,j));
00467 }
00468 }
00469
00470
00471
00472
00473 double* ew = new double[n];
00474 long *iwork = new long[5*n];
00475 double *rwork = new double[7*n];
00476 doublecomplex *work = new doublecomplex[n];
00477 doublecomplex *q = new doublecomplex[n*n];
00478
00479
00480
00481 long info=own_ew_(&BerechneEV, &uplo, &n, &Anzahl_Eigenwerte, ab, &ldab, bb, &ldbb,
00482 &EW_min, &EW_max, ew, q, &n, work, rwork, iwork);
00483 if (!info==0)
00484 {
00485 STD__ cerr << " Error calculating eigenvalues: (status " << info << ")" << STD__ endl;
00486 return info;
00487 }
00488 delete [] ab ;
00489 delete [] bb ;
00490
00491 if (BerechneEV==1 && Anzahl_Eigenwerte>0)
00492 {
00493
00494 doublecomplex *EV = new doublecomplex[n*Anzahl_Eigenwerte];
00495 long *ifail = new long[Anzahl_Eigenwerte];
00496
00497 for (i=0;i<n*Anzahl_Eigenwerte;i++)
00498 {
00499 EV[i].r=0;
00500 EV[i].i=0;
00501 }
00502 info=own_ev_(&n, &Anzahl_Eigenwerte, ew, EV, &n, q, &n, work, rwork, iwork, ifail);
00503 if (!info==0)
00504 {
00505 STD__ cerr << " Error calculating eigenvectors" << STD__ endl;
00506 return info;
00507 }
00508
00509
00510 Eigenvectoren.resize(n,Anzahl_Eigenwerte);
00511 for (j=0;j<Anzahl_Eigenwerte;j++)
00512 {
00513 for (int i=0; i<n; i++)
00514 {
00515 Eigenvectoren(i,j).set(EV[i+n*j].r, EV[i+n*j].i);
00516 }
00517 }
00518 delete[] ifail;
00519 delete[] EV;
00520 }
00521
00522
00523 Eigenwerte.resize(Anzahl_Eigenwerte);
00524 for(i=0; i<Anzahl_Eigenwerte; i++) Eigenwerte(i) = ew[i];
00525
00526 delete[] ew;
00527 delete[] q;
00528 delete[] iwork;
00529 delete[] rwork;
00530 delete[] work;
00531 return 0;
00532 }
00533
00534
00535
00536
00538
00539 int eig(const F_Matrix<cplx<double> >& A, Vector<double>& EW, F_Matrix<cplx<double> >& EVec)
00540 {
00541 char jobz='V';
00542 char uplo='U';
00543 integer n=A.rows();
00544
00545 integer lwork =2*n-1;
00546 doublecomplex *work = new doublecomplex[lwork];
00547 double *rwork = new double[3*n-2];
00548 integer info=0;
00549
00550 EVec=A;
00551 zheev_(&jobz, &uplo, &n, (doublecomplex*) EVec.get_fortran_matrix(), &n,
00552 EW.get_fortran_vector(), work, &lwork, rwork, &info);
00553
00554 if (!info==0)
00555 {
00556 STD__ cerr << " Error calculating eigenvalues: (status " << info << ")" << STD__ endl;
00557 return info;
00558 }
00559
00560
00561 delete[] work;
00562 delete[] rwork;
00563 return 0;
00564 }
00565
00566
00567 int eig(F_Matrix<cplx<double> > A, Vector<double>& EW)
00568 {
00569 char jobz='N';
00570 char uplo='U';
00571 integer n=A.rows();
00572
00573 integer lwork =2*n-1;
00574 doublecomplex *work = new doublecomplex[lwork];
00575 double *rwork = new double[3*n-2];
00576 integer info=0;
00577
00578 zheev_(&jobz, &uplo, &n, (doublecomplex*) A.get_fortran_matrix(), &n,
00579 EW.get_fortran_vector(), work, &lwork, rwork, &info);
00580
00581 if (!info==0)
00582 {
00583 STD__ cerr << " Error calculating eigenvalues: (status " << info << ")" << STD__ endl;
00584 return info;
00585 }
00586
00587
00588 delete[] work;
00589 delete[] rwork;
00590 return 0;
00591 }
00592
00593 template class tbci_memalloc<doublecomplex>;
00594 template class tbci_memalloc_cache<doublecomplex>;
00595
00596 NAMESPACE_END