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
Exemplo n.º 2
0
  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); 
  }