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 }