#ifdef LAPACK #include #include using namespace std; #include "LapackInterface.hpp" /* #include #define dggev_ dggev #define dsyev_ dsyev #define dggbak_ dggbak #define dggbal_ dggbal #define zggev_ zggev #define zggbal_ zggbal #define zggev_ zggev */ #include "LapackGEP.hpp" void LaEigNSSolveTest() { double * A= new double[16]; double * B= new double[16]; int i; for(i=0;i<16;i++) {A[i]=0.;} A[0]=1.; A[4]=2.; A[1]=2.; A[5]=5.; A[15]=1.; A[10]=0.2; for(i=0;i<16;i++) B[i] = A[i]; char jobvr = 'V', jobvl= 'N'; int n = 4; int info; double * wr = new double[n]; double* work = new double[16*n]; int lwork = 16*n; char uplo = 'U' ; dsyev_(&jobvr,&uplo , &n , A , &n, wr, work, &lwork, &info); // dggev_(&jobvl, &jobvr, &n, A, &n, B, &n, wr, wi, beta, &vl, &nvl, &vr, &nvl, // work , &lwork, &info); int j,k; double *ev = new double[4]; double *v2 = new double[4]; /*cout << " Matrix B (original) " << endl; for(i=0;i * lami, int evecs_bool, double * evecs_re, double * evecs_im, char balance_type ) { char jobvr , jobvl= 'N'; bool balancing = 0; if ( balance_type == 'B' || balance_type == 'S' || balance_type == 'P' ) balancing =1; int info; double * wi= new double[n], * wr = new double[n]; double * beta = new double[n]; double vl=0; int nvl = 1; int nvr ; if (evecs_bool) { jobvr = 'V'; nvr = n; } else { nvr=1; jobvr = 'N'; } double *vr = new double[nvr*nvr]; double* work = new double[16*n]; int lwork = 16*n; int i,j,k; char job=balance_type; // Permute and Scale in Balancing int ihi,ilo; double * lscale, *rscale; lscale = new double[n]; rscale = new double[n]; char side = 'R'; if(balancing) dggbal_(&job,&n, A,&n , B, &n, &ilo, &ihi, lscale, rscale, work, &info) ; else info =0; if(info ==0 ) { dggev_(&jobvl, &jobvr, &n, A, &n, B, &n, wr, wi, beta, &vl, &nvl, vr, &nvr, work , &lwork, &info); if(info==0) { if(jobvr == 'V' && balancing) { dggbak_(&job, &side, &n, &ilo, &ihi, lscale, rscale, &n, vr, &n,&info) ; if(info!=0) { cout << " Error in dggbak_ :: info " << info << endl; return; } } } else { cout << " Error in dggev_ :: info " << info << endl; return; } } else { cout << " Error in dggbal_ :: info " << info << endl; return; } delete lscale; delete rscale; for(i=0;i1e-30) // not infinite eigenvalue lami[i]=std::complex(wr[i]/beta[i],wi[i]/beta[i]); else { lami[i]=std::complex(100.,100.); } } if(evecs_bool) { for(i=0;i real eigenvector in i-th line { for(j=0;j(vr[i*n + j],0.); evecs_re[i*n+j]= vr[i*n+j]; evecs_im[i*n+j]= 0.; } } else // conjugate complex eigenvectors { for(j=0;j(vr[i*n+j],vr[(i+1)*n+j]); // evecs[(i+1)*n+j]=std::complex(vr[i*n+j],-vr[(i+1)*n+j]); evecs_re[i*n+j]= vr[i*n+j]; evecs_re[(i+1)*n+j]=vr[i*n+j]; evecs_im[i*n+j]= vr[(i+1)*n+j]; evecs_im[(i+1)*n+j]=-vr[(i+1)*n+j]; } i++; } } } delete wi; delete wr; delete beta; delete work; delete vr; } // Attention A,B are overwritten !!! void LaEigNSSolve(int n, std::complex * A, std::complex * B, std::complex * lami, int evecs_bool, std::complex * evecs, std::complex * dummy, char balance_type) { char jobvr , jobvl= 'N'; bool balancing = 0; if ( balance_type == 'B' || balance_type == 'S' || balance_type == 'P' ) balancing =1; std::complex * alpha= new std::complex[n]; std::complex * beta = new std::complex[n]; std::complex vl=0.; int nvl = 1; std::complex * vr ; std::complex * work = new std::complex[8*n]; int lwork = 8*n; double *rwork = new double[8*n]; int nvr = n ; if (evecs_bool) { jobvr = 'V'; vr = evecs; } else jobvr = 'N'; //std::complex * A1,*B1; int i; char job=balance_type; // Permute and Scale in Balancing int ihi,ilo; double * lscale, *rscale; lscale = new double[n]; rscale = new double[n]; double * work2; work2 = new double[6*n]; char side = 'R'; int info = 0; int ii; ii=0; if(balancing) zggbal_(&job,&n, A, &n , B, &n, &ilo, &ihi, lscale, rscale, work2, &info) ; if(info == 0 ) { zggev_(&jobvl, &jobvr, &n, A, &n, B, &n, alpha, beta, &vl, &nvl, vr, &nvr, work , &lwork, rwork, &info); if(info==0) { if(jobvr == 'V' && balancing) { zggbak_(&job, &side, &n, &ilo, &ihi, lscale, rscale, &n, vr, &n,&info) ; if(info!=0) { cout << "***** Error in zggbak_ **** " << endl; return; } } } else { cout << "**** Error in zggev_ *****" << endl; return; } } else { cout << "**** Error in zggbal_ **** " << endl; return; } delete work; delete rwork; delete lscale; delete rscale; delete work2; for(i=0;i= 1.e-30) lami[i]=std::complex(alpha[i]/beta[i]); else { lami[i] = std::complex(100.,100.); } } /* std:: complex resid[n]; double error; for(int k=0; k & h, const int & ldh, complex & w, complex & z, const int & ldz, complex & work, const int & lwork, int & info); extern "C" void zhsein_ (const char & side, const char & eigsrc, const char & initv, int * select, const int & n, complex & h, const int & ldh, complex & w, complex & vl, const int & ldvl, complex & vr, const int & ldvr, const int & mm, int & m, complex & work, double & rwork, int & ifaill, int & ifailr, int & info); void LapackHessenbergEP (int n, std::complex * A, std::complex * lami, std::complex * evecs) { int lwork = 2 * n * n; // or n ? complex * work = new complex[lwork]; // complex * work2 = new complex[lwork]; double * rwork = new double[n]; complex * hA = new complex[n*n]; for (int i = 0; i < n*n; i++) { hA[i] = A[i]; } int * select = new int[n]; for (int i = 0; i < n; i++) select[i] = 'V'; complex vl; // complex * vl = new complex[n*n]; // complex * vr = new complex[n*n]; int info; int * ifaill = new int[n]; int * ifailr = new int[n]; cout << "calls zhseqr" << endl; zhseqr_('E', 'N', n, 1, n, *hA, n, *lami, *evecs, n, *work, lwork, info); // zhseqr_('S', 'I', n, 1, n, *A, n, *lami, *evecs, n, *work, lwork, info); if (info) cout << "error in eigensolver, info = " << info << endl; for (int i = 0; i < n; i++) cout << "ev(" << i << ") = " << lami[i] << endl; for (int i = 0; i < n*n; i++) { hA[i] = A[i]; } int m = 0; char side = 'R', eigsrc = 'N', initv = 'N'; int hn = n, ldh = n, ldvl = n, ldvr = n, mm = n; cout << "call zhsein" << endl; zhsein_ ('R', 'Q', 'N', select, hn, *A, ldh, *lami, vl, ldvl, *evecs, ldvr, mm, m, *work, *rwork, *ifaill, *ifailr, info); cout << "m = " << m << endl; cout << "rwork[0] = " << rwork[0] << endl; // for (int i = 0; i < n; i++) // cout << "ifail[" << i << "] = " << ifaill[i] << endl; // cout << "ifaill = " << ifaill << endl; // cout << "ifailr = " << ifailr << endl; cout << "info = " << info << endl; delete select; delete hA; delete rwork; delete work; cout << "hessenberg complete" << endl; } void LapackGHEP(int n, double* A, double* B, double* lami) { int i,j; double *B1 = new double[n*n]; double *A1 = new double[n*n]; for(i=0;i * A, std::complex * F) { // Solve Ax=F // A on exit LU factorization // F is overwritten by solution x int nrhs =1; int *ipiv; ipiv = new int[n]; int info; zgesv_(&n, &nrhs, A, &n, ipiv, F, &n, &info ); if(info!=0) cout << " ***** Error in LapackGEP.cpp LaLinearSolveComplex : info = " << info << endl; delete ipiv; return; } void LaLinearSolve(int n, double * A, double * F) { // Invert // A on exit LU factorization // F is overwritten by solution x int nrhs = n; int *ipiv; ipiv = new int[n*n]; int info; dgesv_(&n, &nrhs, A, &n, ipiv, F, &n, &info ); if(info!=0) cout << " ***** Error in LapackGEP.cpp LaLinearSolveComplex : info = " << info << endl; delete ipiv; return; } #endif