TQpResidual.cxx

Go to the documentation of this file.
00001 // @(#)root/quadp:$Id: TQpResidual.cxx 35018 2010-08-25 16:40:46Z moneta $
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 // TQpResidual                                                          //
00046 //                                                                      //
00047 // The Residuals class calculates and stores the quantities that appear //
00048 // on the right-hand side of the linear systems that arise at each      // 
00049 // interior-point iteration. These residuals can be partitioned into    //
00050 // two fundamental categories: the components arising from the linear   //
00051 // equations in the KKT conditions, and the components arising from the //
00052 // complementarity conditions.                                          //
00053 //                                                                      //
00054 //////////////////////////////////////////////////////////////////////////
00055 
00056 #include "Riostream.h"
00057 #include "TQpResidual.h"
00058 #include "TMatrixD.h"
00059 
00060 ClassImp(TQpResidual)
00061 
00062 //______________________________________________________________________________
00063 TQpResidual::TQpResidual()
00064 {
00065 // Constructor
00066 
00067    fNx   = 0;
00068    fMy   = 0;
00069    fMz   = 0;
00070 
00071    fNxup = 0.0;
00072    fNxlo = 0.0;
00073    fMcup = 0.0;
00074    fMclo = 0.0;
00075    fResidualNorm = 0.0;
00076    fDualityGap = 0.0;
00077 }
00078 
00079 
00080 //______________________________________________________________________________
00081 TQpResidual::TQpResidual(Int_t nx,Int_t my,Int_t mz,TVectorD &ixlo,TVectorD &ixup,
00082                          TVectorD &iclo,TVectorD &icup)
00083 {
00084 // Constructor
00085 
00086    fNx = nx;
00087    fMy = my;
00088    fMz = mz;
00089 
00090    if (ixlo.GetNrows() > 0) fXloIndex.Use(ixlo.GetNrows(),ixlo.GetMatrixArray());
00091    if (ixup.GetNrows() > 0) fXupIndex.Use(ixup.GetNrows(),ixup.GetMatrixArray());
00092    if (iclo.GetNrows() > 0) fCloIndex.Use(iclo.GetNrows(),iclo.GetMatrixArray());
00093    if (icup.GetNrows() > 0) fCupIndex.Use(icup.GetNrows(),icup.GetMatrixArray());
00094    fNxlo = ixlo.NonZeros();
00095    fNxup = ixup.NonZeros();
00096    fMclo = iclo.NonZeros();
00097    fMcup = icup.NonZeros();
00098 
00099    fRQ.ResizeTo(fNx);
00100    fRA.ResizeTo(fMy);
00101    fRC.ResizeTo(fMz);
00102 
00103    fRz.ResizeTo(fMz);
00104    if (fMclo > 0) {
00105       fRt.ResizeTo(fMz);
00106       fRlambda.ResizeTo(fMz);
00107    }
00108    if (fMcup > 0) {
00109       fRu.ResizeTo(fMz);
00110       fRpi.ResizeTo(fMz);
00111    }
00112    if (fNxlo > 0) {
00113       fRv.ResizeTo(fNx);
00114       fRgamma.ResizeTo(fNx);
00115    }
00116    if (fNxup > 0) {
00117       fRw.ResizeTo(fNx);
00118       fRphi.ResizeTo(fNx);
00119    }
00120 
00121    fResidualNorm = 0.0;
00122    fDualityGap = 0.0;
00123 }
00124 
00125 
00126 //______________________________________________________________________________
00127 TQpResidual::TQpResidual(const TQpResidual &another) : TObject(another)
00128 {
00129 // Copy constructor
00130 
00131    *this = another;
00132 }
00133 
00134 
00135 //______________________________________________________________________________
00136 void TQpResidual::CalcResids(TQpDataBase *prob_in,TQpVar *vars)
00137 {
00138 // Calculate residuals, their norms, and duality complementarity gap,
00139 // given a problem and variable set.
00140 
00141    TQpDataDens *prob = (TQpDataDens *) prob_in;
00142 
00143    fRQ.ResizeTo(prob->fG); fRQ = prob->fG;
00144    prob->Qmult(1.0,fRQ,1.0,vars->fX);
00145 
00146    // calculate x^T (g+Qx) - contribution to the duality gap
00147    Double_t gap = fRQ*vars->fX;
00148 
00149    prob->ATransmult(1.0,fRQ,-1.0,vars->fY);
00150    prob->CTransmult(1.0,fRQ,-1.0,vars->fZ);
00151    if (fNxlo > 0) Add(fRQ,-1.0,vars->fGamma);
00152    if (fNxup > 0) Add(fRQ, 1.0,vars->fPhi);
00153 
00154    Double_t norm = 0.0;
00155    Double_t componentNorm = fRQ.NormInf();
00156    if (componentNorm > norm) norm = componentNorm;
00157 
00158    fRA.ResizeTo(prob->fBa); fRA = prob->fBa;
00159    prob->Amult(-1.0,fRA,1.0,vars->fX);
00160 
00161    // contribution -d^T y to duality gap
00162    gap -= prob->fBa*vars->fY;
00163 
00164    componentNorm = fRA.NormInf();
00165    if( componentNorm > norm ) norm = componentNorm;
00166 
00167    fRC.ResizeTo(vars->fS); fRC = vars->fS;
00168    prob->Cmult(-1.0,fRC,1.0,vars->fX);
00169 
00170    componentNorm = fRC.NormInf();
00171    if( componentNorm > norm ) norm = componentNorm;
00172 
00173    fRz.ResizeTo(vars->fZ); fRz = vars->fZ;
00174 
00175    if (fMclo > 0) {
00176       Add(fRz,-1.0,vars->fLambda);
00177 
00178       fRt.ResizeTo(vars->fS); fRt = vars->fS;
00179       Add(fRt,-1.0,prob->GetSlowerBound());
00180       fRt.SelectNonZeros(fCloIndex);
00181       Add(fRt,-1.0,vars->fT);
00182 
00183       gap -= prob->fCloBound*vars->fLambda;
00184 
00185       componentNorm = fRt.NormInf();
00186       if( componentNorm > norm ) norm = componentNorm;
00187    }
00188 
00189    if (fMcup > 0) {
00190       Add(fRz,1.0,vars->fPi);
00191 
00192       fRu.ResizeTo(vars->fS); fRu = vars->fS;
00193       Add(fRu,-1.0,prob->GetSupperBound() );
00194       fRu.SelectNonZeros(fCupIndex);
00195       Add(fRu,1.0,vars->fU);
00196 
00197       gap += prob->fCupBound*vars->fPi;
00198 
00199       componentNorm = fRu.NormInf();
00200       if( componentNorm > norm ) norm = componentNorm;
00201    }
00202 
00203    componentNorm = fRz.NormInf();
00204    if( componentNorm > norm ) norm = componentNorm;
00205 
00206    if (fNxlo > 0) {
00207       fRv.ResizeTo(vars->fX); fRv = vars->fX;
00208       Add(fRv,-1.0,prob->GetXlowerBound());
00209       fRv.SelectNonZeros(fXloIndex);
00210       Add(fRv,-1.0,vars->fV);
00211 
00212       gap -= prob->fXloBound*vars->fGamma;
00213 
00214       componentNorm = fRv.NormInf();
00215       if( componentNorm > norm ) norm = componentNorm;
00216    }
00217 
00218    if (fNxup > 0) {
00219       fRw.ResizeTo(vars->fX); fRw = vars->fX;
00220       Add(fRw,-1.0,prob->GetXupperBound());
00221       fRw.SelectNonZeros(fXupIndex);
00222       Add(fRw,1.0,vars->fW);
00223 
00224       gap += prob->fXupBound*vars->fPhi;
00225 
00226       componentNorm = fRw.NormInf();
00227       if (componentNorm > norm) norm = componentNorm;
00228    }
00229 
00230    fDualityGap   = gap;
00231    fResidualNorm = norm;
00232 }
00233 
00234 
00235 //______________________________________________________________________________
00236 void TQpResidual::Add_r3_xz_alpha(TQpVar *vars,Double_t alpha)
00237 {
00238 // Modify the "complementarity" component of the residuals, by adding the pairwise
00239 // products of the complementary variables plus a constant alpha to this term.
00240 
00241    if (fMclo > 0) AddElemMult(fRlambda,1.0,vars->fT,vars->fLambda);
00242    if (fMcup > 0) AddElemMult(fRpi    ,1.0,vars->fU,vars->fPi);
00243    if (fNxlo > 0) AddElemMult(fRgamma ,1.0,vars->fV,vars->fGamma);
00244    if (fNxup > 0) AddElemMult(fRphi   ,1.0,vars->fW,vars->fPhi);
00245 
00246    if (alpha != 0.0) {
00247       if (fMclo > 0) fRlambda.AddSomeConstant(alpha,fCloIndex);
00248       if (fMcup > 0) fRpi    .AddSomeConstant(alpha,fCupIndex);
00249       if (fNxlo > 0) fRgamma .AddSomeConstant(alpha,fXloIndex);
00250       if (fNxup > 0) fRphi   .AddSomeConstant(alpha,fXupIndex);
00251    }
00252 }
00253 
00254 
00255 //______________________________________________________________________________
00256 void TQpResidual::Set_r3_xz_alpha(TQpVar *vars,Double_t alpha)
00257 {
00258 // Set the "complementarity" component of the residuals to the pairwise products of
00259 // the complementary variables plus a constant alpha .
00260 
00261    this->Clear_r3();
00262    this->Add_r3_xz_alpha(vars,alpha);
00263 }
00264 
00265 
00266 //______________________________________________________________________________
00267 void TQpResidual::Clear_r3()
00268 {
00269 // set the complementarity component of the residuals to 0.
00270 
00271    if (fMclo > 0) fRlambda.Zero();
00272    if (fMcup > 0) fRpi    .Zero();
00273    if (fNxlo > 0) fRgamma .Zero();
00274    if (fNxup > 0) fRphi   .Zero();
00275 }
00276 
00277 
00278 //______________________________________________________________________________
00279 void TQpResidual::Clear_r1r2()
00280 {
00281 // set the noncomplementarity components of the residual (the terms arising from
00282 // the linear equalities in the KKT conditions) to 0.
00283 
00284    fRQ.Zero();
00285    fRA.Zero();
00286    fRC.Zero();
00287    fRz.Zero();
00288    if (fNxlo > 0) fRv.Zero();
00289    if (fNxup > 0) fRw.Zero();
00290    if (fMclo > 0) fRt.Zero();
00291    if (fMcup > 0) fRu.Zero();
00292 }
00293 
00294 
00295 //______________________________________________________________________________
00296 void TQpResidual::Project_r3(Double_t rmin,Double_t rmax)
00297 {
00298 // Perform the projection operation required by Gondzio algorithm: replace each
00299 // component r3_i of the complementarity component of the residuals by r3p_i-r3_i,
00300 // where r3p_i is the projection of r3_i onto the box [rmin, rmax]. Then if the
00301 // resulting value is less than -rmax, replace it by -rmax.
00302 
00303    if (fMclo > 0) {
00304       GondzioProjection(fRlambda,rmin,rmax);
00305       fRlambda.SelectNonZeros(fCloIndex);
00306    }
00307    if (fMcup > 0) {
00308       GondzioProjection(fRpi,rmin,rmax);
00309       fRpi.SelectNonZeros(fCupIndex);
00310    }
00311    if (fNxlo > 0) {
00312       GondzioProjection(fRgamma,rmin,rmax);
00313       fRgamma.SelectNonZeros(fXloIndex);
00314    }
00315    if (fNxup > 0) {
00316       GondzioProjection(fRphi,rmin,rmax);
00317       fRphi.SelectNonZeros(fXupIndex);
00318    }
00319 }
00320 
00321 
00322 //______________________________________________________________________________
00323 Bool_t TQpResidual::ValidNonZeroPattern()
00324 {
00325 // Check if vector elements as selected through array indices are non-zero
00326 
00327    if (fNxlo > 0 &&
00328       (!fRv    .MatchesNonZeroPattern(fXloIndex) ||
00329        !fRgamma.MatchesNonZeroPattern(fXloIndex)) ) {
00330       return kFALSE;
00331    }
00332 
00333    if (fNxup > 0 &&
00334       (!fRw  .MatchesNonZeroPattern(fXupIndex) ||
00335        !fRphi.MatchesNonZeroPattern(fXupIndex)) ) {
00336       return kFALSE;
00337    }
00338    if (fMclo > 0 &&
00339       (!fRt     .MatchesNonZeroPattern(fCloIndex) ||
00340        !fRlambda.MatchesNonZeroPattern(fCloIndex)) ) {
00341       return kFALSE;
00342    }
00343 
00344    if (fMcup > 0 &&
00345       (!fRu .MatchesNonZeroPattern(fCupIndex) ||
00346        !fRpi.MatchesNonZeroPattern(fCupIndex)) ) {
00347       return kFALSE;
00348    }
00349 
00350    return kTRUE;
00351 }
00352 
00353 
00354 //______________________________________________________________________________
00355 void TQpResidual::GondzioProjection(TVectorD &v,Double_t rmin,Double_t rmax)
00356 {
00357 // Replace each component r3_i of the complementarity component of the residuals
00358 // by r3p_i-r3_i, where r3p_i is the projection of r3_i onto the box [rmin, rmax].
00359 // Then if the resulting value is less than -rmax, replace it by -rmax.
00360 
00361          Double_t *        ep = v.GetMatrixArray();
00362    const Double_t * const fep = ep+v.GetNrows();
00363 
00364    while (ep < fep) {
00365       if (*ep < rmin)
00366          *ep = rmin - *ep;
00367       else if (*ep > rmax)
00368          *ep = rmax - *ep;
00369       else
00370          *ep = 0.0;
00371       if (*ep < -rmax) *ep = -rmax;
00372       ep++;
00373    }
00374 }
00375 
00376 
00377 //______________________________________________________________________________
00378 TQpResidual &TQpResidual::operator=(const TQpResidual &source)
00379 {
00380 // Assignment operator
00381 
00382    if (this != &source) {
00383       TObject::operator=(source);
00384 
00385       fNx   = source.fNx;
00386       fMy   = source.fMy;
00387       fMz   = source.fMz;
00388 
00389       fNxup = source.fNxup;
00390       fNxlo = source.fNxlo;
00391       fMcup = source.fMcup;
00392       fMclo = source.fMclo;
00393 
00394       fXupIndex.ResizeTo(source.fXupIndex); fXupIndex = source.fXupIndex;
00395       fXloIndex.ResizeTo(source.fXloIndex); fXloIndex = source.fXloIndex;
00396       fCupIndex.ResizeTo(source.fCupIndex); fCupIndex = source.fCupIndex;
00397       fCloIndex.ResizeTo(source.fCloIndex); fCupIndex = source.fCupIndex;
00398 
00399       fRQ     .ResizeTo(source.fRQ);      fRQ      = source.fRQ;
00400       fRA     .ResizeTo(source.fRA);      fRA      = source.fRA;
00401       fRC     .ResizeTo(source.fRC);      fRC      = source.fRC;
00402       fRz     .ResizeTo(source.fRz);      fRz      = source.fRz;
00403       fRv     .ResizeTo(source.fRv);      fRv      = source.fRv;
00404       fRw     .ResizeTo(source.fRw);      fRw      = source.fRw;
00405       fRt     .ResizeTo(source.fRt);      fRt      = source.fRt;
00406       fRu     .ResizeTo(source.fRu);      fRu      = source.fRu;
00407       fRgamma .ResizeTo(source.fRgamma);  fRgamma  = source.fRgamma;
00408       fRphi   .ResizeTo(source.fRphi);    fRphi    = source.fRphi;
00409       fRlambda.ResizeTo(source.fRlambda); fRlambda = source.fRlambda;
00410       fRpi    .ResizeTo(source.fRpi);     fRpi     = source.fRpi;
00411 
00412       // LM: copy also these data members
00413       fResidualNorm = source.fResidualNorm;
00414       fDualityGap = source.fDualityGap;
00415    }
00416    return *this;
00417 }

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