#include "Riostream.h"
#include "TMath.h"
#include "TGondzioSolver.h"
#include "TQpLinSolverDens.h"
ClassImp(TGondzioSolver)
TGondzioSolver::TGondzioSolver()
{
fPrintlevel = 0;
fTsig = 0.0;
fMaximum_correctors = 0;
fNumberGondzioCorrections = 0;
fStepFactor0 = 0.0;
fStepFactor1 = 0.0;
fAcceptTol = 0.0;
fBeta_min = 0.0;
fBeta_max = 0.0;
fCorrector_step = 0;
fStep = 0;
fCorrector_resid = 0;
fFactory = 0;
}
TGondzioSolver::TGondzioSolver(TQpProbBase *of,TQpDataBase *prob,Int_t verbose)
{
fFactory = of;
fStep = fFactory->MakeVariables(prob);
fCorrector_step = fFactory->MakeVariables(prob);
fCorrector_resid = fFactory->MakeResiduals(prob);
fPrintlevel = verbose;
fTsig = 3.0;
fMaximum_correctors = 3;
fNumberGondzioCorrections = 0;
fStepFactor0 = 0.08;
fStepFactor1 = 1.08;
fAcceptTol = 0.005;
fBeta_min = 0.1;
fBeta_max = 10.0;
}
TGondzioSolver::TGondzioSolver(const TGondzioSolver &another) : TQpSolverBase(another)
{
*this = another;
}
Int_t TGondzioSolver::Solve(TQpDataBase *prob,TQpVar *iterate,TQpResidual *resid)
{
Int_t status_code;
Double_t alpha = 1;
Double_t sigma = 1;
fDnorm = prob->DataNorm();
fSys = fFactory->MakeLinSys(prob);
this->Start(fFactory,iterate,prob,resid,fStep);
fIter = 0;
fNumberGondzioCorrections = 0;
Double_t mu = iterate->GetMu();
Int_t done = 0;
do {
fIter++;
resid->CalcResids(prob,iterate);
status_code = this->DoStatus(prob,iterate,resid,fIter,mu,0);
if (status_code != kNOT_FINISHED ) break;
if (fPrintlevel >= 10)
this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,0);
resid->Set_r3_xz_alpha(iterate,0.0);
fSys->Factor(prob,iterate);
fSys->Solve(prob,iterate,resid,fStep);
fStep->Negate();
alpha = iterate->StepBound(fStep);
Double_t muaff = iterate->MuStep(fStep,alpha);
sigma = TMath::Power(muaff/mu,fTsig);
if (fPrintlevel >= 10)
this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,2);
resid->Add_r3_xz_alpha(fStep,-sigma*mu);
fSys->Solve(prob,iterate,resid,fStep);
fStep->Negate();
alpha = iterate->StepBound(fStep);
fCorrector_resid->Clear_r1r2();
Double_t rmin = sigma*mu*fBeta_min;
Double_t rmax = sigma*mu*fBeta_max;
Int_t stopCorrections = 0;
fNumberGondzioCorrections = 0;
if (fPrintlevel >= 10)
cout << "**** Entering the correction loop ****" << endl;
while (fNumberGondzioCorrections < fMaximum_correctors &&
alpha < 1.0 && !stopCorrections) {
*fCorrector_step = *iterate;
Double_t alpha_target = fStepFactor1*alpha+fStepFactor0;
if (alpha_target > 1.0) alpha_target = 1.0;
fCorrector_step->Saxpy(fStep,alpha_target);
fCorrector_resid->Set_r3_xz_alpha(fCorrector_step,0.0);
fCorrector_resid->Project_r3(rmin,rmax);
fSys->Solve(prob,iterate,fCorrector_resid,fCorrector_step);
fCorrector_step->Saxpy(fStep,1.0);
Double_t alpha_enhanced = iterate->StepBound(fCorrector_step);
if (alpha_enhanced == 1.0) {
*fStep = *fCorrector_step;
alpha = alpha_enhanced;
fNumberGondzioCorrections++;
stopCorrections = 1;
}
else if(alpha_enhanced >= (1.0+fAcceptTol)*alpha) {
*fStep = *fCorrector_step;
alpha = alpha_enhanced;
fNumberGondzioCorrections++;
stopCorrections = 0;
}
else {
stopCorrections = 1;
}
}
alpha = this->FinalStepLength(iterate,fStep);
iterate->Saxpy(fStep,alpha);
mu = iterate->GetMu();
} while (!done);
resid->CalcResids(prob,iterate);
if (fPrintlevel >= 10)
this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,1);
return status_code;
}
void TGondzioSolver::DefMonitor(TQpDataBase* ,TQpVar* ,
TQpResidual *resid,
Double_t alpha,Double_t sigma,Int_t i,Double_t mu,
Int_t status_code,Int_t level)
{
switch (level) {
case 0 : case 1:
{
cout << endl << "Duality Gap: " << resid->GetDualityGap() << endl;
if (i > 1) {
cout << " Number of Corrections = " << fNumberGondzioCorrections
<< " alpha = " << alpha << endl;
}
cout << " *** Iteration " << i << " *** " << endl;
cout << " mu = " << mu << " relative residual norm = "
<< resid->GetResidualNorm()/fDnorm << endl;
if (level == 1) {
if (status_code == kSUCCESSFUL_TERMINATION) {
cout << endl
<< " *** SUCCESSFUL TERMINATION ***"
<< endl;
}
else if (status_code == kMAX_ITS_EXCEEDED) {
cout << endl
<< " *** MAXIMUM ITERATIONS REACHED *** " << endl;
}
else if (status_code == kINFEASIBLE) {
cout << endl
<< " *** TERMINATION: PROBABLY INFEASIBLE *** "
<< endl;
}
else if (status_code == kUNKNOWN) {
cout << endl
<< " *** TERMINATION: STATUS UNKNOWN *** " << endl;
}
}
} break;
case 2:
cout << " *** sigma = " << sigma << endl;
break;
}
}
TGondzioSolver::~TGondzioSolver()
{
if (fCorrector_step) { delete fCorrector_step; fCorrector_step = 0; }
if (fStep) { delete fStep; fStep = 0; }
if (fCorrector_resid) { delete fCorrector_resid; fCorrector_resid = 0; }
}
TGondzioSolver &TGondzioSolver::operator=(const TGondzioSolver &source)
{
if (this != &source) {
TQpSolverBase::operator=(source);
fPrintlevel = source.fPrintlevel;
fTsig = source.fTsig ;
fMaximum_correctors = source.fMaximum_correctors;
fNumberGondzioCorrections = source.fNumberGondzioCorrections;
fStepFactor0 = source.fStepFactor0;
fStepFactor1 = source.fStepFactor1;
fAcceptTol = source.fAcceptTol;
fBeta_min = source.fBeta_min;
fBeta_max = source.fBeta_max;
if (fCorrector_step) delete fCorrector_step;
if (fStep) delete fStep;
if (fCorrector_resid) delete fCorrector_resid;
fCorrector_step = new TQpVar(*source.fCorrector_step);
fStep = new TQpVar(*source.fStep);
fCorrector_resid = new TQpResidual(*source.fCorrector_resid);
fFactory = source.fFactory;
}
return *this;
}
Last change: Wed Jun 25 08:46:03 2008
Last generated: 2008-06-25 08:46
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.