TQpVar.cxx

Go to the documentation of this file.
00001 // @(#)root/quadp:$Id: TQpVar.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 // Class containing the variables for the general QP formulation         //
00046 //                                                                       //
00047 ///////////////////////////////////////////////////////////////////////////
00048 
00049 #include "Riostream.h"
00050 #include "TQpVar.h"
00051 #include "TMatrixD.h"
00052 
00053 ClassImp(TQpVar)
00054 
00055 //______________________________________________________________________________
00056 TQpVar::TQpVar()
00057 {
00058 // Default constructor
00059 
00060    fNx   = 0;
00061    fMy   = 0;
00062    fMz   = 0;
00063    fNxup = 0;
00064    fNxlo = 0;
00065    fMcup = 0;
00066    fMclo = 0;
00067    fNComplementaryVariables = 0;   
00068 }
00069 
00070 
00071 //______________________________________________________________________________
00072 TQpVar::TQpVar(TVectorD &x_in,TVectorD &s_in,TVectorD &y_in,TVectorD &z_in,
00073                TVectorD &v_in,TVectorD &gamma_in,TVectorD &w_in,TVectorD &phi_in,
00074                TVectorD &t_in,TVectorD &lambda_in,TVectorD &u_in,TVectorD &pi_in,
00075                TVectorD &ixlow_in,TVectorD &ixupp_in,TVectorD &iclow_in,TVectorD &icupp_in)
00076 {
00077 // Constructor
00078 
00079    if (x_in     .GetNrows() > 0) fX.       Use(x_in     .GetNrows(),x_in     .GetMatrixArray());
00080    if (s_in     .GetNrows() > 0) fS.       Use(s_in     .GetNrows(),s_in     .GetMatrixArray());
00081    if (y_in     .GetNrows() > 0) fY.       Use(y_in     .GetNrows(),y_in     .GetMatrixArray());
00082    if (z_in     .GetNrows() > 0) fZ.       Use(z_in     .GetNrows(),z_in     .GetMatrixArray());
00083    if (v_in     .GetNrows() > 0) fV.       Use(v_in     .GetNrows(),v_in     .GetMatrixArray());
00084    if (phi_in   .GetNrows() > 0) fPhi.     Use(phi_in   .GetNrows(),phi_in   .GetMatrixArray());
00085    if (w_in     .GetNrows() > 0) fW.       Use(w_in     .GetNrows(),w_in     .GetMatrixArray());
00086    if (gamma_in .GetNrows() > 0) fGamma.   Use(gamma_in .GetNrows(),gamma_in .GetMatrixArray());
00087    if (t_in     .GetNrows() > 0) fT.       Use(t_in     .GetNrows(),t_in     .GetMatrixArray());
00088    if (lambda_in.GetNrows() > 0) fLambda.  Use(lambda_in.GetNrows(),lambda_in.GetMatrixArray());
00089    if (u_in     .GetNrows() > 0) fU.       Use(u_in     .GetNrows(),u_in     .GetMatrixArray());
00090    if (pi_in    .GetNrows() > 0) fPi.      Use(pi_in    .GetNrows(),pi_in    .GetMatrixArray());
00091    if (ixlow_in .GetNrows() > 0) fXloIndex.Use(ixlow_in .GetNrows(),ixlow_in .GetMatrixArray());
00092    if (ixupp_in .GetNrows() > 0) fXupIndex.Use(ixupp_in .GetNrows(),ixupp_in .GetMatrixArray());
00093    if (iclow_in .GetNrows() > 0) fCloIndex.Use(iclow_in .GetNrows(),iclow_in .GetMatrixArray());
00094    if (icupp_in .GetNrows() > 0) fCupIndex.Use(icupp_in .GetNrows(),icupp_in .GetMatrixArray());
00095 
00096    fNx = fX.GetNrows();
00097    fMy = fY.GetNrows();
00098    fMz = fZ.GetNrows();
00099 
00100    R__ASSERT(fNx == fXloIndex.GetNrows() || 0 == fXloIndex.GetNrows());
00101    R__ASSERT(fNx == fXloIndex.GetNrows() || 0 == fXloIndex.GetNrows());
00102    R__ASSERT(fMz == fCloIndex.GetNrows() || 0 == fCloIndex.GetNrows());
00103    R__ASSERT(fMz == fCupIndex.GetNrows() || 0 == fCupIndex.GetNrows());
00104 
00105    fNxlo = fXloIndex.NonZeros();
00106    fNxup = fXupIndex.NonZeros();
00107    fMclo = fCloIndex.NonZeros();
00108    fMcup = fCupIndex.NonZeros();
00109    fNComplementaryVariables = fMclo+fMcup+fNxlo+fNxup;
00110 
00111    R__ASSERT(fMz == fS.GetNrows());
00112    R__ASSERT(fNx == fV     .GetNrows() || (0 == fV     .GetNrows() && fNxlo == 0));
00113    R__ASSERT(fNx == fGamma .GetNrows() || (0 == fGamma .GetNrows() && fNxlo == 0));
00114 
00115    R__ASSERT(fNx == fW     .GetNrows() || (0 == fW     .GetNrows() && fNxup == 0));
00116    R__ASSERT(fNx == fPhi   .GetNrows() || (0 == fPhi   .GetNrows() && fNxup == 0));
00117 
00118    R__ASSERT(fMz == fT     .GetNrows() || (0 == fT     .GetNrows() && fMclo == 0));
00119    R__ASSERT(fMz == fLambda.GetNrows() || (0 == fLambda.GetNrows() && fMclo == 0));
00120 
00121    R__ASSERT(fMz == fU     .GetNrows() || (0 == fU     .GetNrows() && fMcup == 0));
00122    R__ASSERT(fMz == fPi    .GetNrows() || (0 == fPi    .GetNrows() && fMcup == 0));
00123 }
00124 
00125 
00126 //______________________________________________________________________________
00127 TQpVar::TQpVar(Int_t nx,Int_t my,Int_t mz,TVectorD &ixlow,TVectorD &ixupp,
00128                TVectorD &iclow,TVectorD &icupp)
00129 {
00130 // Constructor
00131 
00132    R__ASSERT(nx == ixlow.GetNrows() || 0 == ixlow.GetNrows());
00133    R__ASSERT(nx == ixlow.GetNrows() || 0 == ixlow.GetNrows());
00134    R__ASSERT(mz == iclow.GetNrows() || 0 == iclow.GetNrows());
00135    R__ASSERT(mz == icupp.GetNrows() || 0 == icupp.GetNrows());
00136 
00137    fNxlo = ixlow.NonZeros();
00138    fNxup = ixupp.NonZeros();
00139    fMclo = iclow.NonZeros();
00140    fMcup = icupp.NonZeros();
00141 
00142    if (ixlow.GetNrows() > 0) fXloIndex.Use(ixlow.GetNrows(),ixlow.GetMatrixArray());
00143    if (ixupp.GetNrows() > 0) fXupIndex.Use(ixupp.GetNrows(),ixupp.GetMatrixArray());
00144    if (iclow.GetNrows() > 0) fCloIndex.Use(iclow.GetNrows(),iclow.GetMatrixArray());
00145    if (icupp.GetNrows() > 0) fCupIndex.Use(icupp.GetNrows(),icupp.GetMatrixArray());
00146 
00147    fNx = nx;
00148    fMy = my;
00149    fMz = mz;
00150 
00151    if (fMclo > 0) {
00152       fT.ResizeTo(fMz);
00153       fLambda.ResizeTo(fMz);
00154    }
00155    if (fMcup > 0) {
00156       fU.ResizeTo(fMz);
00157       fPi.ResizeTo(fMz);
00158    }
00159    if (fNxlo > 0) {
00160       fV.ResizeTo(fNx);
00161       fGamma.ResizeTo(fNx);
00162    }
00163 
00164    if (fNxup > 0) {
00165       fW.ResizeTo(fNx);
00166       fPhi.ResizeTo(fNx);
00167    }
00168 
00169    fS.ResizeTo(fMz);
00170    fX.ResizeTo(fNx);
00171    fY.ResizeTo(fMy);
00172    fZ.ResizeTo(fMz);
00173    fNComplementaryVariables = fMclo+fMcup+fNxlo+fNxup;
00174 }
00175 
00176 
00177 //______________________________________________________________________________
00178 TQpVar::TQpVar(const TQpVar &another) : TObject(another)
00179 {
00180 // Copy constructor
00181 
00182    *this = another;
00183 }
00184 
00185 
00186 //______________________________________________________________________________
00187 Double_t TQpVar::GetMu()
00188 {
00189 // compute complementarity gap, obtained by taking the inner product of the
00190 // complementary vectors and dividing by the total number of components
00191 // computes mu = (t'lambda +u'pi + v'gamma + w'phi)/(mclow+mcupp+nxlow+nxupp)
00192 
00193    Double_t mu = 0.0;
00194    if (fNComplementaryVariables > 0 ) {
00195       if (fMclo > 0) mu += fT*fLambda;
00196       if (fMcup > 0) mu += fU*fPi;
00197       if (fNxlo > 0) mu += fV*fGamma;
00198       if (fNxup > 0) mu += fW*fPhi;
00199 
00200       mu /= fNComplementaryVariables;
00201    }
00202    return mu;
00203 }
00204 
00205 
00206 //______________________________________________________________________________
00207 Double_t TQpVar::MuStep(TQpVar *step,Double_t alpha)
00208 {
00209 // Compute the complementarity gap resulting from a step of length "alpha" along
00210 // direction "step"
00211 
00212    Double_t mu = 0.0;
00213    if (fNComplementaryVariables > 0) {
00214       if (fMclo > 0)
00215          mu += (fT+alpha*step->fT)*(fLambda+alpha*step->fLambda);
00216       if (fMcup > 0)
00217          mu += (fU+alpha*step->fU)*(fPi+alpha*step->fPi);
00218       if (fNxlo > 0)
00219          mu += (fV+alpha*step->fV)*(fGamma+alpha*step->fGamma);
00220       if (fNxup > 0)
00221          mu += (fW+alpha*step->fW)*(fPhi+alpha*step->fPhi);
00222       mu /= fNComplementaryVariables;
00223    }
00224    return mu;
00225 }
00226 
00227 
00228 //______________________________________________________________________________
00229 void TQpVar::Saxpy(TQpVar *b,Double_t alpha)
00230 {
00231 // Perform a "saxpy" operation on all data vectors : x += alpha*y
00232 
00233    Add(fX,alpha,b->fX);
00234    Add(fY,alpha,b->fY);
00235    Add(fZ,alpha,b->fZ);
00236    Add(fS,alpha,b->fS);
00237    if (fMclo > 0) {
00238       R__ASSERT((b->fT)     .MatchesNonZeroPattern(fCloIndex) &&
00239          (b->fLambda).MatchesNonZeroPattern(fCloIndex));
00240 
00241       Add(fT     ,alpha,b->fT);
00242       Add(fLambda,alpha,b->fLambda);
00243    }
00244    if (fMcup > 0) {
00245       R__ASSERT((b->fU) .MatchesNonZeroPattern(fCupIndex) &&
00246          (b->fPi).MatchesNonZeroPattern(fCupIndex));
00247 
00248       Add(fU ,alpha,b->fU);
00249       Add(fPi,alpha,b->fPi);
00250    }
00251    if (fNxlo > 0) {
00252       R__ASSERT((b->fV)    .MatchesNonZeroPattern(fXloIndex) &&
00253          (b->fGamma).MatchesNonZeroPattern(fXloIndex));
00254 
00255       Add(fV    ,alpha,b->fV);
00256       Add(fGamma,alpha,b->fGamma);
00257    }
00258    if (fNxup > 0) {
00259       R__ASSERT((b->fW)  .MatchesNonZeroPattern(fXupIndex) &&
00260          (b->fPhi).MatchesNonZeroPattern(fXupIndex));
00261 
00262       Add(fW  ,alpha,b->fW);
00263       Add(fPhi,alpha,b->fPhi);
00264    }
00265 }
00266 
00267 
00268 //______________________________________________________________________________
00269 void TQpVar::Negate()
00270 {
00271 // Perform a "negate" operation on all data vectors : x =  -x
00272 
00273    fS *= -1.;
00274    fX *= -1.;
00275    fY *= -1.;
00276    fZ *= -1.;
00277    if (fMclo > 0) {
00278       fT      *= -1.;
00279       fLambda *= -1.;
00280    }
00281    if (fMcup > 0) {
00282       fU  *= -1.;
00283       fPi *= -1.;
00284    }
00285    if (fNxlo > 0) {
00286       fV     *= -1.;
00287       fGamma *= -1.;
00288    }
00289    if (fNxup > 0) {
00290       fW   *= -1.;
00291       fPhi *= -1.;
00292    }
00293 }
00294 
00295 
00296 //______________________________________________________________________________
00297 Double_t TQpVar::StepBound(TQpVar *b)
00298 {
00299 // calculate the largest alpha in (0,1] such that the/ nonnegative variables stay
00300 // nonnegative in the given search direction. In the general QP problem formulation
00301 // this is the largest value of alpha such that
00302 //     (t,u,v,w,lambda,pi,phi,gamma) + alpha * (b->t,b->u,b->v,b->w,b->lambda,b->pi,
00303 //                                                b->phi,b->gamma) >= 0.
00304 
00305    Double_t maxStep = 1.0;
00306 
00307    if (fMclo > 0 ) {
00308       R__ASSERT(fT     .SomePositive(fCloIndex));
00309       R__ASSERT(fLambda.SomePositive(fCloIndex));
00310 
00311       maxStep = this->StepBound(fT,     b->fT,     maxStep);
00312       maxStep = this->StepBound(fLambda,b->fLambda,maxStep);
00313    }
00314 
00315    if (fMcup > 0 ) {
00316       R__ASSERT(fU .SomePositive(fCupIndex));
00317       R__ASSERT(fPi.SomePositive(fCupIndex));
00318 
00319       maxStep = this->StepBound(fU, b->fU, maxStep);
00320       maxStep = this->StepBound(fPi,b->fPi,maxStep);
00321    }
00322 
00323    if (fNxlo > 0 ) {
00324       R__ASSERT(fV    .SomePositive(fXloIndex));
00325       R__ASSERT(fGamma.SomePositive(fXloIndex));
00326 
00327       maxStep = this->StepBound(fV,    b->fV,    maxStep);
00328       maxStep = this->StepBound(fGamma,b->fGamma,maxStep);
00329    }
00330 
00331    if (fNxup > 0 ) {
00332       R__ASSERT(fW  .SomePositive(fXupIndex));
00333       R__ASSERT(fPhi.SomePositive(fXupIndex));
00334 
00335       maxStep = this->StepBound(fW,  b->fW,  maxStep);
00336       maxStep = this->StepBound(fPhi,b->fPhi,maxStep);
00337    }
00338 
00339    return maxStep;
00340 }
00341 
00342 
00343 //______________________________________________________________________________
00344 Double_t TQpVar::StepBound(TVectorD &v,TVectorD &dir,Double_t maxStep)
00345 {
00346 // Find the maximum stepsize of v in direction dir
00347 // before violating the nonnegativity constraints
00348 
00349    if (!AreCompatible(v,dir)) {
00350       ::Error("StepBound(TVectorD &,TVectorD &,Double_t)","vector's not compatible");
00351       return kFALSE;
00352    }
00353 
00354    const Int_t n = v.GetNrows();
00355    const Double_t * const pD = dir.GetMatrixArray();
00356    const Double_t * const pV = v.GetMatrixArray();
00357 
00358    Double_t bound = maxStep;
00359    for (Int_t i = 0; i < n; i++) {
00360       Double_t tmp = pD[i];
00361       if ( pV[i] >= 0 && tmp < 0 ) {
00362          tmp = -pV[i]/tmp;
00363          if (tmp < bound)
00364             bound = tmp;
00365       }
00366    }
00367    return bound;
00368 }
00369 
00370 
00371 //______________________________________________________________________________
00372 Bool_t TQpVar::IsInteriorPoint()
00373 {
00374 // Is the current position an interior point  ?
00375 
00376    Bool_t interior = kTRUE;
00377    if (fMclo > 0)
00378       interior = interior &&
00379          fT.SomePositive(fCloIndex) && fLambda.SomePositive(fCloIndex);
00380 
00381    if (fMcup > 0)
00382       interior = interior &&
00383          fU.SomePositive(fCupIndex) && fPi.SomePositive(fCupIndex);
00384 
00385    if (fNxlo > 0)
00386       interior = interior &&
00387          fV.SomePositive(fXloIndex) && fGamma.SomePositive(fXloIndex);
00388 
00389    if (fNxup > 0)
00390       interior = interior &&
00391          fW.SomePositive(fXupIndex) && fPhi.SomePositive(fXupIndex);
00392 
00393    return interior;
00394 }
00395 
00396 
00397 //______________________________________________________________________________
00398 Double_t TQpVar::FindBlocking(TQpVar   *step,
00399                               Double_t &primalValue,
00400                               Double_t &primalStep,
00401                               Double_t &dualValue,
00402                               Double_t &dualStep,
00403                               Int_t    &fIrstOrSecond)
00404 {
00405 // Performs the same function as StepBound, and supplies additional information about
00406 // which component of the nonnegative variables is responsible for restricting alpha.
00407 // In terms of the abstract formulation, the components have the following meanings :
00408 //
00409 //  primalValue   : the value of the blocking component of the primal variables (u,t,v,w).
00410 //  primalStep    : the corresponding value of the blocking component of the primal step
00411 //                  variables (b->u,b->t,b->v,b->w)
00412 //  dualValue     : the value of the blocking component of the dual variables/
00413 //                  (lambda,pi,phi,gamma).
00414 //  dualStep      : the corresponding value of the blocking component of the dual step
00415 //                   variables (b->lambda,b->pi,b->phi,b->gamma)
00416 //  firstOrSecond : 1 if the primal step is blocking,
00417 //                  2 if the dual step is block,
00418 //                  0 if no step is blocking.
00419 
00420    fIrstOrSecond = 0;
00421    Double_t alpha = 1.0;
00422    if (fMclo > 0)
00423       alpha = FindBlocking(fT,step->fT,fLambda,step->fLambda,alpha,
00424          primalValue,primalStep,dualValue,dualStep,fIrstOrSecond);
00425 
00426    if (fMcup > 0)
00427       alpha = FindBlocking(fU,step->fU,fPi,step->fPi,alpha,
00428          primalValue,primalStep,dualValue,dualStep,fIrstOrSecond);
00429 
00430    if (fNxlo > 0)
00431       alpha = FindBlocking(fV,step->fV,fGamma,step->fGamma,alpha,
00432          primalValue,primalStep,dualValue,dualStep,fIrstOrSecond);
00433 
00434    if (fNxup > 0)
00435       alpha = FindBlocking(fW,step->fW,fPhi,step->fPhi,alpha,
00436          primalValue,primalStep,dualValue,dualStep,fIrstOrSecond);
00437 
00438    return alpha;
00439 }
00440 
00441 
00442 //______________________________________________________________________________
00443 Double_t TQpVar::FindBlocking(TVectorD &w,TVectorD &wstep,TVectorD &u,TVectorD &ustep,
00444                               Double_t maxStep,Double_t &w_elt,Double_t &wstep_elt,Double_t &u_elt,
00445                               Double_t &ustep_elt,int& fIrst_or_second)
00446 {
00447 // See other FindBlocking function
00448 
00449    return FindBlockingSub(w.GetNrows(),
00450       w.GetMatrixArray(),    1,
00451       wstep.GetMatrixArray(),1,
00452       u.GetMatrixArray(),    1,
00453       ustep.GetMatrixArray(),1,
00454       maxStep,
00455       w_elt,wstep_elt,
00456       u_elt,ustep_elt,
00457       fIrst_or_second);
00458 }
00459 
00460 
00461 //______________________________________________________________________________
00462 Double_t TQpVar::FindBlockingSub(Int_t n,
00463                                  Double_t *w,    Int_t incw,
00464                                  Double_t *wstep,Int_t incwstep,
00465                                  Double_t *u,    Int_t incu,
00466                                  Double_t *ustep,Int_t incustep,
00467                                  Double_t maxStep,
00468                                  Double_t &w_elt,Double_t &wstep_elt,
00469                                  Double_t &u_elt,Double_t &ustep_elt,
00470                                  Int_t &fIrst_or_second)
00471 {
00472 // See FindBlocking function
00473 
00474    Double_t bound = maxStep;
00475 
00476    Int_t i = n-1;
00477    Int_t lastBlocking = -1;
00478 
00479    // Search backward so that we fInd the blocking constraint of lowest
00480    // index. We do this to make things consistent with MPI's MPI_MINLOC,
00481    // which returns the processor with smallest rank where a min occurs.
00482    //
00483    // Still, going backward is ugly!
00484    Double_t *pw     = w    +(n-1)*incw;
00485    Double_t *pwstep = wstep+(n-1)*incwstep;
00486    Double_t *pu     = u    +(n-1)*incu;
00487    Double_t *pustep = ustep+(n-1)*incustep;
00488 
00489    while (i >= 0) {
00490       Double_t tmp = *pwstep;
00491       if (*pw > 0 && tmp < 0) {
00492          tmp = -*pw/tmp;
00493          if( tmp <= bound ) {
00494             bound = tmp;
00495             lastBlocking = i;
00496             fIrst_or_second = 1;
00497          }
00498       }
00499       tmp = *pustep;
00500       if (*pu > 0 && tmp < 0) {
00501          tmp = -*pu/tmp;
00502          if( tmp <= bound ) {
00503             bound = tmp;
00504             lastBlocking = i;
00505             fIrst_or_second = 2;
00506          }
00507       }
00508 
00509       i--;
00510       if (i >= 0) {
00511          // It is safe to decrement the pointers
00512          pw     -= incw;
00513          pwstep -= incwstep;
00514          pu     -= incu;
00515          pustep -= incustep;
00516       }
00517    }
00518 
00519    if (lastBlocking > -1) {
00520       // fIll out the elements
00521       w_elt     = w[lastBlocking];
00522       wstep_elt = wstep[lastBlocking];
00523       u_elt     = u[lastBlocking];
00524       ustep_elt = ustep[lastBlocking];
00525    }
00526    return bound;
00527 }
00528 
00529 
00530 //______________________________________________________________________________
00531 void TQpVar::InteriorPoint(Double_t alpha,Double_t beta)
00532 {
00533 // Sets components of (u,t,v,w) to alpha and of (lambda,pi,phi,gamma) to beta
00534 
00535    fS.Zero();
00536    fX.Zero();
00537    fY.Zero();
00538    fZ.Zero();
00539 
00540    if (fNxlo > 0) {
00541       fV = alpha;
00542       fV.SelectNonZeros(fXloIndex);
00543       fGamma = beta;
00544       fGamma.SelectNonZeros(fXloIndex);
00545    }
00546 
00547    if (fNxup > 0) {
00548       fW = alpha;
00549       fW.SelectNonZeros(fXupIndex);
00550       fPhi = beta;
00551       fPhi.SelectNonZeros(fXupIndex);
00552    }
00553 
00554    if (fMclo > 0 ) {
00555       fT = alpha;
00556       fT.SelectNonZeros(fCloIndex);
00557       fLambda = beta;
00558       fLambda.SelectNonZeros(fCloIndex);
00559    }
00560 
00561    if (fMcup > 0) {
00562       fU = alpha;
00563       fU.SelectNonZeros(fCupIndex);
00564       fPi = beta;
00565       fPi.SelectNonZeros(fCupIndex);
00566    }
00567 }
00568 
00569 
00570 //______________________________________________________________________________
00571 Double_t TQpVar::Violation()
00572 {
00573 // The amount by which the current variables violate the  non-negativity constraints.
00574 
00575    Double_t viol = 0.0;
00576    Double_t cmin;
00577 
00578    if (fNxlo > 0) {
00579       cmin = fV.Min();
00580       if (cmin < viol) viol = cmin;
00581 
00582       cmin = fGamma.Min();
00583       if (cmin < viol) viol = cmin;
00584    }
00585    if (fNxup > 0) {
00586       cmin = fW.Min();
00587       if (cmin < viol) viol = cmin;
00588 
00589       cmin = fPhi.Min();
00590       if (cmin < viol) viol = cmin;
00591    }
00592    if (fMclo > 0) {
00593       cmin = fT.Min();
00594       if (cmin < viol) viol = cmin;
00595 
00596       cmin = fLambda.Min();
00597       if (cmin < viol) viol = cmin;
00598    }
00599    if (fMcup > 0) {
00600       cmin = fU.Min();
00601       if (cmin < viol) viol = cmin;
00602 
00603       cmin = fPi.Min();
00604       if (cmin < viol) viol = cmin;
00605    }
00606 
00607    return -viol;
00608 }
00609 
00610 
00611 //______________________________________________________________________________
00612 void TQpVar::ShiftBoundVariables(Double_t alpha,Double_t beta)
00613 {
00614 // Add alpha to components of (u,t,v,w) and beta to components of (lambda,pi,phi,gamma)
00615 
00616    if (fNxlo > 0) {
00617       fV    .AddSomeConstant(alpha,fXloIndex);
00618       fGamma.AddSomeConstant(beta, fXloIndex);
00619    }
00620    if (fNxup > 0) {
00621       fW  .AddSomeConstant(alpha,fXupIndex);
00622       fPhi.AddSomeConstant(beta, fXupIndex);
00623    }
00624    if (fMclo > 0) {
00625       fT     .AddSomeConstant(alpha,fCloIndex);
00626       fLambda.AddSomeConstant(beta, fCloIndex);
00627    }
00628    if (fMcup > 0) {
00629       fU .AddSomeConstant(alpha,fCupIndex);
00630       fPi.AddSomeConstant(beta, fCupIndex);
00631    }
00632 }
00633 
00634 
00635 //______________________________________________________________________________
00636 void TQpVar::Print(Option_t * /*option*/) const
00637 {
00638 // Print class members
00639 
00640    cout << "fNx  : " << fNx   << endl;
00641    cout << "fMy  : " << fMy   << endl;
00642    cout << "fMz  : " << fMz   << endl;
00643    cout << "fNxup: " << fNxup << endl;
00644    cout << "fNxlo: " << fNxlo << endl;
00645    cout << "fMcup: " << fMcup << endl;
00646    cout << "fMclo: " << fMclo << endl;
00647 
00648    fXloIndex.Print("fXloIndex");
00649    fXupIndex.Print("fXupIndex");
00650    fCupIndex.Print("fCupIndex");
00651    fCloIndex.Print("fCloIndex");
00652 
00653    fX.Print("fX");
00654    fS.Print("fS");
00655    fY.Print("fY");
00656    fZ.Print("fZ");
00657 
00658    fV.Print("fV");
00659    fPhi.Print("fPhi");
00660 
00661    fW.Print("fW");
00662    fGamma.Print("fGamma");
00663 
00664    fT.Print("fT");
00665    fLambda.Print("fLambda");
00666 
00667    fU.Print("fU");
00668    fPi.Print("fPi");
00669 }
00670 
00671 
00672 //______________________________________________________________________________
00673 Double_t TQpVar::Norm1()
00674 {
00675 // Return the sum of the vector-norm1's
00676 
00677    Double_t norm = 0.0;
00678    norm += fX.Norm1();
00679    norm += fS.Norm1();
00680    norm += fY.Norm1();
00681    norm += fZ.Norm1();
00682 
00683    norm += fV.Norm1();
00684    norm += fPhi.Norm1();
00685    norm += fW.Norm1();
00686    norm += fGamma.Norm1();
00687    norm += fT.Norm1();
00688    norm += fLambda.Norm1();
00689    norm += fU.Norm1();
00690    norm += fPi.Norm1();
00691 
00692    return norm;
00693 }
00694 
00695 
00696 //______________________________________________________________________________
00697 Double_t TQpVar::NormInf()
00698 {
00699 // Return the sum of the vector-normInf's
00700 
00701    Double_t norm = 0.0;
00702 
00703    Double_t tmp = fX.NormInf();
00704    if (tmp > norm) norm = tmp;
00705    tmp = fS.NormInf();
00706    if (tmp > norm) norm = tmp;
00707    tmp = fY.NormInf();
00708    if (tmp > norm) norm = tmp;
00709    tmp = fZ.NormInf();
00710    if (tmp > norm) norm = tmp;
00711 
00712    tmp = fV.NormInf();
00713    if (tmp > norm) norm = tmp;
00714    tmp = fPhi.NormInf();
00715    if (tmp > norm) norm = tmp;
00716 
00717    tmp = fW.NormInf();
00718    if (tmp > norm) norm = tmp;
00719    tmp = fGamma.NormInf();
00720    if (tmp > norm) norm = tmp;
00721 
00722    tmp = fT.NormInf();
00723    if (tmp > norm) norm = tmp;
00724    tmp = fLambda.NormInf();
00725    if (tmp > norm) norm = tmp;
00726 
00727    tmp = fU.NormInf();
00728    if (tmp > norm) norm = tmp;
00729    tmp = fPi.NormInf();
00730    if (tmp > norm) norm = tmp;
00731 
00732    return norm;
00733 }
00734 
00735 
00736 //______________________________________________________________________________
00737 Bool_t TQpVar::ValidNonZeroPattern()
00738 {
00739 // Check that the variables conform to the non-zero indices
00740 
00741    if (fNxlo > 0 &&
00742       ( !fV    .MatchesNonZeroPattern(fXloIndex) ||
00743         !fGamma.MatchesNonZeroPattern(fXloIndex) ) ) {
00744       return kFALSE;
00745    }
00746 
00747    if (fNxup > 0 &&
00748       ( !fW  .MatchesNonZeroPattern(fXupIndex) ||
00749         !fPhi.MatchesNonZeroPattern(fXupIndex) ) ) {
00750       return kFALSE;
00751    }
00752    if (fMclo > 0 &&
00753       ( !fT     .MatchesNonZeroPattern(fCloIndex) ||
00754         !fLambda.MatchesNonZeroPattern(fCloIndex) ) ) {
00755       return kFALSE;
00756    }
00757 
00758    if (fMcup > 0 &&
00759       ( !fU .MatchesNonZeroPattern(fCupIndex) ||
00760         !fPi.MatchesNonZeroPattern(fCupIndex) ) ) {
00761       return kFALSE;
00762    }
00763 
00764    return kTRUE;
00765 }
00766 
00767 
00768 //______________________________________________________________________________
00769 TQpVar &TQpVar::operator=(const TQpVar &source)
00770 {
00771 // Assignment operator
00772 
00773    if (this != &source) {
00774       TObject::operator=(source);
00775       fNx       = source.fNx;
00776       fMy       = source.fMy;
00777       fMz       = source.fMz;
00778       fNxup     = source.fNxup;
00779       fNxlo     = source.fNxlo;
00780       fMcup     = source.fMcup;
00781       fMclo     = source.fMclo;
00782 
00783       fXloIndex = source.fXloIndex;
00784       fXupIndex = source.fXupIndex;
00785       fCupIndex = source.fCupIndex;
00786       fCloIndex = source.fCloIndex;
00787 
00788       fX     .ResizeTo(source.fX);      fX      = source.fX;
00789       fS     .ResizeTo(source.fS);      fS      = source.fS;
00790       fY     .ResizeTo(source.fY);      fY      = source.fY;
00791       fZ     .ResizeTo(source.fZ);      fZ      = source.fZ;
00792 
00793       fV     .ResizeTo(source.fV);      fV      = source.fV;
00794       fPhi   .ResizeTo(source.fPhi);    fPhi    = source.fPhi;
00795 
00796       fW     .ResizeTo(source.fW);      fW      = source.fW;
00797       fGamma .ResizeTo(source.fGamma) ; fGamma  = source.fGamma;
00798 
00799       fT     .ResizeTo(source.fT);      fT      = source.fT;
00800       fLambda.ResizeTo(source.fLambda); fLambda = source.fLambda;
00801 
00802       fU     .ResizeTo(source.fU);      fU      = source.fU;
00803       fPi    .ResizeTo(source.fPi);     fPi     = source.fPi;
00804 
00805       // LM: copy also this data member
00806       fNComplementaryVariables = source.fNComplementaryVariables;
00807    }
00808    return *this;
00809 }

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