TMehrotraSolver.cxx

Go to the documentation of this file.
00001 // @(#)root/quadp:$Id: TMehrotraSolver.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 // TMehrotraSolver                                                      //
00046 //                                                                      //
00047 // Derived class of TQpSolverBase implementing the original Mehrotra    //
00048 // predictor-corrector algorithm                                        //
00049 //                                                                      //
00050 //////////////////////////////////////////////////////////////////////////
00051 
00052 #include "Riostream.h"
00053 #include "TMath.h"
00054 #include "TMehrotraSolver.h"
00055 
00056 ClassImp(TMehrotraSolver)
00057 
00058 //______________________________________________________________________________
00059 TMehrotraSolver::TMehrotraSolver()
00060 {
00061 // Default constructor
00062 
00063    fPrintlevel = 0;
00064    fTsig       = 0.0;
00065    fStep       = 0;
00066    fFactory    = 0;
00067 }
00068 
00069 
00070 //______________________________________________________________________________
00071 TMehrotraSolver::TMehrotraSolver(TQpProbBase *of,TQpDataBase *prob,Int_t verbose)
00072 {
00073 // Constructor
00074 
00075    fFactory = of;
00076    fStep = fFactory->MakeVariables(prob);
00077 
00078    fPrintlevel = verbose;
00079    fTsig       = 3.0;            // the usual value for the centering exponent (tau)
00080 }
00081 
00082 
00083 //______________________________________________________________________________
00084 TMehrotraSolver::TMehrotraSolver(const TMehrotraSolver &another) : TQpSolverBase(another)
00085 {
00086 // Copy constructor
00087 
00088    *this = another;
00089 }
00090 
00091 
00092 //______________________________________________________________________________
00093 Int_t TMehrotraSolver::Solve(TQpDataBase *prob,TQpVar *iterate,TQpResidual *resid)
00094 {
00095 // Solve the quadratic programming problem as formulated through prob, store
00096 // the final solution in iterate->fX . Monitor the residuals during the iterations
00097 // through resid . The status is returned as defined in TQpSolverBase::ETerminationCode .
00098 
00099    Int_t status_code;
00100    Double_t alpha = 1;
00101    Double_t sigma = 1;
00102 
00103    fDnorm = prob->DataNorm();
00104 
00105    // initialization of (x,y,z) and factorization routine.
00106    fSys = fFactory->MakeLinSys(prob);
00107    this->Start(fFactory,iterate,prob,resid,fStep);
00108 
00109    fIter = 0;
00110    Double_t mu = iterate->GetMu();
00111 
00112    Int_t done = 0;
00113    do {
00114       fIter++;
00115 
00116       // evaluate residuals and update algorithm status:
00117       resid->CalcResids(prob,iterate);
00118 
00119       //  termination test:
00120       status_code = this->DoStatus(prob,iterate,resid,fIter,mu,0);
00121       if (status_code != kNOT_FINISHED ) break;
00122       if (fPrintlevel >= 10)
00123          this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,0);
00124 
00125       // *** Predictor step ***
00126 
00127       resid->Set_r3_xz_alpha(iterate,0.0);
00128 
00129       fSys->Factor(prob,iterate);
00130       fSys->Solve(prob,iterate,resid,fStep);
00131       fStep->Negate();
00132 
00133       alpha = iterate->StepBound(fStep);
00134 
00135       // calculate centering parameter
00136       Double_t muaff = iterate->MuStep(fStep,alpha);
00137       sigma = TMath::Power(muaff/mu,fTsig);
00138 
00139       // *** Corrector step ***
00140 
00141       // form right hand side of linear system:
00142       resid->Add_r3_xz_alpha(fStep,-sigma*mu );
00143 
00144       fSys->Solve(prob,iterate,resid,fStep);
00145       fStep->Negate();
00146 
00147       // We've finally decided on a step direction, now calculate the
00148       // length using Mehrotra's heuristic.
00149       alpha = this->FinalStepLength(iterate,fStep);
00150 
00151       // alternatively, just use a crude step scaling factor.
00152       //alpha = 0.995 * iterate->StepBound(fStep);
00153 
00154       // actually take the step and calculate the new mu
00155       iterate->Saxpy(fStep,alpha);
00156       mu = iterate->GetMu();
00157    } while(!done);
00158 
00159    resid->CalcResids(prob,iterate);
00160    if (fPrintlevel >= 10)
00161       this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,1);
00162 
00163    return status_code;
00164 }
00165 
00166 
00167 //______________________________________________________________________________
00168 void TMehrotraSolver::DefMonitor(TQpDataBase * /* data */,TQpVar * /* vars */,
00169                                  TQpResidual *resids,
00170                                  Double_t alpha,Double_t /* sigma */,Int_t i,Double_t mu,
00171                                  Int_t status_code,Int_t level)
00172 {
00173 // Print information about the optimization process and monitor the convergence
00174 // status of thye algorithm
00175 
00176    switch (level) {
00177       case 0 : case 1:
00178       {
00179          cout << endl << "Duality Gap: " << resids->GetDualityGap() << endl;
00180          if (i > 1) {
00181             cout << " alpha = " << alpha << endl;
00182          }
00183          cout << " *** Iteration " << i << " *** " << endl;
00184          cout << " mu = " << mu << " relative residual norm = "
00185             << resids->GetResidualNorm()/fDnorm << endl;
00186 
00187          if (level == 1) {
00188             // Termination has been detected by the status check; print
00189             // appropriate message
00190             switch (status_code) {
00191                case kSUCCESSFUL_TERMINATION:
00192                   cout << endl << " *** SUCCESSFUL TERMINATION ***" << endl;
00193                   break;
00194                case kMAX_ITS_EXCEEDED:
00195                   cout << endl << " *** MAXIMUM ITERATIONS REACHED *** " << endl;
00196                   break;
00197                case kINFEASIBLE:
00198                   cout << endl << " *** TERMINATION: PROBABLY INFEASIBLE *** " << endl;
00199                   break;
00200                case kUNKNOWN:
00201                   cout << endl << " *** TERMINATION: STATUS UNKNOWN *** " << endl;
00202                   break;
00203             }
00204          }
00205       } break;                   // end case 0: case 1:
00206    }                             // end switch(level)
00207 }
00208 
00209 
00210 //______________________________________________________________________________
00211 TMehrotraSolver::~TMehrotraSolver()
00212 {
00213 // Deconstructor
00214 
00215    delete fStep;
00216 }
00217 
00218 
00219 //______________________________________________________________________________
00220 TMehrotraSolver &TMehrotraSolver::operator=(const TMehrotraSolver &source)
00221 {
00222 // Assignment operator
00223 
00224    if (this != &source) {
00225       TQpSolverBase::operator=(source);
00226 
00227       fPrintlevel = source.fPrintlevel;
00228       fTsig       = source.fTsig;
00229 
00230       if (fStep) delete fStep;
00231 
00232       fStep    = new TQpVar(*source.fStep);
00233       fFactory = source.fFactory;
00234    }
00235    return *this;
00236 }

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