1 /* $Id: ClpInterior.hpp 1665 2011-01-04 17:55:54Z lou $ */
2 // Copyright (C) 2003, International Business Machines
3 // Corporation and others.  All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5 /*
6    Authors
7 
8    John Tomlin (pdco)
9    John Forrest (standard predictor-corrector)
10 
11    Note JJF has added arrays - this takes more memory but makes
12    flow easier to understand and hopefully easier to extend
13 
14  */
15 #ifndef ClpInterior_H
16 #define ClpInterior_H
17 
18 #include <iostream>
19 #include <cfloat>
20 #include "ClpModel.hpp"
21 #include "ClpMatrixBase.hpp"
22 #include "ClpSolve.hpp"
23 #include "CoinDenseVector.hpp"
24 class ClpLsqr;
25 class ClpPdcoBase;
26 /// ******** DATA to be moved into protected section of ClpInterior
27 typedef struct {
28      double  atolmin;
29      double  r3norm;
30      double  LSdamp;
31      double* deltay;
32 } Info;
33 /// ******** DATA to be moved into protected section of ClpInterior
34 
35 typedef struct {
36      double  atolold;
37      double  atolnew;
38      double  r3ratio;
39      int   istop;
40      int   itncg;
41 } Outfo;
42 /// ******** DATA to be moved into protected section of ClpInterior
43 
44 typedef struct {
45      double  gamma;
46      double  delta;
47      int MaxIter;
48      double  FeaTol;
49      double  OptTol;
50      double  StepTol;
51      double  x0min;
52      double  z0min;
53      double  mu0;
54      int   LSmethod;   // 1=Cholesky    2=QR    3=LSQR
55      int   LSproblem;  // See below
56      int LSQRMaxIter;
57      double  LSQRatol1; // Initial  atol
58      double  LSQRatol2; // Smallest atol (unless atol1 is smaller)
59      double  LSQRconlim;
60      int  wait;
61 } Options;
62 class Lsqr;
63 class ClpCholeskyBase;
64 // ***** END
65 /** This solves LPs using interior point methods
66 
67     It inherits from ClpModel and all its arrays are created at
68     algorithm time.
69 
70 */
71 
72 class ClpInterior : public ClpModel {
73      friend void ClpInteriorUnitTest(const std::string & mpsDir,
74                                      const std::string & netlibDir);
75 
76 public:
77 
78      /**@name Constructors and destructor and copy */
79      //@{
80      /// Default constructor
81      ClpInterior (  );
82 
83      /// Copy constructor.
84      ClpInterior(const ClpInterior &);
85      /// Copy constructor from model.
86      ClpInterior(const ClpModel &);
87      /** Subproblem constructor.  A subset of whole model is created from the
88          row and column lists given.  The new order is given by list order and
89          duplicates are allowed.  Name and integer information can be dropped
90      */
91      ClpInterior (const ClpModel * wholeModel,
92                   int numberRows, const int * whichRows,
93                   int numberColumns, const int * whichColumns,
94                   bool dropNames = true, bool dropIntegers = true);
95      /// Assignment operator. This copies the data
96      ClpInterior & operator=(const ClpInterior & rhs);
97      /// Destructor
98      ~ClpInterior (  );
99      // Ones below are just ClpModel with some changes
100      /** Loads a problem (the constraints on the
101            rows are given by lower and upper bounds). If a pointer is 0 then the
102            following values are the default:
103            <ul>
104              <li> <code>colub</code>: all columns have upper bound infinity
105              <li> <code>collb</code>: all columns have lower bound 0
106              <li> <code>rowub</code>: all rows have upper bound infinity
107              <li> <code>rowlb</code>: all rows have lower bound -infinity
108          <li> <code>obj</code>: all variables have 0 objective coefficient
109            </ul>
110        */
111      void loadProblem (  const ClpMatrixBase& matrix,
112                          const double* collb, const double* colub,
113                          const double* obj,
114                          const double* rowlb, const double* rowub,
115                          const double * rowObjective = nullptr);
116      void loadProblem (  const CoinPackedMatrix& matrix,
117                          const double* collb, const double* colub,
118                          const double* obj,
119                          const double* rowlb, const double* rowub,
120                          const double * rowObjective = nullptr);
121 
122      /** Just like the other loadProblem() method except that the matrix is
123        given in a standard column major ordered format (without gaps). */
124      void loadProblem (  const int numcols, const int numrows,
125                          const CoinBigIndex* start, const int* index,
126                          const double* value,
127                          const double* collb, const double* colub,
128                          const double* obj,
129                          const double* rowlb, const double* rowub,
130                          const double * rowObjective = nullptr);
131      /// This one is for after presolve to save memory
132      void loadProblem (  const int numcols, const int numrows,
133                          const CoinBigIndex* start, const int* index,
134                          const double* value, const int * length,
135                          const double* collb, const double* colub,
136                          const double* obj,
137                          const double* rowlb, const double* rowub,
138                          const double * rowObjective = nullptr);
139      /// Read an mps file from the given filename
140      int readMps(const char *filename,
141                  bool keepNames = false,
142                  bool ignoreErrors = false);
143      /** Borrow model.  This is so we dont have to copy large amounts
144          of data around.  It assumes a derived class wants to overwrite
145          an empty model with a real one - while it does an algorithm.
146          This is same as ClpModel one. */
147      void borrowModel(ClpModel & otherModel);
148      /** Return model - updates any scalars */
149      void returnModel(ClpModel & otherModel);
150      //@}
151 
152      /**@name Functions most useful to user */
153      //@{
154      /** Pdco algorithm - see ClpPdco.hpp for method */
155      int pdco();
156      // ** Temporary version
157      int  pdco( ClpPdcoBase * stuff, Options &options, Info &info, Outfo &outfo);
158      /// Primal-Dual Predictor-Corrector barrier
159      int primalDual();
160      //@}
161 
162      /**@name most useful gets and sets */
163      //@{
164      /// If problem is primal feasible
primalFeasible() const165      inline bool primalFeasible() const {
166           return (sumPrimalInfeasibilities_ <= 1.0e-5);
167      }
168      /// If problem is dual feasible
dualFeasible() const169      inline bool dualFeasible() const {
170           return (sumDualInfeasibilities_ <= 1.0e-5);
171      }
172      /// Current (or last) algorithm
algorithm() const173      inline int algorithm() const {
174           return algorithm_;
175      }
176      /// Set algorithm
setAlgorithm(int value)177      inline void setAlgorithm(int value) {
178           algorithm_ = value;
179      }
180      /// Sum of dual infeasibilities
sumDualInfeasibilities() const181      inline CoinWorkDouble sumDualInfeasibilities() const {
182           return sumDualInfeasibilities_;
183      }
184      /// Sum of primal infeasibilities
sumPrimalInfeasibilities() const185      inline CoinWorkDouble sumPrimalInfeasibilities() const {
186           return sumPrimalInfeasibilities_;
187      }
188      /// dualObjective.
dualObjective() const189      inline CoinWorkDouble dualObjective() const {
190           return dualObjective_;
191      }
192      /// primalObjective.
primalObjective() const193      inline CoinWorkDouble primalObjective() const {
194           return primalObjective_;
195      }
196      /// diagonalNorm
diagonalNorm() const197      inline CoinWorkDouble diagonalNorm() const {
198           return diagonalNorm_;
199      }
200      /// linearPerturbation
linearPerturbation() const201      inline CoinWorkDouble linearPerturbation() const {
202           return linearPerturbation_;
203      }
setLinearPerturbation(CoinWorkDouble value)204      inline void setLinearPerturbation(CoinWorkDouble value) {
205           linearPerturbation_ = value;
206      }
207      /// projectionTolerance
projectionTolerance() const208      inline CoinWorkDouble projectionTolerance() const {
209           return projectionTolerance_;
210      }
setProjectionTolerance(CoinWorkDouble value)211      inline void setProjectionTolerance(CoinWorkDouble value) {
212           projectionTolerance_ = value;
213      }
214      /// diagonalPerturbation
diagonalPerturbation() const215      inline CoinWorkDouble diagonalPerturbation() const {
216           return diagonalPerturbation_;
217      }
setDiagonalPerturbation(CoinWorkDouble value)218      inline void setDiagonalPerturbation(CoinWorkDouble value) {
219           diagonalPerturbation_ = value;
220      }
221      /// gamma
gamma() const222      inline CoinWorkDouble gamma() const {
223           return gamma_;
224      }
setGamma(CoinWorkDouble value)225      inline void setGamma(CoinWorkDouble value) {
226           gamma_ = value;
227      }
228      /// delta
delta() const229      inline CoinWorkDouble delta() const {
230           return delta_;
231      }
setDelta(CoinWorkDouble value)232      inline void setDelta(CoinWorkDouble value) {
233           delta_ = value;
234      }
235      /// ComplementarityGap
complementarityGap() const236      inline CoinWorkDouble complementarityGap() const {
237           return complementarityGap_;
238      }
239      //@}
240 
241      /**@name most useful gets and sets */
242      //@{
243      /// Largest error on Ax-b
largestPrimalError() const244      inline CoinWorkDouble largestPrimalError() const {
245           return largestPrimalError_;
246      }
247      /// Largest error on basic duals
largestDualError() const248      inline CoinWorkDouble largestDualError() const {
249           return largestDualError_;
250      }
251      /// Maximum iterations
maximumBarrierIterations() const252      inline int maximumBarrierIterations() const {
253           return maximumBarrierIterations_;
254      }
setMaximumBarrierIterations(int value)255      inline void setMaximumBarrierIterations(int value) {
256           maximumBarrierIterations_ = value;
257      }
258      /// Set cholesky (and delete present one)
259      void setCholesky(ClpCholeskyBase * cholesky);
260      /// Return number fixed to see if worth presolving
261      int numberFixed() const;
262      /** fix variables interior says should be.  If reallyFix false then just
263          set values to exact bounds */
264      void fixFixed(bool reallyFix = true);
265      /// Primal erturbation vector
primalR() const266      inline CoinWorkDouble * primalR() const {
267           return primalR_;
268      }
269      /// Dual erturbation vector
dualR() const270      inline CoinWorkDouble * dualR() const {
271           return dualR_;
272      }
273      //@}
274 
275 protected:
276      /**@name protected methods */
277      //@{
278      /// Does most of deletion
279      void gutsOfDelete();
280      /// Does most of copying
281      void gutsOfCopy(const ClpInterior & rhs);
282      /// Returns true if data looks okay, false if not
283      bool createWorkingData();
284      void deleteWorkingData();
285      /// Sanity check on input rim data
286      bool sanityCheck();
287      ///  This does housekeeping
288      int housekeeping();
289      //@}
290 public:
291      /**@name public methods */
292      //@{
293      /// Raw objective value (so always minimize)
rawObjectiveValue() const294      inline CoinWorkDouble rawObjectiveValue() const {
295           return objectiveValue_;
296      }
297      /// Returns 1 if sequence indicates column
isColumn(int sequence) const298      inline int isColumn(int sequence) const {
299           return sequence < numberColumns_ ? 1 : 0;
300      }
301      /// Returns sequence number within section
sequenceWithin(int sequence) const302      inline int sequenceWithin(int sequence) const {
303           return sequence < numberColumns_ ? sequence : sequence - numberColumns_;
304      }
305      /// Checks solution
306      void checkSolution();
307      /** Modifies djs to allow for quadratic.
308          returns quadratic offset */
309      CoinWorkDouble quadraticDjs(CoinWorkDouble * djRegion, const CoinWorkDouble * solution,
310                                  CoinWorkDouble scaleFactor);
311 
312      /// To say a variable is fixed
setFixed(int sequence)313      inline void setFixed( int sequence) {
314           status_[sequence] = static_cast<unsigned char>(status_[sequence] | 1) ;
315      }
clearFixed(int sequence)316      inline void clearFixed( int sequence) {
317           status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~1) ;
318      }
fixed(int sequence) const319      inline bool fixed(int sequence) const {
320           return ((status_[sequence] & 1) != 0);
321      }
322 
323      /// To flag a variable
setFlagged(int sequence)324      inline void setFlagged( int sequence) {
325           status_[sequence] = static_cast<unsigned char>(status_[sequence] | 2) ;
326      }
clearFlagged(int sequence)327      inline void clearFlagged( int sequence) {
328           status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~2) ;
329      }
flagged(int sequence) const330      inline bool flagged(int sequence) const {
331           return ((status_[sequence] & 2) != 0);
332      }
333 
334      /// To say a variable is fixed OR free
setFixedOrFree(int sequence)335      inline void setFixedOrFree( int sequence) {
336           status_[sequence] = static_cast<unsigned char>(status_[sequence] | 4) ;
337      }
clearFixedOrFree(int sequence)338      inline void clearFixedOrFree( int sequence) {
339           status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~4) ;
340      }
fixedOrFree(int sequence) const341      inline bool fixedOrFree(int sequence) const {
342           return ((status_[sequence] & 4) != 0);
343      }
344 
345      /// To say a variable has lower bound
setLowerBound(int sequence)346      inline void setLowerBound( int sequence) {
347           status_[sequence] = static_cast<unsigned char>(status_[sequence] | 8) ;
348      }
clearLowerBound(int sequence)349      inline void clearLowerBound( int sequence) {
350           status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~8) ;
351      }
lowerBound(int sequence) const352      inline bool lowerBound(int sequence) const {
353           return ((status_[sequence] & 8) != 0);
354      }
355 
356      /// To say a variable has upper bound
setUpperBound(int sequence)357      inline void setUpperBound( int sequence) {
358           status_[sequence] = static_cast<unsigned char>(status_[sequence] | 16) ;
359      }
clearUpperBound(int sequence)360      inline void clearUpperBound( int sequence) {
361           status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~16) ;
362      }
upperBound(int sequence) const363      inline bool upperBound(int sequence) const {
364           return ((status_[sequence] & 16) != 0);
365      }
366 
367      /// To say a variable has fake lower bound
setFakeLower(int sequence)368      inline void setFakeLower( int sequence) {
369           status_[sequence] = static_cast<unsigned char>(status_[sequence] | 32) ;
370      }
clearFakeLower(int sequence)371      inline void clearFakeLower( int sequence) {
372           status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~32) ;
373      }
fakeLower(int sequence) const374      inline bool fakeLower(int sequence) const {
375           return ((status_[sequence] & 32) != 0);
376      }
377 
378      /// To say a variable has fake upper bound
setFakeUpper(int sequence)379      inline void setFakeUpper( int sequence) {
380           status_[sequence] = static_cast<unsigned char>(status_[sequence] | 64) ;
381      }
clearFakeUpper(int sequence)382      inline void clearFakeUpper( int sequence) {
383           status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~64) ;
384      }
fakeUpper(int sequence) const385      inline bool fakeUpper(int sequence) const {
386           return ((status_[sequence] & 64) != 0);
387      }
388      //@}
389 
390 ////////////////// data //////////////////
391 protected:
392 
393      /**@name data.  Many arrays have a row part and a column part.
394       There is a single array with both - columns then rows and
395       then normally two arrays pointing to rows and columns.  The
396       single array is the owner of memory
397      */
398      //@{
399      /// Largest error on Ax-b
400      CoinWorkDouble largestPrimalError_;
401      /// Largest error on basic duals
402      CoinWorkDouble largestDualError_;
403      /// Sum of dual infeasibilities
404      CoinWorkDouble sumDualInfeasibilities_;
405      /// Sum of primal infeasibilities
406      CoinWorkDouble sumPrimalInfeasibilities_;
407      /// Worst complementarity
408      CoinWorkDouble worstComplementarity_;
409      ///
410 public:
411      CoinWorkDouble xsize_;
412      CoinWorkDouble zsize_;
413 protected:
414      /// Working copy of lower bounds (Owner of arrays below)
415      CoinWorkDouble * lower_;
416      /// Row lower bounds - working copy
417      CoinWorkDouble * rowLowerWork_;
418      /// Column lower bounds - working copy
419      CoinWorkDouble * columnLowerWork_;
420      /// Working copy of upper bounds (Owner of arrays below)
421      CoinWorkDouble * upper_;
422      /// Row upper bounds - working copy
423      CoinWorkDouble * rowUpperWork_;
424      /// Column upper bounds - working copy
425      CoinWorkDouble * columnUpperWork_;
426      /// Working copy of objective
427      CoinWorkDouble * cost_;
428 public:
429      /// Rhs
430      CoinWorkDouble * rhs_;
431      CoinWorkDouble * x_;
432      CoinWorkDouble * y_;
433      CoinWorkDouble * dj_;
434 protected:
435      /// Pointer to Lsqr object
436      ClpLsqr * lsqrObject_;
437      /// Pointer to stuff
438      ClpPdcoBase * pdcoStuff_;
439      /// Below here is standard barrier stuff
440      /// mu.
441      CoinWorkDouble mu_;
442      /// objectiveNorm.
443      CoinWorkDouble objectiveNorm_;
444      /// rhsNorm.
445      CoinWorkDouble rhsNorm_;
446      /// solutionNorm.
447      CoinWorkDouble solutionNorm_;
448      /// dualObjective.
449      CoinWorkDouble dualObjective_;
450      /// primalObjective.
451      CoinWorkDouble primalObjective_;
452      /// diagonalNorm.
453      CoinWorkDouble diagonalNorm_;
454      /// stepLength
455      CoinWorkDouble stepLength_;
456      /// linearPerturbation
457      CoinWorkDouble linearPerturbation_;
458      /// diagonalPerturbation
459      CoinWorkDouble diagonalPerturbation_;
460      // gamma from Saunders and Tomlin regularized
461      CoinWorkDouble gamma_;
462      // delta from Saunders and Tomlin regularized
463      CoinWorkDouble delta_;
464      /// targetGap
465      CoinWorkDouble targetGap_;
466      /// projectionTolerance
467      CoinWorkDouble projectionTolerance_;
468      /// maximumRHSError.  maximum Ax
469      CoinWorkDouble maximumRHSError_;
470      /// maximumBoundInfeasibility.
471      CoinWorkDouble maximumBoundInfeasibility_;
472      /// maximumDualError.
473      CoinWorkDouble maximumDualError_;
474      /// diagonalScaleFactor.
475      CoinWorkDouble diagonalScaleFactor_;
476      /// scaleFactor.  For scaling objective
477      CoinWorkDouble scaleFactor_;
478      /// actualPrimalStep
479      CoinWorkDouble actualPrimalStep_;
480      /// actualDualStep
481      CoinWorkDouble actualDualStep_;
482      /// smallestInfeasibility
483      CoinWorkDouble smallestInfeasibility_;
484      /// historyInfeasibility.
485 #define LENGTH_HISTORY 5
486      CoinWorkDouble historyInfeasibility_[LENGTH_HISTORY];
487      /// complementarityGap.
488      CoinWorkDouble complementarityGap_;
489      /// baseObjectiveNorm
490      CoinWorkDouble baseObjectiveNorm_;
491      /// worstDirectionAccuracy
492      CoinWorkDouble worstDirectionAccuracy_;
493      /// maximumRHSChange
494      CoinWorkDouble maximumRHSChange_;
495      /// errorRegion. i.e. Ax
496      CoinWorkDouble * errorRegion_;
497      /// rhsFixRegion.
498      CoinWorkDouble * rhsFixRegion_;
499      /// upperSlack
500      CoinWorkDouble * upperSlack_;
501      /// lowerSlack
502      CoinWorkDouble * lowerSlack_;
503      /// diagonal
504      CoinWorkDouble * diagonal_;
505      /// solution
506      CoinWorkDouble * solution_;
507      /// work array
508      CoinWorkDouble * workArray_;
509      /// delta X
510      CoinWorkDouble * deltaX_;
511      /// delta Y
512      CoinWorkDouble * deltaY_;
513      /// deltaZ.
514      CoinWorkDouble * deltaZ_;
515      /// deltaW.
516      CoinWorkDouble * deltaW_;
517      /// deltaS.
518      CoinWorkDouble * deltaSU_;
519      CoinWorkDouble * deltaSL_;
520      /// Primal regularization array
521      CoinWorkDouble * primalR_;
522      /// Dual regularization array
523      CoinWorkDouble * dualR_;
524      /// rhs B
525      CoinWorkDouble * rhsB_;
526      /// rhsU.
527      CoinWorkDouble * rhsU_;
528      /// rhsL.
529      CoinWorkDouble * rhsL_;
530      /// rhsZ.
531      CoinWorkDouble * rhsZ_;
532      /// rhsW.
533      CoinWorkDouble * rhsW_;
534      /// rhs C
535      CoinWorkDouble * rhsC_;
536      /// zVec
537      CoinWorkDouble * zVec_;
538      /// wVec
539      CoinWorkDouble * wVec_;
540      /// cholesky.
541      ClpCholeskyBase * cholesky_;
542      /// numberComplementarityPairs i.e. ones with lower and/or upper bounds (not fixed)
543      int numberComplementarityPairs_;
544      /// numberComplementarityItems_ i.e. number of active bounds
545      int numberComplementarityItems_;
546      /// Maximum iterations
547      int maximumBarrierIterations_;
548      /// gonePrimalFeasible.
549      bool gonePrimalFeasible_;
550      /// goneDualFeasible.
551      bool goneDualFeasible_;
552      /// Which algorithm being used
553      int algorithm_;
554      //@}
555 };
556 //#############################################################################
557 /** A function that tests the methods in the ClpInterior class. The
558     only reason for it not to be a member method is that this way it doesn't
559     have to be compiled into the library. And that's a gain, because the
560     library should be compiled with optimization on, but this method should be
561     compiled with debugging.
562 
563     It also does some testing of ClpFactorization class
564  */
565 void
566 ClpInteriorUnitTest(const std::string & mpsDir,
567                     const std::string & netlibDir);
568 
569 
570 #endif
571