Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGondzioSolver.cxx
Go to the documentation of this file.
1// @(#)root/quadp:$Id$
2// Author: Eddy Offermann May 2004
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/*************************************************************************
13 * Parts of this file are copied from the OOQP distribution and *
14 * are subject to the following license: *
15 * *
16 * COPYRIGHT 2001 UNIVERSITY OF CHICAGO *
17 * *
18 * The copyright holder hereby grants you royalty-free rights to use, *
19 * reproduce, prepare derivative works, and to redistribute this software*
20 * to others, provided that any changes are clearly documented. This *
21 * software was authored by: *
22 * *
23 * E. MICHAEL GERTZ gertz@mcs.anl.gov *
24 * Mathematics and Computer Science Division *
25 * Argonne National Laboratory *
26 * 9700 S. Cass Avenue *
27 * Argonne, IL 60439-4844 *
28 * *
29 * STEPHEN J. WRIGHT swright@cs.wisc.edu *
30 * Computer Sciences Department *
31 * University of Wisconsin *
32 * 1210 West Dayton Street *
33 * Madison, WI 53706 FAX: (608)262-9777 *
34 * *
35 * Any questions or comments may be directed to one of the authors. *
36 * *
37 * ARGONNE NATIONAL LABORATORY (ANL), WITH FACILITIES IN THE STATES OF *
38 * ILLINOIS AND IDAHO, IS OWNED BY THE UNITED STATES GOVERNMENT, AND *
39 * OPERATED BY THE UNIVERSITY OF CHICAGO UNDER PROVISION OF A CONTRACT *
40 * WITH THE DEPARTMENT OF ENERGY. *
41 *************************************************************************/
42
43////////////////////////////////////////////////////////////////////////////////
44///
45/// \class TGondzioSolver
46///
47/// Derived class of TQpSolverBase implementing Gondzio-correction
48/// version of Mehrotra's original predictor-corrector algorithm.
49///
50////////////////////////////////////////////////////////////////////////////////
51
52
53#include <iostream>
54#include "TMath.h"
55#include "TGondzioSolver.h"
56#include "TQpLinSolverDens.h"
57
58
59////////////////////////////////////////////////////////////////////////////////
60/// Default constructor
61
63{
64 fPrintlevel = 0;
65 fTsig = 0.0;
68
69 fStepFactor0 = 0.0;
70 fStepFactor1 = 0.0;
71 fAcceptTol = 0.0;
72 fBeta_min = 0.0;
73 fBeta_max = 0.0;
74
75 fCorrector_step = nullptr;
76 fStep = nullptr;
77 fCorrector_resid = nullptr;
78 fFactory = nullptr;
79}
80
81
82////////////////////////////////////////////////////////////////////////////////
83/// Constructor
84
86{
87 fFactory = of;
91
92 fPrintlevel = verbose;
93 fTsig = 3.0; // the usual value for the centering exponent (tau)
94
95 fMaximum_correctors = 3; // maximum number of Gondzio correctors
96
98
99 // the two StepFactor constants set targets for increase in step
100 // length for each corrector
101 fStepFactor0 = 0.08;
102 fStepFactor1 = 1.08;
103
104 // accept the enhanced step if it produces a small improvement in
105 // the step length
106 fAcceptTol = 0.005;
107
108 //define the Gondzio correction box
109 fBeta_min = 0.1;
110 fBeta_max = 10.0;
111}
112
113
114////////////////////////////////////////////////////////////////////////////////
115/// Copy constructor
116
121
122
123////////////////////////////////////////////////////////////////////////////////
124/// Solve the quadratic programming problem as formulated through prob, store
125/// the final solution in iterate->fX . Monitor the residuals during the iterations
126/// through resid . The status is returned as defined in TQpSolverBase::ETerminationCode .
127
129{
130 Int_t status_code;
131 Double_t alpha = 1;
132 Double_t sigma = 1;
133
134 fDnorm = prob->DataNorm();
135
136 // initialization of (x,y,z) and factorization routine.
138 this->Start(fFactory,iterate,prob,resid,fStep);
139
140 fIter = 0;
142 Double_t mu = iterate->GetMu();
143
144 Int_t done = 0;
145 do {
146 fIter++;
147 // evaluate residuals and update algorithm status:
148 resid->CalcResids(prob,iterate);
149
150 // termination test:
151 status_code = this->DoStatus(prob,iterate,resid,fIter,mu,0);
152 if (status_code != kNOT_FINISHED ) break;
153 if (fPrintlevel >= 10)
154 this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,0);
155
156 // *** Predictor step ***
157
158 resid->Set_r3_xz_alpha(iterate,0.0);
159
162 fStep->Negate();
163
164 alpha = iterate->StepBound(fStep);
165
166 // calculate centering parameter
167 Double_t muaff = iterate->MuStep(fStep,alpha);
169
170 if (fPrintlevel >= 10)
171 this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,2);
172
173 // *** Corrector step ***
174
175 // form right hand side of linear system:
176 resid->Add_r3_xz_alpha(fStep,-sigma*mu);
177
179 fStep->Negate();
180
181 // calculate distance to boundary along the Mehrotra
182 // predictor-corrector step:
183 alpha = iterate->StepBound(fStep);
184
185 // prepare for Gondzio corrector loop: zero out the
186 // corrector_resid structure:
188
189 // calculate the target box:
192
195
196 // enter the Gondzio correction loop:
197 if (fPrintlevel >= 10)
198 std::cout << "**** Entering the correction loop ****" << std::endl;
199
201 alpha < 1.0 && !stopCorrections) {
202
203 // copy current variables into fcorrector_step
205
206 // calculate target steplength
208 if (alpha_target > 1.0) alpha_target = 1.0;
209
210 // add a step of this length to corrector_step
212
213 // place XZ into the r3 component of corrector_resids
215
216 // do the projection operation
218
219 // solve for corrector direction
221
222 // add the current step to corrector_step, and calculate the
223 // step to boundary along the resulting direction
226
227 // if the enhanced step length is actually 1, make it official
228 // and stop correcting
229 if (alpha_enhanced == 1.0) {
231 alpha = alpha_enhanced;
233 stopCorrections = 1;
234 }
235 else if(alpha_enhanced >= (1.0+fAcceptTol)*alpha) {
236 // if enhanced step length is significantly better than the
237 // current alpha, make the enhanced step official, but maybe
238 // keep correcting
240 alpha = alpha_enhanced;
242 stopCorrections = 0;
243 }
244 else {
245 // otherwise quit the correction loop
246 stopCorrections = 1;
247 }
248 }
249
250 // We've finally decided on a step direction, now calculate the
251 // length using Mehrotra's heuristic.x
252 alpha = this->FinalStepLength(iterate,fStep);
253
254 // alternatively, just use a crude step scaling factor.
255 // alpha = 0.995 * iterate->StepBound(fStep);
256
257 // actually take the step (at last!) and calculate the new mu
258
259 iterate->Saxpy(fStep,alpha);
260 mu = iterate->GetMu();
261 } while (!done);
262
263 resid->CalcResids(prob,iterate);
264 if (fPrintlevel >= 10)
265 this->DoMonitor(prob,iterate,resid,alpha,sigma,fIter,mu,status_code,1);
266
267 return status_code;
268}
269
270
271////////////////////////////////////////////////////////////////////////////////
272/// Print information about the optimization process and monitor the convergence
273/// status of thye algorithm
274
275void TGondzioSolver::DefMonitor(TQpDataBase* /* data */,TQpVar* /* vars */,
278 Int_t status_code,Int_t level)
279{
280 switch (level) {
281 case 0 : case 1:
282 {
283 std::cout << std::endl << "Duality Gap: " << resid->GetDualityGap() << std::endl;
284 if (i > 1) {
285 std::cout << " Number of Corrections = " << fNumberGondzioCorrections
286 << " alpha = " << alpha << std::endl;
287 }
288 std::cout << " *** Iteration " << i << " *** " << std::endl;
289 std::cout << " mu = " << mu << " relative residual norm = "
290 << resid->GetResidualNorm()/fDnorm << std::endl;
291
292 if (level == 1) {
293 // Termination has been detected by the status check; print
294 // appropriate message
295 if (status_code == kSUCCESSFUL_TERMINATION) {
296 std::cout << std::endl
297 << " *** SUCCESSFUL TERMINATION ***"
298 << std::endl;
299 }
300 else if (status_code == kMAX_ITS_EXCEEDED) {
301 std::cout << std::endl
302 << " *** MAXIMUM ITERATIONS REACHED *** " << std::endl;
303 }
304 else if (status_code == kINFEASIBLE) {
305 std::cout << std::endl
306 << " *** TERMINATION: PROBABLY INFEASIBLE *** "
307 << std::endl;
308 }
309 else if (status_code == kUNKNOWN) {
310 std::cout << std::endl
311 << " *** TERMINATION: STATUS UNKNOWN *** " << std::endl;
312 }
313 }
314 } break;
315 case 2:
316 std::cout << " *** sigma = " << sigma << std::endl;
317 break;
318 }
319}
320
321
322////////////////////////////////////////////////////////////////////////////////
323/// Deconstructor
324
326{
327 if (fCorrector_step) { delete fCorrector_step; fCorrector_step = nullptr; }
328 if (fStep) { delete fStep; fStep = nullptr; }
329 if (fCorrector_resid) { delete fCorrector_resid; fCorrector_resid = nullptr; }
330}
331
332
333////////////////////////////////////////////////////////////////////////////////
334/// Assignment operator
335
337{
338 if (this != &source) {
340
341 fPrintlevel = source.fPrintlevel;
342 fTsig = source.fTsig ;
343 fMaximum_correctors = source.fMaximum_correctors;
344 fNumberGondzioCorrections = source.fNumberGondzioCorrections;
345
346 fStepFactor0 = source.fStepFactor0;
347 fStepFactor1 = source.fStepFactor1;
348 fAcceptTol = source.fAcceptTol;
349 fBeta_min = source.fBeta_min;
350 fBeta_max = source.fBeta_max;
351
353 if (fStep) delete fStep;
355
356 fCorrector_step = new TQpVar(*source.fCorrector_step);
357 fStep = new TQpVar(*source.fStep);
358 fCorrector_resid = new TQpResidual(*source.fCorrector_resid);
359 fFactory = source.fFactory;
360 }
361 return *this;
362}
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
@ kNOT_FINISHED
@ kINFEASIBLE
@ kMAX_ITS_EXCEEDED
@ kUNKNOWN
@ kSUCCESSFUL_TERMINATION
Derived class of TQpSolverBase implementing Gondzio-correction version of Mehrotra's original predict...
Double_t fAcceptTol
Int_t fMaximum_correctors
TQpVar * fCorrector_step
Int_t fNumberGondzioCorrections
Double_t fStepFactor0
TQpProbBase * fFactory
TGondzioSolver()
Default constructor.
Int_t Solve(TQpDataBase *prob, TQpVar *iterate, TQpResidual *resid) override
Solve the quadratic programming problem as formulated through prob, store the final solution in itera...
void DefMonitor(TQpDataBase *data, TQpVar *vars, TQpResidual *resids, Double_t alpha, Double_t sigma, Int_t i, Double_t mu, Int_t status_code, Int_t level) override
Print information about the optimization process and monitor the convergence status of thye algorithm...
~TGondzioSolver() override
Deconstructor.
TGondzioSolver & operator=(const TGondzioSolver &source)
Assignment operator.
Double_t fStepFactor1
TQpResidual * fCorrector_resid
Data for the general QP formulation.
Definition TQpDataBase.h:61
virtual void Solve(TQpDataBase *prob, TQpVar *vars, TQpResidual *resids, TQpVar *step)
Solves the system for a given set of residuals.
virtual void Factor(TQpDataBase *prob, TQpVar *vars)
Sets up the matrix for the main linear system in "augmented system" form.
default general problem formulation:
Definition TQpProbBase.h:89
virtual TQpLinSolverBase * MakeLinSys(const TQpDataBase *data)=0
virtual TQpResidual * MakeResiduals(const TQpDataBase *data)=0
virtual TQpVar * MakeVariables(const TQpDataBase *data)=0
The Residuals class calculates and stores the quantities that appear on the right-hand side of the li...
Definition TQpResidual.h:62
void Clear_r1r2()
set the noncomplementarity components of the residual (the terms arising from the linear equalities i...
void Set_r3_xz_alpha(TQpVar *vars, Double_t alpha)
Set the "complementarity" component of the residuals to the pairwise products of the complementary va...
void Project_r3(Double_t rmin, Double_t rmax)
Perform the projection operation required by Gondzio algorithm: replace each component r3_i of the co...
The Solver class contains methods for monitoring and checking the convergence status of the algorithm...
TQpLinSolverBase * fSys
Double_t fDnorm
virtual void Start(TQpProbBase *formulation, TQpVar *iterate, TQpDataBase *prob, TQpResidual *resid, TQpVar *step)
Implements a default starting-point heuristic.
virtual void DoMonitor(TQpDataBase *data, TQpVar *vars, TQpResidual *resids, Double_t alpha, Double_t sigma, Int_t i, Double_t mu, Int_t stop_code, Int_t level)
Monitor progress / convergence aat each interior-point iteration.
virtual Int_t DoStatus(TQpDataBase *data, TQpVar *vars, TQpResidual *resids, Int_t i, Double_t mu, Int_t level)
Tests for termination.
virtual Double_t FinalStepLength(TQpVar *iterate, TQpVar *step)
Implements a version of Mehrotra starting point heuristic, modified to ensure identical steps in the ...
TQpSolverBase & operator=(const TQpSolverBase &source)
Assignment operator.
Class containing the variables for the general QP formulation.
Definition TQpVar.h:60
virtual void Negate()
Perform a "negate" operation on all data vectors : x = -x.
Definition TQpVar.cxx:271
virtual void Saxpy(TQpVar *b, Double_t alpha)
Perform a "saxpy" operation on all data vectors : x += alpha*y.
Definition TQpVar.cxx:231
const Double_t sigma
int iterate(rng_state_t *X)
Definition mixmax.icc:34
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:732