57 ClassImp(TQpSolverBase);
62 TQpSolverBase::TQpSolverBase()
72 fGamma_a = 1.0/(1.0-fGamma_f);
80 fMu_history =
new Double_t[fMaxit];
81 fRnorm_history =
new Double_t[fMaxit];
82 fPhi_history =
new Double_t[fMaxit];
83 fPhi_min_history =
new Double_t[fMaxit];
92 TQpSolverBase::TQpSolverBase(
const TQpSolverBase &another) : TObject(another)
101 TQpSolverBase::~TQpSolverBase()
103 if (fSys) {
delete fSys; fSys = 0; }
105 if (fMu_history) {
delete [] fMu_history; fMu_history = 0; }
106 if (fRnorm_history) {
delete [] fRnorm_history; fRnorm_history = 0; }
107 if (fPhi_history) {
delete [] fPhi_history; fPhi_history = 0; }
108 if (fPhi_min_history) {
delete [] fPhi_min_history; fPhi_min_history = 0; }
118 void TQpSolverBase::Start(TQpProbBase *formulation,TQpVar *iterate,TQpDataBase *prob,
119 TQpResidual *resid,TQpVar *step)
121 this->DefStart(formulation,iterate,prob,resid,step);
128 void TQpSolverBase::DefStart(TQpProbBase * ,TQpVar *iterate,
129 TQpDataBase *prob,TQpResidual *resid,TQpVar *step)
131 Double_t sdatanorm = TMath::Sqrt(fDnorm);
132 Double_t a = sdatanorm;
133 Double_t b = sdatanorm;
135 iterate->InteriorPoint(a,b);
136 resid->CalcResids(prob,iterate);
137 resid->Set_r3_xz_alpha(iterate,0.0);
139 fSys->Factor(prob,iterate);
140 fSys->Solve(prob,iterate,resid,step);
144 iterate->Saxpy(step,1.0);
146 Double_t shift = 1.e3+2*iterate->Violation();
147 iterate->ShiftBoundVariables(shift,shift);
154 void TQpSolverBase::SteveStart(TQpProbBase * ,
155 TQpVar *iterate,TQpDataBase *prob,
156 TQpResidual *resid,TQpVar *step)
158 Double_t sdatanorm = TMath::Sqrt(fDnorm);
162 iterate->InteriorPoint(a,b);
167 resid->Set_r3_xz_alpha(iterate,-sdatanorm);
168 resid->CalcResids(prob,iterate);
174 iterate->InteriorPoint(a,b);
175 fSys->Factor(prob,iterate);
176 fSys->Solve (prob,iterate,resid,step);
185 Double_t shift = 1.5*iterate->Violation();
186 iterate->ShiftBoundVariables(shift,shift);
190 const Double_t mutemp = iterate->GetMu();
191 const Double_t xsnorm = iterate->Norm1();
192 const Double_t delta = 0.5*iterate->fNComplementaryVariables*mutemp/xsnorm;
193 iterate->ShiftBoundVariables(delta,delta);
202 void TQpSolverBase::DumbStart(TQpProbBase * ,
203 TQpVar *iterate,TQpDataBase * ,
204 TQpResidual * ,TQpVar * )
206 const Double_t sdatanorm = fDnorm;
207 const Double_t a = 1.e3;
208 const Double_t b = 1.e5;
209 const Double_t bigstart = a*sdatanorm+b;
210 iterate->InteriorPoint(bigstart,bigstart);
218 Double_t TQpSolverBase::FinalStepLength(TQpVar *iterate,TQpVar *step)
221 Double_t primalValue; Double_t primalStep; Double_t dualValue; Double_t dualStep;
222 const Double_t maxAlpha = iterate->FindBlocking(step,primalValue,primalStep,
223 dualValue,dualStep,firstOrSecond);
224 Double_t mufull = iterate->MuStep(step,maxAlpha);
228 Double_t alpha = 1.0;
229 switch (firstOrSecond) {
234 alpha = (-primalValue+mufull/(dualValue+maxAlpha*dualStep))/primalStep;
237 alpha = (-dualValue+mufull/(primalValue+maxAlpha*primalStep))/dualStep;
240 R__ASSERT(0 &&
"Can't get here");
244 if (alpha < fGamma_f*maxAlpha) alpha = fGamma_f*maxAlpha;
255 void TQpSolverBase::DoMonitor(TQpDataBase *data,TQpVar *vars,TQpResidual *resids,
256 Double_t alpha,Double_t sigma,Int_t i,Double_t mu,
257 Int_t stop_code,Int_t level)
259 this->DefMonitor(data,vars,resids,alpha,sigma,i,mu,stop_code,level);
268 Int_t TQpSolverBase::DoStatus(TQpDataBase *data,TQpVar *vars,TQpResidual *resids,
269 Int_t i,Double_t mu,Int_t level)
271 return this->DefStatus(data,vars,resids,i,mu,level);
278 Int_t TQpSolverBase::DefStatus(TQpDataBase * ,TQpVar * ,
279 TQpResidual *resids,Int_t iterate,Double_t mu,Int_t )
281 Int_t stop_code = kNOT_FINISHED;
283 const Double_t gap = TMath::Abs(resids->GetDualityGap());
284 const Double_t rnorm = resids->GetResidualNorm();
286 Int_t idx = iterate-1;
287 if (idx < 0 ) idx = 0;
288 if (idx >= fMaxit) idx = fMaxit-1;
291 fMu_history[idx] = mu;
292 fRnorm_history[idx] = rnorm;
293 fPhi = (rnorm+gap)/fDnorm;
294 fPhi_history[idx] = fPhi;
297 fPhi_min_history[idx] = fPhi_min_history[idx-1];
298 if (fPhi < fPhi_min_history[idx]) fPhi_min_history[idx] = fPhi;
300 fPhi_min_history[idx] = fPhi;
302 if (iterate >= fMaxit) {
303 stop_code = kMAX_ITS_EXCEEDED;
305 else if (mu <= fMutol && rnorm <= fArtol*fDnorm) {
306 stop_code = kSUCCESSFUL_TERMINATION;
308 if (stop_code != kNOT_FINISHED)
return stop_code;
311 if (idx >= 10 && fPhi >= 1.e-8 && fPhi >= 1.e4*fPhi_min_history[idx])
312 stop_code = kINFEASIBLE;
313 if (stop_code != kNOT_FINISHED)
return stop_code;
316 if (idx >= 30 && fPhi_min_history[idx] >= .5*fPhi_min_history[idx-30])
317 stop_code = kUNKNOWN;
319 if (rnorm/fDnorm > fArtol &&
320 (fRnorm_history[idx]/fMu_history[idx])/(fRnorm_history[0]/fMu_history[0]) >= 1.e8)
321 stop_code = kUNKNOWN;
330 TQpSolverBase &TQpSolverBase::operator=(
const TQpSolverBase &source)
332 if (
this != &source) {
333 TObject::operator=(source);
336 fDnorm = source.fDnorm;
337 fMutol = source.fMutol;
338 fArtol = source.fArtol;
339 fGamma_f = source.fGamma_f;
340 fGamma_a = source.fGamma_a;
342 fIter = source.fIter;
344 if (fMaxit != source.fMaxit) {
345 if (fMu_history)
delete [] fMu_history;
346 fMu_history =
new Double_t[fMaxit];
347 if (fRnorm_history)
delete [] fRnorm_history;
348 fRnorm_history =
new Double_t[fMaxit];
349 if (fPhi_history)
delete [] fPhi_history;
350 fPhi_history =
new Double_t[fMaxit];
351 if (fPhi_min_history)
delete [] fPhi_min_history;
352 fPhi_min_history =
new Double_t[fMaxit];
355 fMaxit = source.fMaxit;
356 memcpy(fMu_history,source.fMu_history,fMaxit*
sizeof(Double_t));
357 memcpy(fRnorm_history,source.fRnorm_history,fMaxit*
sizeof(Double_t));
358 memcpy(fPhi_history,source.fPhi_history,fMaxit*
sizeof(Double_t));
359 memcpy(fPhi_min_history,source.fPhi_min_history,fMaxit*
sizeof(Double_t));