00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 #include "Riostream.h"
00052 #include "TQpLinSolverBase.h"
00053 #include "TMatrixD.h"
00054 
00055 ClassImp(TQpLinSolverBase)
00056 
00057 
00058 TQpLinSolverBase::TQpLinSolverBase()
00059 {
00060 
00061 
00062    fNx   = 0;
00063    fMy   = 0;
00064    fMz   = 0;
00065    fNxup = 0;
00066    fNxlo = 0;
00067    fMcup = 0;
00068    fMclo = 0;
00069    fFactory = 0;
00070 }
00071 
00072 
00073 
00074 TQpLinSolverBase::TQpLinSolverBase(TQpProbBase *factory,TQpDataBase *data)
00075 {
00076 
00077 
00078    fFactory = factory;
00079 
00080    fNx = data->fNx;
00081    fMy = data->fMy;
00082    fMz = data->fMz;
00083 
00084    fXloIndex.ResizeTo(data->fXloIndex); fXloIndex = data->fXloIndex;
00085    fXupIndex.ResizeTo(data->fXupIndex); fXupIndex = data->fXupIndex;
00086    fCloIndex.ResizeTo(data->fCloIndex); fCloIndex = data->fCloIndex;
00087    fCupIndex.ResizeTo(data->fCupIndex); fCupIndex = data->fCupIndex;
00088 
00089    fNxlo = fXloIndex.NonZeros();
00090    fNxup = fXupIndex.NonZeros();
00091    fMclo = fCloIndex.NonZeros();
00092    fMcup = fCupIndex.NonZeros();
00093 
00094    if (fNxup+fNxlo > 0) {
00095       fDd.ResizeTo(fNx);
00096       fDq.ResizeTo(fNx);
00097       data->GetDiagonalOfQ(fDq);
00098    }
00099    fNomegaInv.ResizeTo(fMz);
00100    fRhs      .ResizeTo(fNx+fMy+fMz);
00101 }
00102 
00103 
00104 
00105 TQpLinSolverBase::TQpLinSolverBase(const TQpLinSolverBase &another) : TObject(another), 
00106                                                                       fFactory(another.fFactory)
00107 {
00108 
00109 
00110    *this = another;
00111 }
00112 
00113 
00114 
00115 void TQpLinSolverBase::Factor(TQpDataBase * ,TQpVar *vars)
00116 {
00117 
00118 
00119 
00120 
00121    R__ASSERT(vars->ValidNonZeroPattern());
00122 
00123    if (fNxlo+fNxup > 0) {
00124       fDd.ResizeTo(fDq);
00125       fDd = fDq;
00126    }
00127    this->ComputeDiagonals(fDd,fNomegaInv,
00128       vars->fT,vars->fLambda,vars->fU,vars->fPi,
00129       vars->fV,vars->fGamma,vars->fW,vars->fPhi);
00130    if (fNxlo+fNxup > 0) this->PutXDiagonal(fDd);
00131 
00132    fNomegaInv.Invert();
00133    fNomegaInv *= -1.;
00134 
00135    if (fMclo+fMcup > 0) this->PutZDiagonal(fNomegaInv);
00136 }
00137 
00138 
00139 
00140 void TQpLinSolverBase::ComputeDiagonals(TVectorD &dd,TVectorD &omega,
00141                                         TVectorD &t, TVectorD &lambda,
00142                                         TVectorD &u, TVectorD &pi,
00143                                         TVectorD &v, TVectorD &gamma,
00144                                         TVectorD &w, TVectorD &phi)
00145 {
00146 
00147 
00148    if (fNxup+fNxlo > 0) {
00149       if (fNxlo > 0) AddElemDiv(dd,1.0,gamma,v,fXloIndex);
00150       if (fNxup > 0) AddElemDiv(dd,1.0,phi  ,w,fXupIndex);
00151    }
00152    omega.Zero();
00153    if (fMclo > 0) AddElemDiv(omega,1.0,lambda,t,fCloIndex);
00154    if (fMcup > 0) AddElemDiv(omega,1.0,pi,    u,fCupIndex);
00155 }
00156 
00157 
00158 
00159 void TQpLinSolverBase::Solve(TQpDataBase *prob,TQpVar *vars,TQpResidual *res,TQpVar *step)
00160 {
00161 
00162 
00163 
00164 
00165 
00166    R__ASSERT(vars->ValidNonZeroPattern());
00167    R__ASSERT(res ->ValidNonZeroPattern());
00168 
00169    (step->fX).ResizeTo(res->fRQ); step->fX = res->fRQ;
00170    if (fNxlo > 0) {
00171       TVectorD &vInvGamma = step->fV;
00172       vInvGamma.ResizeTo(vars->fGamma); vInvGamma = vars->fGamma;
00173       ElementDiv(vInvGamma,vars->fV,fXloIndex);
00174 
00175       AddElemMult(step->fX,1.0,vInvGamma,res->fRv);
00176       AddElemDiv (step->fX,1.0,res->fRgamma,vars->fV,fXloIndex);
00177    }
00178 
00179    if (fNxup > 0) {
00180       TVectorD &wInvPhi = step->fW;
00181       wInvPhi.ResizeTo(vars->fPhi); wInvPhi = vars->fPhi;
00182       ElementDiv(wInvPhi,vars->fW,fXupIndex);
00183 
00184       AddElemMult(step->fX,1.0,wInvPhi,res->fRw);
00185       AddElemDiv (step->fX,-1.0,res->fRphi,vars->fW,fXupIndex);
00186    }
00187 
00188    
00189    (step->fS).ResizeTo(res->fRz); step->fS = res->fRz;
00190    if (fMclo > 0) {
00191       TVectorD &tInvLambda = step->fT;
00192       tInvLambda.ResizeTo(vars->fLambda); tInvLambda = vars->fLambda;
00193       ElementDiv(tInvLambda,vars->fT,fCloIndex);
00194 
00195       AddElemMult(step->fS,1.0,tInvLambda,res->fRt);
00196       AddElemDiv (step->fS,1.0,res->fRlambda,vars->fT,fCloIndex);
00197    }
00198 
00199    if (fMcup > 0) {
00200       TVectorD &uInvPi = step->fU;
00201 
00202       uInvPi.ResizeTo(vars->fPi); uInvPi = vars->fPi;
00203       ElementDiv(uInvPi,vars->fU,fCupIndex);
00204 
00205       AddElemMult(step->fS,1.0,uInvPi,res->fRu);
00206       AddElemDiv (step->fS,-1.0,res->fRpi,vars->fU,fCupIndex);
00207    }
00208 
00209    (step->fY).ResizeTo(res->fRA); step->fY = res->fRA;
00210    (step->fZ).ResizeTo(res->fRC); step->fZ = res->fRC;
00211 
00212    if (fMclo > 0)
00213       this->SolveXYZS(step->fX,step->fY,step->fZ,step->fS,step->fLambda,prob);
00214    else
00215       this->SolveXYZS(step->fX,step->fY,step->fZ,step->fS,step->fPi,prob);
00216 
00217    if (fMclo > 0) {
00218       (step->fT).ResizeTo(step->fS); step->fT = step->fS;
00219       Add(step->fT,-1.0,res->fRt);
00220       (step->fT).SelectNonZeros(fCloIndex);
00221 
00222       (step->fLambda).ResizeTo(res->fRlambda); step->fLambda = res->fRlambda;
00223       AddElemMult(step->fLambda,-1.0,vars->fLambda,step->fT);
00224       ElementDiv(step->fLambda,vars->fT,fCloIndex);
00225    }
00226 
00227    if (fMcup > 0) {
00228       (step->fU).ResizeTo(res->fRu); step->fU = res->fRu;
00229       Add(step->fU,-1.0,step->fS);
00230       (step->fU).SelectNonZeros(fCupIndex);
00231 
00232       (step->fPi).ResizeTo(res->fRpi); step->fPi = res->fRpi;
00233       AddElemMult(step->fPi,-1.0,vars->fPi,step->fU);
00234       ElementDiv(step->fPi,vars->fU,fCupIndex);
00235    }
00236 
00237    if (fNxlo > 0) {
00238       (step->fV).ResizeTo(step->fX); step->fV = step->fX;
00239       Add(step->fV,-1.0,res->fRv);
00240       (step->fV).SelectNonZeros(fXloIndex);
00241 
00242       (step->fGamma).ResizeTo(res->fRgamma); step->fGamma = res->fRgamma;
00243       AddElemMult(step->fGamma,-1.0,vars->fGamma,step->fV);
00244       ElementDiv(step->fGamma,vars->fV,fXloIndex);
00245    }
00246 
00247    if (fNxup > 0) {
00248       (step->fW).ResizeTo(res->fRw); step->fW = res->fRw;
00249       Add(step->fW,-1.0,step->fX);
00250       (step->fW).SelectNonZeros(fXupIndex);
00251 
00252       (step->fPhi).ResizeTo(res->fRphi); step->fPhi = res->fRphi;
00253       AddElemMult(step->fPhi,-1.0,vars->fPhi,step->fW);
00254       ElementDiv(step->fPhi,vars->fW,fXupIndex);
00255    }
00256    R__ASSERT(step->ValidNonZeroPattern());
00257 }
00258 
00259 
00260 
00261 void TQpLinSolverBase::SolveXYZS(TVectorD &stepx,TVectorD &stepy,
00262                                  TVectorD &stepz,TVectorD &steps,
00263                                  TVectorD & , TQpDataBase *  )
00264 {
00265 
00266 
00267    AddElemMult(stepz,-1.0,fNomegaInv,steps);
00268    this->JoinRHS(fRhs,stepx,stepy,stepz);
00269 
00270    this->SolveCompressed(fRhs);
00271 
00272    this->SeparateVars(stepx,stepy,stepz,fRhs);
00273 
00274    stepy *= -1.;
00275    stepz *= -1.;
00276 
00277    Add(steps,-1.0,stepz);
00278    ElementMult(steps,fNomegaInv);
00279    steps *= -1.;
00280 }
00281 
00282 
00283 
00284 void TQpLinSolverBase::JoinRHS(TVectorD &rhs_out, TVectorD &rhs1_in,
00285                                TVectorD &rhs2_in,TVectorD &rhs3_in)
00286 {
00287 
00288 
00289 
00290 
00291 
00292 
00293    fFactory->JoinRHS(rhs_out,rhs1_in,rhs2_in,rhs3_in);
00294 }
00295 
00296 
00297 
00298 void TQpLinSolverBase::SeparateVars(TVectorD &x_in,TVectorD &y_in,
00299                                     TVectorD &z_in,TVectorD &vars_in)
00300 {
00301 
00302 
00303 
00304 
00305 
00306 
00307    fFactory->SeparateVars(x_in,y_in,z_in,vars_in);
00308 }
00309 
00310 
00311 
00312 TQpLinSolverBase &TQpLinSolverBase::operator=(const TQpLinSolverBase &source)
00313 {
00314 
00315 
00316    if (this != &source) {
00317       TObject::operator=(source);
00318 
00319       fNx   = source.fNx;
00320       fMy   = source.fMy;
00321       fMz   = source.fMz;
00322       fNxup = source.fNxup;
00323       fNxlo = source.fNxlo;
00324       fMcup = source.fMcup;
00325       fMclo = source.fMclo;
00326 
00327       fNomegaInv.ResizeTo(source.fNomegaInv); fNomegaInv = source.fNomegaInv;
00328       fRhs      .ResizeTo(source.fRhs);       fRhs       = source.fRhs;
00329 
00330       fDd       .ResizeTo(source.fDd);        fDd        = source.fDd;
00331       fDq       .ResizeTo(source.fDq);        fDq        = source.fDq;
00332 
00333       fXupIndex .ResizeTo(source.fXupIndex);  fXupIndex  = source.fXupIndex;
00334       fCupIndex .ResizeTo(source.fCupIndex);  fCupIndex  = source.fCupIndex;
00335       fXloIndex .ResizeTo(source.fXloIndex);  fXloIndex  = source.fXloIndex;
00336       fCloIndex .ResizeTo(source.fCloIndex);  fCloIndex  = source.fCloIndex;
00337 
00338       
00339       fFactory = source.fFactory;
00340    }
00341    return *this;
00342 }