TGondzioSolver.cxx

Go to the documentation of this file.
00001 // @(#)root/quadp:$Id: TGondzioSolver.cxx 20882 2007-11-19 11:31:26Z rdm $
00002 // Author: Eddy Offermann   May 2004
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 /*************************************************************************
00013  * Parts of this file are copied from the OOQP distribution and          *
00014  * are subject to the following license:                                 *
00015  *                                                                       *
00016  * COPYRIGHT 2001 UNIVERSITY OF CHICAGO                                  *
00017  *                                                                       *
00018  * The copyright holder hereby grants you royalty-free rights to use,    *
00019  * reproduce, prepare derivative works, and to redistribute this software*
00020  * to others, provided that any changes are clearly documented. This     *
00021  * software was authored by:                                             *
00022  *                                                                       *
00023  *   E. MICHAEL GERTZ      gertz@mcs.anl.gov                             *
00024  *   Mathematics and Computer Science Division                           *
00025  *   Argonne National Laboratory                                         *
00026  *   9700 S. Cass Avenue                                                 *
00027  *   Argonne, IL 60439-4844                                              *
00028  *                                                                       *
00029  *   STEPHEN J. WRIGHT     swright@cs.wisc.edu                           *
00030  *   Computer Sciences Department                                        *
00031  *   University of Wisconsin                                             *
00032  *   1210 West Dayton Street                                             *
00033  *   Madison, WI 53706   FAX: (608)262-9777                              *
00034  *                                                                       *
00035  * Any questions or comments may be directed to one of the authors.      *
00036  *                                                                       *
00037  * ARGONNE NATIONAL LABORATORY (ANL), WITH FACILITIES IN THE STATES OF   *
00038  * ILLINOIS AND IDAHO, IS OWNED BY THE UNITED STATES GOVERNMENT, AND     *
00039  * OPERATED BY THE UNIVERSITY OF CHICAGO UNDER PROVISION OF A CONTRACT   *
00040  * WITH THE DEPARTMENT OF ENERGY.                                        *
00041  *************************************************************************/
00042 
00043 //////////////////////////////////////////////////////////////////////////
00044 //                                                                      //
00045 // TGondzioSolver                                                       //
00046 //                                                                      //
00047 // Derived class of TQpSolverBase implementing Gondzio-correction       //
00048 // version of Mehrotra's original predictor-corrector algorithm.        //
00049 //                                                                      //
00050 //////////////////////////////////////////////////////////////////////////
00051 
00052 
00053 #include "Riostream.h"
00054 #include "TMath.h"
00055 #include "TGondzioSolver.h"
00056 #include "TQpLinSolverDens.h"
00057 
00058 ClassImp(TGondzioSolver)
00059 
00060 //______________________________________________________________________________
00061 TGondzioSolver::TGondzioSolver()
00062 {
00063 // Default constructor
00064 
00065    fPrintlevel               = 0;
00066    fTsig                     = 0.0;
00067    fMaximum_correctors       = 0;
00068    fNumberGondzioCorrections = 0;
00069 
00070    fStepFactor0 = 0.0;
00071    fStepFactor1 = 0.0;
00072    fAcceptTol   = 0.0;
00073    fBeta_min    = 0.0;
00074    fBeta_max    = 0.0;
00075 
00076    fCorrector_step  = 0;
00077    fStep            = 0;
00078    fCorrector_resid = 0;
00079    fFactory         = 0;
00080 }
00081 
00082 
00083 //______________________________________________________________________________
00084 TGondzioSolver::TGondzioSolver(TQpProbBase *of,TQpDataBase *prob,Int_t verbose)
00085 {
00086 // Constructor
00087 
00088    fFactory = of;
00089    fStep            = fFactory->MakeVariables(prob);
00090    fCorrector_step  = fFactory->MakeVariables(prob);
00091    fCorrector_resid = fFactory->MakeResiduals(prob);
00092 
00093    fPrintlevel = verbose;
00094    fTsig       = 3.0;            // the usual value for the centering exponent (tau)
00095 
00096    fMaximum_correctors = 3;      // maximum number of Gondzio correctors
00097 
00098    fNumberGondzioCorrections = 0;
00099 
00100    // the two StepFactor constants set targets for increase in step
00101    // length for each corrector
00102    fStepFactor0 = 0.08;
00103    fStepFactor1 = 1.08;
00104 
00105    // accept the enhanced step if it produces a small improvement in
00106    // the step length
00107    fAcceptTol = 0.005;
00108 
00109    //define the Gondzio correction box
00110    fBeta_min = 0.1;
00111    fBeta_max = 10.0;
00112 }
00113 
00114 
00115 //______________________________________________________________________________
00116 TGondzioSolver::TGondzioSolver(const TGondzioSolver &another) : TQpSolverBase(another)
00117 {
00118 // Copy constructor
00119 
00120    *this = another;
00121 }
00122 
00123 
00124 //______________________________________________________________________________
00125 Int_t TGondzioSolver::Solve(TQpDataBase *prob,TQpVar *iterate,TQpResidual *resid)
00126 {
00127 // Solve the quadratic programming problem as formulated through prob, store
00128 // the final solution in iterate->fX . Monitor the residuals during the iterations
00129 // through resid . The status is returned as defined in TQpSolverBase::ETerminationCode .
00130 
00131    Int_t status_code;
00132    Double_t alpha = 1;
00133    Double_t sigma = 1;
00134 
00135    fDnorm = prob->DataNorm();
00136 
00137    // initialization of (x,y,z) and factorization routine.
00138    fSys = fFactory->MakeLinSys(prob);
00139    this->Start(fFactory,iterate,prob,resid,fStep);
00140 
00141    fIter = 0;
00142    fNumberGondzioCorrections = 0;
00143    Double_t mu = iterate->GetMu();
00144 
00145    Int_t done = 0;
00146    do {
00147       fIter++;
00148       // evaluate residuals and update algorithm status:
00149       resid->CalcResids(prob,iterate);
00150 
00151       //  termination test:
00152       status_code = this->DoStatus(prob,iterate,resid,fIter,mu,0);
00153       if (status_code != kNOT_FINISHED ) break;
00154       if (fPrintlevel >= 10)
00155          this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,0);
00156 
00157       // *** Predictor step ***
00158 
00159       resid->Set_r3_xz_alpha(iterate,0.0);
00160 
00161       fSys->Factor(prob,iterate);
00162       fSys->Solve(prob,iterate,resid,fStep);
00163       fStep->Negate();
00164 
00165       alpha = iterate->StepBound(fStep);
00166 
00167       // calculate centering parameter
00168       Double_t muaff = iterate->MuStep(fStep,alpha);
00169       sigma = TMath::Power(muaff/mu,fTsig);
00170 
00171       if (fPrintlevel >= 10)
00172          this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,2);
00173 
00174       // *** Corrector step ***
00175 
00176       // form right hand side of linear system:
00177       resid->Add_r3_xz_alpha(fStep,-sigma*mu);
00178 
00179       fSys->Solve(prob,iterate,resid,fStep);
00180       fStep->Negate();
00181 
00182       // calculate distance to boundary along the Mehrotra
00183       // predictor-corrector step:
00184       alpha = iterate->StepBound(fStep);
00185 
00186       // prepare for Gondzio corrector loop: zero out the
00187       // corrector_resid structure:
00188       fCorrector_resid->Clear_r1r2();
00189 
00190       // calculate the target box:
00191       Double_t rmin = sigma*mu*fBeta_min;
00192       Double_t rmax = sigma*mu*fBeta_max;
00193 
00194       Int_t stopCorrections     = 0;
00195       fNumberGondzioCorrections = 0;
00196 
00197       // enter the Gondzio correction loop:
00198       if (fPrintlevel >= 10)
00199          cout << "**** Entering the correction loop ****" << endl;
00200 
00201       while (fNumberGondzioCorrections < fMaximum_correctors  &&
00202       alpha < 1.0 && !stopCorrections) {
00203 
00204          // copy current variables into fcorrector_step
00205          *fCorrector_step = *iterate;
00206 
00207          // calculate target steplength
00208          Double_t alpha_target = fStepFactor1*alpha+fStepFactor0;
00209          if (alpha_target > 1.0) alpha_target = 1.0;
00210 
00211          // add a step of this length to corrector_step
00212          fCorrector_step->Saxpy(fStep,alpha_target);
00213 
00214          // place XZ into the r3 component of corrector_resids
00215          fCorrector_resid->Set_r3_xz_alpha(fCorrector_step,0.0);
00216 
00217          // do the projection operation
00218          fCorrector_resid->Project_r3(rmin,rmax);
00219 
00220          // solve for corrector direction
00221          fSys->Solve(prob,iterate,fCorrector_resid,fCorrector_step);
00222 
00223          // add the current step to corrector_step, and calculate the
00224          // step to boundary along the resulting direction
00225          fCorrector_step->Saxpy(fStep,1.0);
00226          Double_t alpha_enhanced = iterate->StepBound(fCorrector_step);
00227 
00228          // if the enhanced step length is actually 1, make it official
00229          // and stop correcting
00230          if (alpha_enhanced == 1.0) {
00231             *fStep = *fCorrector_step;
00232             alpha = alpha_enhanced;
00233             fNumberGondzioCorrections++;
00234             stopCorrections = 1;
00235          }
00236          else if(alpha_enhanced >= (1.0+fAcceptTol)*alpha) {
00237             // if enhanced step length is significantly better than the
00238             // current alpha, make the enhanced step official, but maybe
00239             // keep correcting
00240             *fStep = *fCorrector_step;
00241             alpha = alpha_enhanced;
00242             fNumberGondzioCorrections++;
00243             stopCorrections = 0;
00244          }
00245          else {
00246             // otherwise quit the correction loop
00247             stopCorrections = 1;
00248          }
00249       }
00250 
00251       // We've finally decided on a step direction, now calculate the
00252       // length using Mehrotra's heuristic.x
00253       alpha = this->FinalStepLength(iterate,fStep);
00254 
00255       // alternatively, just use a crude step scaling factor.
00256       // alpha = 0.995 * iterate->StepBound(fStep);
00257 
00258       // actually take the step (at last!) and calculate the new mu
00259 
00260       iterate->Saxpy(fStep,alpha);
00261       mu = iterate->GetMu();
00262    } while (!done);
00263 
00264    resid->CalcResids(prob,iterate);
00265    if (fPrintlevel >= 10)
00266       this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,1);
00267 
00268    return status_code;
00269 }
00270 
00271 
00272 //______________________________________________________________________________
00273 void TGondzioSolver::DefMonitor(TQpDataBase* /* data */,TQpVar* /* vars */,
00274                                 TQpResidual *resid,
00275                                 Double_t alpha,Double_t sigma,Int_t i,Double_t mu,
00276                                 Int_t status_code,Int_t level)
00277 {
00278 // Print information about the optimization process and monitor the convergence
00279 // status of thye algorithm
00280 
00281    switch (level) {
00282       case 0 : case 1:
00283       {
00284          cout << endl << "Duality Gap: " << resid->GetDualityGap() << endl;
00285          if (i > 1) {
00286             cout << " Number of Corrections = " << fNumberGondzioCorrections
00287                << " alpha = " << alpha << endl;
00288          }
00289          cout << " *** Iteration " << i << " *** " << endl;
00290          cout << " mu = " << mu << " relative residual norm = "
00291             << resid->GetResidualNorm()/fDnorm << endl;
00292 
00293          if (level == 1) {
00294             // Termination has been detected by the status check; print
00295             // appropriate message
00296             if (status_code == kSUCCESSFUL_TERMINATION) {
00297                cout << endl
00298                   << " *** SUCCESSFUL TERMINATION ***"
00299                   << endl;
00300             }
00301             else if (status_code == kMAX_ITS_EXCEEDED) {
00302                cout << endl
00303                   << " *** MAXIMUM ITERATIONS REACHED *** " << endl;
00304             }
00305             else if (status_code == kINFEASIBLE) {
00306                cout << endl
00307                   << " *** TERMINATION: PROBABLY INFEASIBLE *** "
00308                   << endl;
00309             }
00310             else if (status_code == kUNKNOWN) {
00311                cout << endl
00312                   << " *** TERMINATION: STATUS UNKNOWN *** " << endl;
00313             }
00314          }
00315       } break;
00316       case 2:
00317          cout << " *** sigma = " << sigma << endl;
00318          break;
00319    }
00320 }
00321 
00322 
00323 //______________________________________________________________________________
00324 TGondzioSolver::~TGondzioSolver()
00325 {
00326 // Deconstructor
00327 
00328    if (fCorrector_step)  { delete fCorrector_step;  fCorrector_step  = 0; }
00329    if (fStep)            { delete fStep;            fStep            = 0; }
00330    if (fCorrector_resid) { delete fCorrector_resid; fCorrector_resid = 0; }
00331 }
00332 
00333 
00334 //______________________________________________________________________________
00335 TGondzioSolver &TGondzioSolver::operator=(const TGondzioSolver &source)
00336 {
00337 // Assignment operator
00338 
00339    if (this != &source) {
00340       TQpSolverBase::operator=(source);
00341 
00342       fPrintlevel               = source.fPrintlevel;
00343       fTsig                     = source.fTsig ;
00344       fMaximum_correctors       = source.fMaximum_correctors;
00345       fNumberGondzioCorrections = source.fNumberGondzioCorrections;
00346 
00347       fStepFactor0 = source.fStepFactor0;
00348       fStepFactor1 = source.fStepFactor1;
00349       fAcceptTol   = source.fAcceptTol;
00350       fBeta_min    = source.fBeta_min;
00351       fBeta_max    = source.fBeta_max;
00352 
00353       if (fCorrector_step)  delete fCorrector_step;
00354       if (fStep)            delete fStep;
00355       if (fCorrector_resid) delete fCorrector_resid;
00356 
00357       fCorrector_step  = new TQpVar(*source.fCorrector_step);
00358       fStep            = new TQpVar(*source.fStep);
00359       fCorrector_resid = new TQpResidual(*source.fCorrector_resid);
00360       fFactory         = source.fFactory;
00361    }
00362    return *this;
00363 }

Generated on Tue Jul 5 14:37:58 2011 for ROOT_528-00b_version by  doxygen 1.5.1