MatrixXd MultivariateFNormalSufficient::compute_PW_cg() const { //compute PW using CG. Preconditionner is Sigma^-1 and initial guess //is previous value of PW. Do M steps (theoretically sufficient) and if the //residuals are too big do the inversion. // timer_.start(PW_CG_SUCCESS); //static unsigned numtries=0; //static unsigned numfail=0; cg_->set_A(get_Sigma()); cg_->set_B(get_W()); cg_->set_X0(PW_); cg_->set_tol(cg_tol_); MatrixXd PW(cg_->optimize(precond_, M_)); if (cg_->info()>0) timer_.stop(PW_CG_SUCCESS); double resid = (get_Sigma()*PW-get_W()).norm(); if (resid > cg_tol_) { //numfail++; PW = compute_PW_direct(); } //numtries++; //std::cout << "CG: numtries="<<numtries<<" numfail="<<numfail<<std::endl; return PW; }
VectorXd MultivariateFNormalSufficient::get_Sigma_eigenvalues() const { Eigen::SelfAdjointEigenSolver<MatrixXd> eigensolver(get_Sigma(), Eigen::EigenvaluesOnly); CHECK(eigensolver.info() == Eigen::Success, "Could not determine eigenvalues!"); return eigensolver.eigenvalues(); }
VectorXd MultivariateFNormalSufficient::get_Sigma_eigenvalues() const { Eigen::SelfAdjointEigenSolver<MatrixXd> eigensolver(get_Sigma(), Eigen::EigenvaluesOnly); if (eigensolver.info() != Eigen::Success) IMP_THROW("Could not determine eigenvalues!", ModelException); return eigensolver.eigenvalues(); }
void IASIAM::get_G() { get_Sigma(); for (int i=0; i<N; i++) r->G[i] = 1.0 / (ii*r->omega[i] + r->mu - epsilon - r->Delta[i] - r->Sigma[i]) ; if (PatchTailWithAtomicLimit) r->PatchAtomicLimitG(AtomicCutoff, U); }
//Eigen::LLT<MatrixXd, Eigen::Upper> Eigen::LDLT<MatrixXd, Eigen::Upper> MultivariateFNormalSufficient::get_ldlt() const { if (!flag_ldlt_) { timer_.start(CHOLESKY); IMP_LOG(TERSE, "MVN: computing Cholesky decomposition" << std::endl); // compute Cholesky decomposition for determinant and inverse //Eigen::LLT<MatrixXd, Eigen::Upper> ldlt(get_Sigma()); Eigen::LDLT<MatrixXd, Eigen::Upper> ldlt(get_Sigma()); //if (ldlt.info() != Eigen::Success) if (!ldlt.isPositive()) { std::cout << "Sigma" << std::endl; std::cout << get_Sigma() << std::endl; IMP_THROW("Sigma matrix is not positive semidefinite!", ModelException); } const_cast<MultivariateFNormalSufficient *>(this)->set_ldlt(ldlt); timer_.stop(CHOLESKY); } return ldlt_; }
void SIAM::get_G_CHM() { get_Sigma(); if (UseLatticeSpecificG) #pragma omp parallel for for (int i=0; i<N; i++) { complex<double> com = r->omega[i] + r->mu - r->Sigma[i]; r->G[i] = LS_get_G(LatticeType, t, com); } else { complex<double>** g = new complex<double>*[N]; #pragma omp parallel for for (int i=0; i<N; i++) { //treat integrand carefully double D = 0.0; complex<double> LogTerm = 0.0; if (abs(imag(r->Sigma[i]))<0.1) { D = grid->interpl(r->NIDOS, r->mu + r->omega[i] - real(r->Sigma[i])); LogTerm = complex<double>(D, 0.0) * log( (r->mu + r->omega[i] - r->Sigma[i] + r->omega[N-1]) /(r->mu + r->omega[i] - r->Sigma[i] - r->omega[N-1]) ); } //create integrand array g[i] = new complex<double>[N]; for (int j=0; j<N; j++) g[i][j] = complex<double>(r->NIDOS[j] - D, 0.0) / ( r->mu + r->omega[i] - r->omega[j] - r->Sigma[i] ); //integrate to get G r->G[i] = TrapezIntegral(N, g[i], r->omega) + LogTerm ; if (ClipOff(r->G[i])) Clipped = true; delete [] g[i]; } delete [] g; if (Clipped) printf(" !!!!Clipping G!!!!\n"); } }
//Eigen::LLT<MatrixXd, Eigen::Upper> Eigen::LDLT<MatrixXd, Eigen::Upper> MultivariateFNormalSufficient::get_ldlt() const { if (!flag_ldlt_) { LOG( "MVN: computing Cholesky decomposition" << std::endl); // compute Cholesky decomposition for determinant and inverse //Eigen::LLT<MatrixXd, Eigen::Upper> ldlt(get_Sigma()); Eigen::LDLT<MatrixXd, Eigen::Upper> ldlt(get_Sigma()); //if (ldlt.info() != Eigen::Success) CHECK(ldlt.isPositive(), "Sigma matrix is not positive semidefinite!"); const_cast<MultivariateFNormalSufficient *>(this)->set_ldlt(ldlt); } return ldlt_; }
void SIAM::get_G_CHM() { get_Sigma(); for (int i=0; i<N; i++) { //treat integrand carefully double D = 0.0; complex<double> LogTerm = 0.0; if (abs(imag(Sigma[i]))<0.1) { D = grid->interpl(Dos,mu + omega[i]-real(Sigma[i]));/*DOS(DOStype_CHM, t_CHM, mu + omega[i]-real(Sigma[i]));*/ LogTerm = complex<double>(D, 0.0) * log( (mu + omega[i] - Sigma[i] + omega[N-1]) /(mu + omega[i] - Sigma[i] - omega[N-1]) ); } //create integrand array complex<double>* g = new complex<double>[N]; for (int j=0; j<N; j++) g[j] = complex<double>(/*DOS( DOStype_CHM, t_CHM, omega[j] )*/Dos[j] - D, 0.0) / ( mu + omega[i] - omega[j] - Sigma[i] ); /* //treat integrand less carefully complex<double>* g = new complex<double>[N]; for (int j=0; j<N; j++) g[j] = complex<double>(DOS( DOStype_CHM, t_CHM, omega[j] )) / ( complex<double>(mu,eta) + omega[i] - omega[j] - Sigma[i] ); */ //integrate to get G G[i] = TrapezIntegral(N, g,omega) + LogTerm ; if (ClipOff(G[i])) Clipped = true; delete [] g; } if (Clipped) printf(" !!!!Clipping G!!!!\n"); }
void SIAM::SolveSiam(complex<double>* V) { mu0 = real(V[0]); MPT_B = real(V[1]); //--------------------// get_G0(); n = get_n(G0); MPT_B0 = get_MPT_B0(); get_As(); get_Ps(); get_SOCSigma(); get_Sigma(); get_G(); //--------------------// V[0] = mu0 + (get_n(G) - n); //we need to satisfy (get_n(G) == n) and V[1] = get_MPT_B(); // (MPT_B == get_MPT_B()) }
double MultivariateFNormalSufficient::get_Sigma_condition_number() const { return get_Sigma().norm()*get_P().norm(); }
bool SIAM::Run_CHM(double n, complex<double>* Delta, //input complex<double>* G_out, complex<double>* Sigma_out, double &mu_out) //output { if (!Initialized) exit(1); Clipped = false; for (int i=0; i<N; i++) if (ClipOff(Delta[i])) Clipped = true; if (Clipped) printf(" !!! Clipping Delta !!!\n"); this->n = n; this->Delta = Delta; //PrintFunc("DeltaSiam",N,Delta,omega); this->epsilon = 0; if (n==0.5) HalfFilling = true; else HalfFilling = false; printf(" ------- SIAM for CHM: n=%.3f, U=%.3f, T=%.3f, epsilon=%.3f -------\n", n, U, T, epsilon); if (HalfFilling) { mu = 0.5*U; mu0 = 0.0; MPT_B = 0.0; MPT_B0 = 0.0; SymmetricCase = true; } //------initial guess---------// complex<double>* V = new complex<double>[1]; V[0] = mu0; //initial guess is always the last mu0. in first DMFT iteration it is 0 //---------------------------// printf(" MPT: B = %fe, B0 = %fe\n", MPT_B, MPT_B0); //----------------- CALCULATION ----------------------// if (HalfFilling)//and (SymmetricCase)) get_G0(); else UseBroyden<SIAM>(1, MAX_ITS, Accr, &SIAM::get_G0, this, V); printf(" mu0 = %f\n", mu0); printf("Integral G0: %.6f\n",imag(TrapezIntegral(N,G0,omega))); get_As(); get_Ps(); get_SOCSigma(); V[0] = mu; if (HalfFilling)//and (SymmetricCase)) { if (IsBethe) { get_Sigma(); get_G(); //get_G() !!!! samo proba // printf(" Integral G = %.6f\n",imag(TrapezIntegral(N,G,omega))); } else get_G_CHM(); } else { if (IsBethe) UseBroyden<SIAM>(1, MAX_ITS, Accr, &SIAM::get_G, this, V); else UseBroyden<SIAM>(1, MAX_ITS, Accr, &SIAM::get_G_CHM, this, V); } MPT_B = get_MPT_B(); MPT_B0 = get_MPT_B0(); printf(" mu = %f\n", mu); delete [] V; //-----------------------------------------------------// //output spectral weight if optioned if (CheckSpectralWeight) { printf(" Spectral weight G: %fe\n", -imag(TrapezIntegral(N,G,omega))/pi); printf(" Spectral weight G0: %fe\n", -imag(TrapezIntegral(N,G0,omega))/pi); } //-------- OUTPUT ---------// for (int i=0; i<N; i++) { G_out[i] = G[i]; Sigma_out[i] = Sigma[i]; } mu_out = mu; //-------------------------// // printf(" PROVERA: n = %f, U = %f \n",n, U); return Clipped; }
bool SIAM::Run_CHM(Result* r) //output { this->r = r; N = r->grid->get_N(); grid = r->grid; get_fermi(); Clipped = false; epsilon = 0; if (r->n==0.5) HalfFilling = true; else HalfFilling = false; printf(" ------- SIAM for CHM: n=%.3f, U=%.3f, T=%.3f, epsilon=%.3f -------\n", r->n, U, T, epsilon); if (HalfFilling) { r->mu = 0.5*U; mu0 = 0.0; MPT_B = 0.0; MPT_B0 = 0.0; SymmetricCase = true; } //------initial guess---------// complex<double>* V = new complex<double>[1]; V[0] = mu0; //initial guess is always the last mu0. in first DMFT iteration it is 0 //---------------------------// printf(" MPT: B = %fe, B0 = %fe\n", MPT_B, MPT_B0); //----------------- CALCULATION ----------------------// if (HalfFilling)//and (SymmetricCase)) get_G0(); else UseBroyden<SIAM>(1, MAX_ITS, Accr, &SIAM::get_G0, this, V); printf(" mu0 = %f\n", mu0); get_As(); get_Ps(); get_SOCSigma(); V[0] = r->mu; if (HalfFilling)//and (SymmetricCase)) { if (isBethe) { get_Sigma(); get_G(); } else get_G_CHM(); } else { if (isBethe) UseBroyden<SIAM>(1, MAX_ITS, Accr, &SIAM::get_G, this, V); else UseBroyden<SIAM>(1, MAX_ITS, Accr, &SIAM::get_G_CHM, this, V); } MPT_B = get_MPT_B(); MPT_B0 = get_MPT_B0(); printf(" mu = %f\n", r->mu); delete [] V; //-----------------------------------------------------// //output spectral weight if optioned if (CheckSpectralWeight) { printf(" n0: %.6f\n", get_n(r->G0)); printf(" n: %.6f\n", get_n(r->G)); } // fill in DOS #pragma omp parallel for for (int i=0; i<N; i++) r->DOS[i] = - imag(r->G[i]) / pi; r->mu0 = mu0; return false; }