MatrixXd MultivariateFNormalSufficient::get_PW() const { if (!flag_PW_) { ////PW timer_.start(SOLVE); MatrixXd PW(M_,M_); if (N_==1) { IMP_LOG(TERSE, "MVN: W=0 => PW=0" << std::endl); PW.setZero(); } else { IMP_LOG(TERSE, "MVN: solving for PW" << std::endl); if (use_cg_) { if (first_PW_) { PW = compute_PW_direct(); (*const_cast<bool *>(&first_PW_))=false; } else { PW = compute_PW_cg(); } } else { PW = compute_PW_direct(); } } const_cast<MultivariateFNormalSufficient *>(this)->set_PW(PW); timer_.stop(SOLVE); } return PW_; }
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; }
MatrixXd MultivariateFNormalSufficient::get_PW() const { if (!flag_PW_) { ////PW MatrixXd PW(M_,M_); if (N_==1) { LOG( "MVN: W=0 => PW=0" << std::endl); PW.setZero(); } else { LOG( "MVN: solving for PW" << std::endl); PW = compute_PW_direct(); } const_cast<MultivariateFNormalSufficient *>(this)->set_PW(PW); } return PW_; }