#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;
}
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.