void QuasiNewton<dcomplex>::symmHerDiag(int NTrial, ostream &output){ /* * Solve S(R)| X(R) > = E(R)| X(R) > (1/ω) * * | X(R) > = | X(R)_g > * | X(R)_u > * * The opposite (1/ω vs ω) is solved because the metric is not positive definite * and can therefore not be solved using DSYGV because of the involved Cholesky * decomposition. * */ char JOBV = 'V'; char UPLO = 'L'; int iType = 1; int TwoNTrial = 2*NTrial; int INFO; ComplexCMMap SSuper(this->SSuperMem, 2*NTrial,2*NTrial); ComplexCMMap SCPY(this->SCPYMem, TwoNTrial,TwoNTrial); SCPY = SSuper; // Copy of original matrix to use for re-orthogonalization // Perform diagonalization of reduced subspace using DSYGV zhegv_(&iType,&JOBV,&UPLO,&TwoNTrial,this->SSuperMem,&TwoNTrial, this->ASuperMem,&TwoNTrial,this->RealEMem,this->WORK,&this->LWORK, this->RWORK,&INFO); if(INFO!=0) CErr("ZHEGV failed to converge in Davison Iterations",output); // Grab the "positive paired" roots (throw away other element of the pair) this->RealEMem += NTrial; RealVecMap ER (this->RealEMem,NTrial); new (&SSuper) ComplexCMMap(this->SSuperMem+2*NTrial*NTrial,2*NTrial,NTrial); // Swap the ordering because we solve for (1/ω) for(auto i = 0 ; i < NTrial; i++) ER(i) = 1.0/ER(i); for(auto i = 0 ; i < NTrial/2; i++){ SSuper.col(i).swap(SSuper.col(NTrial - i - 1)); double tmp = ER(i); ER(i) = ER(NTrial - i - 1); ER(NTrial - i - 1) = tmp; } /* * Re-orthogonalize the eigenvectors with respect to the metric S(R) * because DSYGV orthogonalzies the vectors with respect to E(R) * because we solve the opposite problem. * * Gramm-Schmidt */ this->metBiOrth(SSuper,SCPY); // Separate the eigenvectors into gerade and ungerade parts ComplexCMMap XTSigmaR(this->XTSigmaRMem,NTrial,NTrial); ComplexCMMap XTSigmaL(this->XTSigmaLMem,NTrial,NTrial); XTSigmaR = SSuper.block(0, 0,NTrial,NTrial); XTSigmaL = SSuper.block(NTrial,0,NTrial,NTrial); } // symmHerDiag
int LapackGHEPEPairs(int hn, complex<double>* A, complex<double>* B, double* lami) { integer n = hn; char jobzm = 'V' , uplo = 'U'; integer lwork=8*n; std::complex<double>* work = new std::complex<double>[lwork]; double* rwork = new double[lwork]; integer info; integer itype =1; integer lda = n; integer ldb = n; cout << " zhegv " << endl; cout << " A s " << endl; for(int j=0;j<n;j++) { for(int k=0;k<n;k++) cout << A[j*n+k] << " \t " ; cout << endl; } cout << " M " << endl; for(int j=0;j<n;j++) { for(int k=0;k<n;k++) cout << B[j*n+k] << " \t " ; cout << endl; } zhegv_(&itype,&jobzm,&uplo , &n , A , &lda, B, &ldb, lami, work, &lwork, rwork, &info); cout << " ... is back " << endl; if(info != 0) { cout << "LapackGHEPEPairs Info " << info << endl; cout << "n = " << n << endl; } delete [] work; delete [] rwork; return(info); }