Scippy

SoPlex

Sequential object-oriented simPlex

spxbasis.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2019 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file spxbasis.h
17  * @brief Simplex basis.
18  */
19 #ifndef _SPXBASIS_H_
20 #define _SPXBASIS_H_
21 
22 /* undefine SOPLEX_DEBUG flag from including files; if SOPLEX_DEBUG should be defined in this file, do so below */
23 #ifdef SOPLEX_DEBUG
24 #define SOPLEX_DEBUG_SPXBASIS
25 #undef SOPLEX_DEBUG
26 #endif
27 
28 #include <assert.h>
29 #include <iostream>
30 #include <iomanip>
31 #include <string.h>
32 #include <sstream>
33 
34 #include "soplex/spxdefines.h"
35 #include "soplex/spxlp.h"
36 #include "soplex/svector.h"
37 #include "soplex/ssvector.h"
38 #include "soplex/dataarray.h"
39 #include "soplex/slinsolver.h"
40 #include "soplex/nameset.h"
41 #include "soplex/spxout.h"
42 #include "soplex/timerfactory.h"
43 
44 //#define MEASUREUPDATETIME
45 
46 namespace soplex
47 {
48 class SPxSolver;
49 
50 /**@class SPxBasis
51  @brief Simplex basis.
52  @ingroup Algo
53 
54  Consider the linear program as provided from class SPxLP:
55  \f[
56  \begin{array}{rl}
57  \hbox{max} & c^T x \\
58  \hbox{s.t.} & l_r \le Ax \le u_r \\
59  & l_c \le x \le u_c
60  \end{array}
61  \f]
62  where \f$c, l_c, u_c, x \in {\bf R}^n\f$, \f$l_r, u_r \in {\bf R}^m\f$ and
63  \f$A \in {\bf R}^{m \times n}\f$. Solving this LP with the simplex algorithm
64  requires the definition of a \em basis. Such can be defined as a set of
65  column vectors or a set of row vectors building a non-singular matrix. We
66  will refer to the first case as the \em columnwise \em representation and
67  the latter case will be called the \em rowwise \em representation. In both
68  cases, a \em basis is a set of vectors forming a non-singular matrix. The
69  dimension of the vectors is referred to as the basis' \em dimension,
70  whereas the number of vectors belonging to the LP is called the basis'
71  \em codimension.
72 
73  Class SPxBasis is designed to represent a generic simplex basis, suitable
74  for both representations. At any time the representation can be changed by
75  calling method setRep().
76 
77  Class SPxBasis provides methods for solving linear systems with the basis
78  matrix. However, SPxBasis does not provide a linear solver by its own.
79  Instead, a SLinSolver object must be #load%ed to a SPxBasis which will
80  be called for solving linear systems.
81 */
82 class SPxBasis
83 {
84 public:
85 
86  /// basis status.
87  /** Each SPxBasis is assigned a status flag, which can take on of the
88  above values.
89  */
90  enum SPxStatus
91  {
92  NO_PROBLEM = -2, ///< No Problem has been loaded to the basis.
93  SINGULAR = -1, ///< Basis is singular.
94  REGULAR = 0, ///< Basis is not known to be dual nor primal feasible.
95  DUAL = 1, ///< Basis is dual feasible.
96  PRIMAL = 2, ///< Basis is primal feasible.
97  OPTIMAL = 3, ///< Basis is optimal, i.e. dual and primal feasible.
98  UNBOUNDED = 4, ///< LP has been proven to be primal unbounded.
99  INFEASIBLE = 5 ///< LP has been proven to be primal infeasible.
100  };
101 
102 
103  /// Basis descriptor.
104  class Desc
105  {
106  public:
107 
108  //------------------------------------
109  //**@name Status */
110  //@{
111  /// Status of a variable.
112  /** A basis is described by assigning a Status to all of the LP
113  variables and covariables. This assignment is maintained by the
114  basis #Desc%riptor.
115 
116  Variables and covariables (slackvariables) may have a primal or dual Status. The
117  first type specifies that a variable is set on a primal bound, while
118  the latter type indicates a dual variable to be set on a bound.
119  If a row variable has a primal status, say #P_ON_UPPER, this means
120  that the upper bound of the inequality is set to be tight. Hence,
121  in this case the upper bound must not be infinity.
122 
123  Equivalently, if the status of a variable is dual, say #D_ON_UPPER,
124  it means that the dual variable corresponding to the upper bound
125  inequality of this variable is set to 0.
126 
127  For a column basis, primal #Status%es correspond to nonbasic
128  variables, while dual ones are basic. This is reversed for a row
129  basis. We will now reveal in more detail the significance of
130  variable #Status%es.
131 
132  <b>Primal Variables</b>
133 
134  Consider a range inequality \f$l_r \le a^T x \le u_r\f$ or bounds on
135  a variable \f$l_c \le x_c \le u_c\f$. The following table reveals
136  what is implied if the corresponding variable or covariable is
137  assigned to a primal #Status:
138 
139  \f[
140  \begin{array}{lcl}
141  l_c \le x_c \le u_c & \mbox{Status}(x_i) & l_r \le a^T x \le u_r \\
142  \hline
143  x_c = u_c < \infty & \mbox{P\_ON\_UPPER} & a^T x = u_r < \infty \\
144  x_c = l_c > -\infty & \mbox{P\_ON\_LOWER} & a^T x = l_r > -\infty \\
145  -\infty < l_c = x_c = u_c < \infty
146  & \mbox{P\_FIXED} &
147  -\infty < l_r = a^T x = u_r < \infty \\
148  -\infty = l_i < x_i=0 < u_i = \infty
149  & \mbox{P\_FREE} &
150  -\infty = l_r < a^T x = 0 < u_r = \infty \\
151  \end{array}
152  \f]
153 
154  Note that to determine whether a variable with #Status stat is set to
155  its upper bound, one can compute the test (-stat | -#P_ON_UPPER).
156  This will yield true even if the variable is fixed, i.e., sitting on
157  both bounds at the same time.
158 
159  <b>Dual Variables</b>
160 
161  In principle for implementing the Simplex algorithm it would suffice
162  to use only one dual #Status. However, for performance reasons it
163  is advisable to introduce various dual status types, reflecting
164  the structure of the bounds. Given an upper bound \f$u\f$ and a lower
165  bound \f$l\f$ of a constraint or variable, the following table
166  indicates the setting of the dual Status of this variable.
167 
168  \f[
169  \begin{array}{cl}
170  l \le ... \le u & \mbox{Status} \\
171  \hline
172  -\infty < l \ne u < \infty & \mbox{D\_ON\_BOTH} \\
173  -\infty < l \ne u = \infty & \mbox{D\_ON\_UPPER} \\
174  -\infty = l \ne u < \infty & \mbox{D\_ON\_LOWER} \\
175  -\infty < l = u < \infty & \mbox{D\_FREE} \\
176  -\infty = l \ne u = \infty & \mbox{D\_UNDEFINED} \\
177  \end{array}
178  \f]
179 
180  Note that unbounded primal variables are reflected by an #D_UNDEFINED
181  dual variable, since no reduced costs exist for them. To facilitate
182  the assignment of dual #Status%es, class SPxBasis provides methods
183  #dualStatus(), #dualColStatus() and #dualRowStatus)().
184  */
185  enum Status
186  {
187  P_ON_LOWER = -4, ///< primal variable is set to its lower bound
188  P_ON_UPPER = -2, ///< primal variable is set to its upper bound
189  P_FREE = -1, ///< primal variable is left free, but unset
190  P_FIXED = P_ON_UPPER + P_ON_LOWER, ///< primal variable is fixed to both bounds
191  D_FREE = 1, ///< dual variable is left free, but unset
192  D_ON_UPPER = 2, ///< dual variable is set to its upper bound
193  D_ON_LOWER = 4, ///< dual variable is set to its lower bound
194  D_ON_BOTH = D_ON_LOWER + D_ON_UPPER, ///< dual variable has two bounds
195  D_UNDEFINED = 8 ///< primal or dual variable is undefined
196  };
197  //@}
198 
199  friend class SPxBasis;
200  friend std::ostream& operator<<(std::ostream& os, const Status& stat);
201 
202  private:
203 
204  //------------------------------------
205  //**@name Data */
206  //@{
207  DataArray < Status > rowstat; ///< status of rows.
208  DataArray < Status > colstat; ///< status of columns.
209  DataArray < Status >* stat; ///< basis' status.
210  DataArray < Status >* costat; ///< cobasis' status.
211  //@}
212 
213  public:
214 
215  //------------------------------------
216  //**@name Access / modification */
217  //@{
218  /// returns number of columns.
219  int nCols() const
220  {
221  return colstat.size();
222  }
223  /// returns number of rows.
224  int nRows() const
225  {
226  return rowstat.size();
227  }
228  /// returns dimension.
229  int dim() const
230  {
231  return stat->size();
232  }
233  /// returns codimension.
234  int coDim() const
235  {
236  return costat->size();
237  }
238  ///
240  {
241  return rowstat[i];
242  }
243  /// returns status of row \p i.
244  Status rowStatus(int i) const
245  {
246  return rowstat[i];
247  }
248  /// returns the array of row \ref soplex::SPxBasis::Desc::Status "Status"es.
249  const Status* rowStatus(void) const
250  {
251  return rowstat.get_const_ptr();
252  }
253  ///
255  {
256  return colstat[i];
257  }
258  /// returns status of column \p i.
259  Status colStatus(int i) const
260  {
261  return colstat[i];
262  }
263  /// returns the array of column \ref soplex::SPxBasis::Desc::Status "Status"es.
264  const Status* colStatus(void) const
265  {
266  return colstat.get_const_ptr();
267  }
268  ///
269  Status& status(int i)
270  {
271  return (*stat)[i];
272  }
273  /// returns status of variable \p i.
274  Status status(int i) const
275  {
276  return (*stat)[i];
277  }
278  /// returns the array of variable \ref soplex::SPxBasis::Desc::Status "Status"es.
279  const Status* status(void) const
280  {
281  return stat->get_const_ptr();
282  }
283  ///
284  Status& coStatus(int i)
285  {
286  return (*costat)[i];
287  }
288  /// returns status of covariable \p i.
289  Status coStatus(int i) const
290  {
291  return (*costat)[i];
292  }
293  /// returns the array of covariable \ref soplex::SPxBasis::Desc::Status "Status"es.
294  const Status* coStatus(void) const
295  {
296  return costat->get_const_ptr();
297  }
298  /// resets dimensions.
299  void reSize(int rowDim, int colDim);
300  //@}
301 
302  //------------------------------------
303  //**@name Debugging */
304  //@{
305  /// Prints out status.
306  void dump() const;
307 
308  /// consistency check.
309  bool isConsistent() const;
310  //@}
311 
312  //------------------------------------
313  //**@name Construction / destruction */
314  //@{
315  /// default constructor
317  : stat(0)
318  , costat(0)
319  {}
320  explicit Desc(const SPxSolver& base);
321 
322  /// copy constructor
323  Desc(const Desc& old);
324  /// assignment operator
325  Desc& operator=(const Desc& rhs);
326  //@}
327  };
328 
329 protected:
330 
331  //------------------------------------
332  //**@name Protected data
333  /**
334  For storing the basis matrix we keep two arrays: Array #theBaseId
335  contains the SPxId%s of the basis vectors, and #matrix the pointers to
336  the vectors themselfes. Method #loadMatrixVecs() serves for loading
337  #matrix according to the SPxId%s stored in #theBaseId. This method must
338  be called whenever the vector pointers may have
339  changed due to manipulations of the LP.
340  */
341  //@{
342  /// the LP
344  /// SPxId%s of basic vectors.
346  /// pointers to the vectors of the basis matrix.
348  /// \c true iff the pointers in \ref soplex::SPxBasis::matrix "matrix" are set up correctly.
350 
351  /* @brief LU factorization of basis matrix
352  The factorization of the matrix is stored in #factor if #factorized != 0.
353  Otherwise #factor is undefined.
354  */
356  /// \c true iff \ref soplex::SPxBasis::factor "factor" = \ref soplex::SPxBasis::matrix "matrix" \f$^{-1}\f$.
358 
359  /// number of updates before refactorization.
360  /** When a vector of the basis matrix is exchanged by a call to method
361  #change(), the LU factorization of the matrix is updated
362  accordingly. However, after atmost #maxUpdates updates of the
363  factorization, it is recomputed in order to regain numerical
364  stability and reduce fill in.
365  */
367 
368  /// allowed increase of nonzeros before refactorization.
369  /** When the number of nonzeros in LU factorization exceeds
370  #nonzeroFactor times the number of nonzeros in B, the
371  basis matrix is refactorized.
372  */
374 
375  /// allowed increase in relative fill before refactorization
376  /** When the real relative fill is bigger than fillFactor times lastFill
377  * the Basis will be refactorized.
378  */
380 
381  /// allowed total increase in memory consumption before refactorization
383 
384  /* Rank-1-updates to the basis may be performed via method #change(). In
385  this case, the factorization is updated, and the following members are
386  reset.
387  */
388  int iterCount; ///< number of calls to change() since last manipulation
389  int lastIterCount; ///< number of calls to change() before halting the simplex
390  int iterDegenCheck;///< number of calls to change() since last degeneracy check
391  int updateCount; ///< number of calls to change() since last factorize()
392  int totalUpdateCount; ///< number of updates
393  int nzCount; ///< number of nonzeros in basis matrix
394  int lastMem; ///< memory needed after last fresh factorization
395  Real lastFill; ///< fill ratio that occured during last factorization
396  int lastNzCount; ///< number of nonzeros in basis matrix after last fresh factorization
397 
398  Timer* theTime; ///< time spent in updates
399  Timer::TYPE timerType; ///< type of timer (user or wallclock)
400 
401  SPxId lastin; ///< lastEntered(): variable entered the base last
402  SPxId lastout; ///< lastLeft(): variable left the base last
403  int lastidx; ///< lastIndex(): basis index where last update was done
404  Real minStab; ///< minimum stability
405  //@}
406 
407 private:
408 
409  //------------------------------------
410  //**@name Private data */
411  //@{
412  SPxStatus thestatus; ///< current status of the basis.
413  Desc thedesc; ///< the basis' Descriptor
414  bool freeSlinSolver; ///< true iff factor should be freed inside of this object
415  SPxOut* spxout; ///< message handler
416 
417  //@}
418 
419 public:
420 
421  //------------------------------------------------
422  /**@name Status and Descriptor related Methods */
423  //@{
424  /// returns current SPxStatus.
426  {
427  return thestatus;
428  }
429 
430  /// sets basis SPxStatus to \p stat.
432  {
433 
434  if(thestatus != stat)
435  {
436 #ifdef SOPLEX_DEBUG
437  MSG_DEBUG(std::cout << "DBSTAT01 SPxBasis::setStatus(): status: "
438  << int(thestatus) << " (" << thestatus << ") -> "
439  << int(stat) << " (" << stat << ")" << std::endl;)
440 #endif
441 
442  thestatus = stat;
443 
444  if(stat == NO_PROBLEM)
445  invalidate();
446  }
447  }
448 
449  // TODO control factorization frequency dynamically
450  /// change maximum number of iterations until a refactorization is performed
451  void setMaxUpdates(int maxUp)
452  {
453  assert(maxUp >= 0);
454  maxUpdates = maxUp;
455  }
456 
457  /// returns maximum number of updates before a refactorization is performed
458  int getMaxUpdates() const
459  {
460  return maxUpdates;
461  }
462 
463  ///
464  const Desc& desc() const
465  {
466  return thedesc;
467  }
468  /// returns current basis Descriptor.
470  {
471  return thedesc;
472  }
473 
474  /// dual Status for the \p i'th column variable of the loaded LP.
475  Desc::Status dualColStatus(int i) const;
476 
477  /// dual Status for the column variable with ID \p id of the loaded LP.
478  Desc::Status dualStatus(const SPxColId& id) const;
479 
480  /// dual Status for the \p i'th row variable of the loaded LP.
481  Desc::Status dualRowStatus(int i) const;
482 
483  /// dual Status for the row variable with ID \p id of the loaded LP.
484  Desc::Status dualStatus(const SPxRowId& id) const;
485 
486  /// dual Status for the variable with ID \p id of the loaded LP.
487  /** It is automatically detected, whether the \p id is one of a
488  row or a column variable, and the correct row or column status
489  is returned.
490  */
491  Desc::Status dualStatus(const SPxId& id) const
492  {
493  return id.isSPxRowId()
494  ? dualStatus(SPxRowId(id))
495  : dualStatus(SPxColId(id));
496  }
497  //@}
498 
499 
500  //-----------------------------------
501  /**@name Inquiry Methods */
502  //@{
503  ///
504  inline SPxId& baseId(int i)
505  {
506  return theBaseId[i];
507  }
508  /// returns the Id of the \p i'th basis vector.
509  inline SPxId baseId(int i) const
510  {
511  return theBaseId[i];
512  }
513 
514  /// returns the \p i'th basic vector.
515  const SVector& baseVec(int i) const
516  {
517  assert(matrixIsSetup);
518  return *matrix[i];
519  }
520 
521  /// returns SPxId of last vector included to the basis.
522  inline SPxId lastEntered() const
523  {
524  return lastin;
525  }
526 
527  /// returns SPxId of last vector that left the basis.
528  inline SPxId lastLeft() const
529  {
530  return lastout;
531  }
532 
533  /// returns index in basis where last update was done.
534  inline int lastIndex() const
535  {
536  return lastidx;
537  }
538 
539  /// returns number of basis changes since last refactorization.
540  inline int lastUpdate() const
541  {
542  return updateCount;
543  }
544 
545  /// returns number of basis changes since last \ref soplex::SPxBasis::load() "load()".
546  inline int iteration() const
547  {
548  return iterCount;
549  }
550 
551  /// returns the number of iterations prior to the last break in execution
552  inline int prevIteration() const
553  {
554  return lastIterCount;
555  }
556 
557  /// returns the number of iterations since the last degeneracy check
558  inline int lastDegenCheck() const
559  {
560  return iterDegenCheck;
561  }
562 
563  /// returns loaded solver.
564  inline SPxSolver* solver() const
565  {
566  return theLP;
567  }
568  //@}
569 
570  //-----------------------------------
571  /**@name Linear Algebra */
572  //@{
573  /// Basis-vector product.
574  /** Depending on the representation, for an SPxBasis B,
575  B.multBaseWith(x) computes
576  - \f$x \leftarrow Bx\f$ in the columnwise case, and
577  - \f$x \leftarrow x^TB\f$ in the rowwise case.
578 
579  Both can be seen uniformly as multiplying the basis matrix \p B with
580  a vector \p x aligned the same way as the \em vectors of \p B.
581  */
582  Vector& multBaseWith(Vector& x) const;
583 
584  /// Basis-vector product
585  void multBaseWith(SSVector& x, SSVector& result) const;
586 
587  /// Vector-basis product.
588  /** Depending on the representation, for a #SPxBasis B,
589  B.multWithBase(x) computes
590  - \f$x \leftarrow x^TB\f$ in the columnwise case and
591  - \f$x \leftarrow Bx\f$ in the rowwise case.
592 
593  Both can be seen uniformly as multiplying the basis matrix \p B with
594  a vector \p x aligned the same way as the \em covectors of \p B.
595  */
596  Vector& multWithBase(Vector& x) const;
597 
598  /// Vector-basis product
599  void multWithBase(SSVector& x, SSVector& result) const;
600 
601  /* compute an estimated condition number for the current basis matrix
602  * by computing estimates of the norms of B and B^-1 using the power method.
603  * maxiters and tolerance control the accuracy of the estimate.
604  */
605  Real condition(int maxiters = 10, Real tolerance = 1e-6);
606 
607  /* wrapper to compute an estimate of the condition number of the current basis matrix */
609  {
610  return condition(20, 1e-6);
611  }
612 
613  /* wrapper to compute the exact condition number of the current basis matrix */
615  {
616  return condition(1000, 1e-9);
617  }
618 
619  /* compute condition number estimation based on the diagonal of the LU factorization
620  * type = 0: max/min ratio
621  * type = 1: trace of U (sum of diagonal elements)
622  * type = 2: product of diagonal elements
623  */
624  Real getFastCondition(int type = 0);
625 
626  /// returns the stability of the basis matrix.
627  Real stability() const
628  {
629  return factor->stability();
630  }
631  ///
632  void solve(Vector& x, const Vector& rhs)
633  {
634  if(rhs.dim() == 0)
635  {
636  x.clear();
637  return;
638  }
639 
640  if(!factorized)
642 
643  factor->solveRight(x, rhs);
644  }
645  ///
646  void solve(SSVector& x, const SVector& rhs)
647  {
648  if(rhs.size() == 0)
649  {
650  x.clear();
651  return;
652  }
653 
654  if(!factorized)
656 
657  factor->solveRight(x, rhs);
658  }
659  /// solves linear system with basis matrix.
660  /** Depending on the representation, for a SPxBasis B,
661  B.solve(x) computes
662  - \f$x \leftarrow B^{-1}rhs\f$ in the columnwise case and
663  - \f$x \leftarrow rhs^TB^{-1}\f$ in the rowwise case.
664 
665  Both can be seen uniformly as solving a linear system with the basis
666  matrix \p B and a right handside vector \p x aligned the same way as
667  the \em vectors of \p B.
668  */
669  void solve4update(SSVector& x, const SVector& rhs)
670  {
671  if(rhs.size() == 0)
672  {
673  x.clear();
674  return;
675  }
676 
677  if(!factorized)
679 
680  factor->solveRight4update(x, rhs);
681  }
682  /// solves two systems in one call.
683  void solve4update(SSVector& x, Vector& y, const SVector& rhsx, SSVector& rhsy)
684  {
685  if(!factorized)
687 
688  factor->solve2right4update(x, y, rhsx, rhsy);
689  }
690  /// solves two systems in one call using only sparse data structures
691  void solve4update(SSVector& x, SSVector& y, const SVector& rhsx, SSVector& rhsy)
692  {
693  if(!factorized)
695 
696  factor->solve2right4update(x, y, rhsx, rhsy);
697  }
698  /// solves three systems in one call.
699  void solve4update(SSVector& x, Vector& y, Vector& y2,
700  const SVector& rhsx, SSVector& rhsy, SSVector& rhsy2)
701  {
702  if(!factorized)
704 
705  assert(rhsy.isSetup());
706  assert(rhsy2.isSetup());
707  factor->solve3right4update(x, y, y2, rhsx, rhsy, rhsy2);
708  }
709  /// solves three systems in one call using only sparse data structures
711  const SVector& rhsx, SSVector& rhsy, SSVector& rhsy2)
712  {
713  if(!factorized)
715 
716  assert(rhsy.isSetup());
717  assert(rhsy2.isSetup());
718  factor->solve3right4update(x, y, y2, rhsx, rhsy, rhsy2);
719  }
720  /// Cosolves linear system with basis matrix.
721  /** Depending on the representation, for a SPxBasis B,
722  B.coSolve(x) computes
723  - \f$x \leftarrow rhs^TB^{-1}\f$ in the columnwise case and
724  - \f$x \leftarrow B^{-1}rhs\f$ in the rowwise case.
725 
726  Both can be seen uniformly as solving a linear system with the basis
727  matrix \p B and a right handside vector \p x aligned the same way as
728  the \em covectors of \p B.
729  */
730  void coSolve(Vector& x, const Vector& rhs)
731  {
732  if(rhs.dim() == 0)
733  {
734  x.clear();
735  return;
736  }
737 
738  if(!factorized)
740 
741  factor->solveLeft(x, rhs);
742  }
743  /// Sparse version of coSolve
744  void coSolve(SSVector& x, const SVector& rhs)
745  {
746  if(rhs.size() == 0)
747  {
748  x.clear();
749  return;
750  }
751 
752  if(!factorized)
754 
755  factor->solveLeft(x, rhs);
756  }
757  /// solves two systems in one call.
758  void coSolve(SSVector& x, Vector& y, const SVector& rhsx, SSVector& rhsy)
759  {
760  if(!factorized)
762 
763  factor->solveLeft(x, y, rhsx, rhsy);
764  }
765  /// Sparse version of solving two systems in one call.
766  void coSolve(SSVector& x, SSVector& y, const SVector& rhsx, SSVector& rhsy)
767  {
768  if(!factorized)
770 
771  factor->solveLeft(x, y, rhsx, rhsy);
772  }
773  /// solves three systems in one call. May be improved by using just one pass through the basis.
774  void coSolve(SSVector& x, Vector& y, Vector& z, const SVector& rhsx, SSVector& rhsy, SSVector& rhsz)
775  {
776  if(!factorized)
778 
779  factor->solveLeft(x, y, z, rhsx, rhsy, rhsz);
780  }
781  /// Sparse version of solving three systems in one call.
782  void coSolve(SSVector& x, SSVector& y, SSVector& z, const SVector& rhsx, SSVector& rhsy,
783  SSVector& rhsz)
784  {
785  if(!factorized)
787 
788  factor->solveLeft(x, y, z, rhsx, rhsy, rhsz);
789  }
790  //@}
791 
792 
793  //------------------------------------
794  /**@name Modification notification.
795  These methods must be called after the loaded LP has been modified.
796  */
797  //@{
798  /// inform SPxBasis, that \p n new rows had been added.
799  void addedRows(int n);
800  /// inform SPxBasis that row \p i had been removed.
801  void removedRow(int i);
802  /// inform SPxBasis that rows in \p perm with negative entry were removed.
803  void removedRows(const int perm[]);
804  /// inform SPxBasis that \p n new columns had been added.
805  void addedCols(int n);
806  /// inform SPxBasis that column \p i had been removed.
807  void removedCol(int i);
808  /// inform SPxBasis that columns in \p perm with negative entry were removed.
809  void removedCols(const int perm[]);
810  /// inform SPxBasis that a row had been changed.
811  void changedRow(int);
812  /// inform SPxBasis that a column had been changed.
813  void changedCol(int);
814  /// inform SPxBasis that a matrix entry had been changed.
815  void changedElement(int, int);
816  //@}
817 
818 
819  //--------------------------------
820  /**@name Miscellaneous */
821  //@{
822  /// performs basis update.
823  /** Changes the \p i 'th vector of the basis with the vector associated to
824  \p id. This includes:
825  - updating the factorization, or recomputing it from scratch by
826  calling \ref soplex::SPxSolver::factorize() "factorize()",
827  - resetting \ref soplex::SPxSolver::lastEntered() "lastEntered()",
828  - resetting \ref soplex::SPxSolver::lastIndex() "lastIndex()",
829  - resetting \ref soplex::SPxSolver::lastLeft() "lastLeft()",
830  - resetting \ref soplex::SPxSolver::lastUpdate() "lastUpdate()",
831  - resetting \ref soplex::SPxSolver::iterations() "iterations()".
832 
833  The basis descriptor is \em not \em modified, since #factor()
834  cannot know about how to set up the status of the involved variables
835  correctly.
836 
837  A vector \p enterVec may be passed for a fast ETA update of the LU
838  factorization associated to the basis. It must be initialized with
839  the solution vector \f$x\f$ of the right linear system \f$Bx = b\f$
840  with the entering vector as right-hand side vector \f$b\f$, where \f$B\f$
841  denotes the basis matrix. This can be computed using method #solve().
842  When using FAST updates, a vector \p eta may be passed for
843  improved performance. It must be initialized by a call to
844  factor->solveRightUpdate() as described in SLinSolver. The
845  implementation hidden behind FAST updates depends on the
846  SLinSolver implementation class.
847  */
848  virtual void change(int i, SPxId& id,
849  const SVector* enterVec, const SSVector* eta = 0);
850 
851  /** Load basis from \p in in MPS format. If \p rowNames and \p colNames
852  * are \c NULL, default names are used for the constraints and variables.
853  */
854  virtual bool readBasis(std::istream& in,
855  const NameSet* rowNames, const NameSet* colNames);
856 
857  /** Write basis to \p os in MPS format. If \p rowNames and \p colNames are
858  * \c NULL, default names are used for the constraints and variables.
859  */
860  virtual void writeBasis(std::ostream& os,
861  const NameSet* rownames, const NameSet* colnames, const bool cpxFormat = false) const;
862 
863  virtual void printMatrix() const;
864 
865  /** Prints current basis matrix to a file using the MatrixMarket format:
866  * row col value
867  * The filename is basis/basis[number].mtx where number is a parameter.
868  */
869  void printMatrixMTX(int number);
870 
871  /// checks if a Descriptor is valid for the current LP w.r.t. its bounds
872  virtual bool isDescValid(const Desc& ds);
873 
874  /// sets up basis.
875  /** Loads a Descriptor to the basis and sets up the basis matrix and
876  all vectors accordingly. The Descriptor must have the same number of
877  rows and columns as the currently loaded LP.
878  */
879  virtual void loadDesc(const Desc&);
880 
881  /// sets up linear solver to use.
882  /** If destroy is true, solver will be freed inside this object, e.g. in the destructor.
883  */
884  virtual void loadBasisSolver(SLinSolver* solver, const bool destroy = false);
885 
886  /// loads the LP \p lp to the basis.
887  /** This involves resetting all counters to 0 and setting up a regular
888  default basis consisting of slacks, artificial variables or bounds.
889  */
890  virtual void load(SPxSolver* lp, bool initSlackBasis = true);
891 
892  /// unloads the LP from the basis.
893  virtual void unLoad()
894  {
895  theLP = 0;
897  }
898 
899  /// invalidates actual basis.
900  /** This method makes the basis matrix and vectors invalid. The basis will
901  be reinitialized if needed.
902  */
903  void invalidate();
904 
905  /// Restores initial basis.
906  /** This method changes the basis to that present just after loading the LP
907  (see addedRows() and addedCols()). This may be necessary if a row or a
908  column is changed, since then the current basis may become singular.
909  */
910  void restoreInitialBasis();
911 
912  /// output basis entries.
913  void dump();
914 
915  /// consistency check.
916  bool isConsistent() const;
917 
918  /// time spent in updates
920  {
921  return theTime->time();
922  }
923  /// number of updates performed
925  {
926  return totalUpdateCount;
927  }
928 
929  /// returns statistical information in form of a string.
930  std::string statistics() const
931  {
932  std::stringstream s;
933  s << factor->statistics()
934 #ifdef MEASUREUPDATETIME
935  << "Updates : " << std::setw(10) << getTotalUpdateCount() << std::endl
936  << " Time spent : " << std::setw(10) << getTotalUpdateTime() << std::endl
937 #endif
938  ;
939 
940  return s.str();
941  }
942 
943  void setOutstream(SPxOut& newOutstream)
944  {
945  spxout = &newOutstream;
946  }
947  //@}
948 
949  //--------------------------------------
950  /**@name Constructors / Destructors */
951  //@{
952  /// default constructor.
954  /// copy constructor
955  SPxBasis(const SPxBasis& old);
956  /// assignment operator
957  SPxBasis& operator=(const SPxBasis& rhs);
958  /// destructor.
959  virtual ~SPxBasis();
960  //@}
961 
962 
963 protected:
964 
965  //--------------------------------------
966  /**@name Protected helpers */
967  //@{
968  /// loads \ref soplex::SPxBasis::matrix "matrix" according to the SPxId%s stored in \ref soplex::SPxBasis::theBaseId "theBaseId".
969  /** This method must be called whenever there is a chance, that the vector
970  pointers may have changed due to manipulations of the LP.
971  */
972  void loadMatrixVecs();
973 
974  /// resizes internal arrays.
975  /** When a new LP is loaded, the basis matrix and vectors become invalid
976  and possibly also of the wrong dimension. Hence, after loading an
977  LP, #reDim() is called to reset all arrays etc. accoriding to the
978  dimensions of the loaded LP.
979  */
980  void reDim();
981 
982  /// factorizes the basis matrix.
983  virtual void factorize();
984 
985  /// sets descriptor representation according to loaded LP.
986  void setRep();
987  //@}
988 
989 };
990 
991 
992 //
993 // Auxiliary functions.
994 //
995 
996 /// Pretty-printing of basis status.
997 std::ostream& operator<<(std::ostream& os,
998  const SPxBasis::SPxStatus& status);
999 
1000 
1001 } // namespace soplex
1002 
1003 /* reset the SOPLEX_DEBUG flag to its original value */
1004 #undef SOPLEX_DEBUG
1005 #ifdef SOPLEX_DEBUG_SPXBASIS
1006 #define SOPLEX_DEBUG
1007 #undef SOPLEX_DEBUG_SPXBASIS
1008 #endif
1009 
1010 #endif // _SPXBASIS_H_
int lastMem
memory needed after last fresh factorization
Definition: spxbasis.h:394
int iterDegenCheck
number of calls to change() since last degeneracy check
Definition: spxbasis.h:390
int nzCount
number of nonzeros in basis matrix
Definition: spxbasis.h:393
int iteration() const
returns number of basis changes since last load().
Definition: spxbasis.h:546
Vector & multWithBase(Vector &x) const
Vector-basis product.
Definition: spxbasis.cpp:984
void addedRows(int n)
inform SPxBasis, that n new rows had been added.
Basis is dual feasible.
Definition: spxbasis.h:95
const Status * colStatus(void) const
returns the array of column Statuses.
Definition: spxbasis.h:264
Real fillFactor
allowed increase in relative fill before refactorization
Definition: spxbasis.h:379
Status & coStatus(int i)
Definition: spxbasis.h:284
bool isSetup() const
Returns setup status.
Definition: ssvectorbase.h:121
Basis is not known to be dual nor primal feasible.
Definition: spxbasis.h:94
void coSolve(Vector &x, const Vector &rhs)
Cosolves linear system with basis matrix.
Definition: spxbasis.h:730
primal variable is fixed to both bounds
Definition: spxbasis.h:190
primal or dual variable is undefined
Definition: spxbasis.h:195
void invalidate()
invalidates actual basis.
Desc::Status dualColStatus(int i) const
dual Status for the i&#39;th column variable of the loaded LP.
Definition: spxbasis.cpp:69
virtual void printMatrix() const
Definition: spxbasis.cpp:729
bool isConsistent() const
consistency check.
Definition: spxdesc.cpp:135
void removedCols(const int perm[])
inform SPxBasis that columns in perm with negative entry were removed.
virtual std::string statistics() const =0
returns statistical information in form of a string.
void setMaxUpdates(int maxUp)
change maximum number of iterations until a refactorization is performed
Definition: spxbasis.h:451
int coDim() const
returns codimension.
Definition: spxbasis.h:234
virtual void solveRight(Vector &x, const Vector &b)=0
Solves .
int size() const
Number of used indices.
Definition: svectorbase.h:153
int updateCount
number of calls to change() since last factorize()
Definition: spxbasis.h:391
Basis is optimal, i.e. dual and primal feasible.
Definition: spxbasis.h:97
Status & rowStatus(int i)
Definition: spxbasis.h:239
virtual bool isDescValid(const Desc &ds)
checks if a Descriptor is valid for the current LP w.r.t. its bounds
Definition: spxbasis.cpp:115
DataArray< Status > * stat
basis&#39; status.
Definition: spxbasis.h:209
int lastIndex() const
returns index in basis where last update was done.
Definition: spxbasis.h:534
friend class SPxBasis
Definition: spxbasis.h:199
int dim() const
returns dimension.
Definition: spxbasis.h:229
virtual ~SPxBasis()
destructor.
Definition: spxbasis.cpp:1355
void changedCol(int)
inform SPxBasis that a column had been changed.
int lastNzCount
number of nonzeros in basis matrix after last fresh factorization
Definition: spxbasis.h:396
void solve4update(SSVector &x, Vector &y, const SVector &rhsx, SSVector &rhsy)
solves two systems in one call.
Definition: spxbasis.h:683
int lastUpdate() const
returns number of basis changes since last refactorization.
Definition: spxbasis.h:540
Status rowStatus(int i) const
returns status of row i.
Definition: spxbasis.h:244
Status coStatus(int i) const
returns status of covariable i.
Definition: spxbasis.h:289
Vector & multBaseWith(Vector &x) const
Basis-vector product.
Definition: spxbasis.cpp:1023
Set of strings.
Desc & operator=(const Desc &rhs)
assignment operator
Definition: spxdesc.cpp:67
void reSize(int rowDim, int colDim)
resets dimensions.
Definition: spxdesc.cpp:95
Real getFastCondition(int type=0)
Definition: spxbasis.cpp:1175
void dump() const
Prints out status.
Definition: spxdesc.cpp:114
Ids for LP columns.Class SPxColId provides DataKeys for the column indices of an SPxLP.
Definition: spxid.h:36
Desc::Status dualStatus(const SPxColId &id) const
dual Status for the column variable with ID id of the loaded LP.
Definition: spxbasis.cpp:34
Sparse Linear Solver virtual base class.
virtual void solve3right4update(SSVector &x, Vector &y, Vector &z, const SVector &b, SSVector &d, SSVector &e)=0
Solves , and .
bool factorized
true iff factor = matrix .
Definition: spxbasis.h:357
void changedElement(int, int)
inform SPxBasis that a matrix entry had been changed.
virtual void writeBasis(std::ostream &os, const NameSet *rownames, const NameSet *colnames, const bool cpxFormat=false) const
Definition: spxbasis.cpp:640
void setRep()
sets descriptor representation according to loaded LP.
Definition: spxbasis.cpp:326
Sparse Linear Solver virtual base class.Class SLinSolver provides a class for solving sparse linear s...
Definition: slinsolver.h:43
TimerFactory class.
Basis is singular.
Definition: spxbasis.h:93
Desc::Status dualRowStatus(int i) const
dual Status for the i&#39;th row variable of the loaded LP.
Definition: spxbasis.cpp:46
Real memFactor
allowed total increase in memory consumption before refactorization
Definition: spxbasis.h:382
int lastIterCount
number of calls to change() before halting the simplex
Definition: spxbasis.h:389
SPxStatus thestatus
current status of the basis.
Definition: spxbasis.h:412
int nCols() const
returns number of columns.
Definition: spxbasis.h:219
void changedRow(int)
inform SPxBasis that a row had been changed.
Status colStatus(int i) const
returns status of column i.
Definition: spxbasis.h:259
dual variable is left free, but unset
Definition: spxbasis.h:191
Wrapper for different output streams and verbosity levels.
void coSolve(SSVector &x, SSVector &y, SSVector &z, const SVector &rhsx, SSVector &rhsy, SSVector &rhsz)
Sparse version of solving three systems in one call.
Definition: spxbasis.h:782
void removedCol(int i)
inform SPxBasis that column i had been removed.
Real getExactCondition()
Definition: spxbasis.h:614
int maxUpdates
number of updates before refactorization.
Definition: spxbasis.h:366
primal variable is set to its upper bound
Definition: spxbasis.h:188
Generic Ids for LP rows or columns.Both SPxColIds and SPxRowIds may be treated uniformly as SPxIds: ...
Definition: spxid.h:85
virtual Real stability() const =0
returns a stability number (0: singularity, 1: perfect stability).
int getMaxUpdates() const
returns maximum number of updates before a refactorization is performed
Definition: spxbasis.h:458
Desc()
default constructor
Definition: spxbasis.h:316
SPxStatus status() const
returns current SPxStatus.
Definition: spxbasis.h:425
const SVector & baseVec(int i) const
returns the i&#39;th basic vector.
Definition: spxbasis.h:515
void reDim()
resizes internal arrays.
double Real
Definition: spxdefines.h:218
SPxId baseId(int i) const
returns the Id of the i&#39;th basis vector.
Definition: spxbasis.h:509
virtual void solveLeft(Vector &x, const Vector &b)=0
solves .
void setStatus(SPxStatus stat)
sets basis SPxStatus to stat.
Definition: spxbasis.h:431
Real lastFill
fill ratio that occured during last factorization
Definition: spxbasis.h:395
void removedRows(const int perm[])
inform SPxBasis that rows in perm with negative entry were removed.
void coSolve(SSVector &x, Vector &y, const SVector &rhsx, SSVector &rhsy)
solves two systems in one call.
Definition: spxbasis.h:758
#define MSG_DEBUG(x)
Definition: spxdefines.h:132
Wrapper for several output streams. A verbosity level is used to decide which stream to use and wheth...
Definition: spxout.h:63
dual variable is set to its upper bound
Definition: spxbasis.h:192
Sparse vectors.
virtual bool readBasis(std::istream &in, const NameSet *rowNames, const NameSet *colNames)
Definition: spxbasis.cpp:412
const T * get_const_ptr() const
get a const C pointer to the data.
Definition: dataarray.h:115
void solve4update(SSVector &x, SSVector &y, SSVector &y2, const SVector &rhsx, SSVector &rhsy, SSVector &rhsy2)
solves three systems in one call using only sparse data structures
Definition: spxbasis.h:710
primal variable is left free, but unset
Definition: spxbasis.h:189
void coSolve(SSVector &x, Vector &y, Vector &z, const SVector &rhsx, SSVector &rhsy, SSVector &rhsz)
solves three systems in one call. May be improved by using just one pass through the basis...
Definition: spxbasis.h:774
Semi sparse vector.
void clear()
Clears vector.
Definition: ssvectorbase.h:603
Real getEstimatedCondition()
Definition: spxbasis.h:608
Basis descriptor.
Definition: spxbasis.h:104
virtual void loadBasisSolver(SLinSolver *solver, const bool destroy=false)
sets up linear solver to use.
Definition: spxbasis.cpp:361
virtual Real time() const =0
SPxId lastout
lastLeft(): variable left the base last
Definition: spxbasis.h:402
Real minStab
minimum stability
Definition: spxbasis.h:404
Status & colStatus(int i)
Definition: spxbasis.h:254
SPxId & baseId(int i)
Definition: spxbasis.h:504
DataArray< Status > rowstat
status of rows.
Definition: spxbasis.h:207
void loadMatrixVecs()
loads matrix according to the SPxIds stored in theBaseId.
Definition: spxbasis.cpp:91
virtual void change(int i, SPxId &id, const SVector *enterVec, const SSVector *eta=0)
performs basis update.
Definition: spxbasis.cpp:773
Timer::TYPE timerType
type of timer (user or wallclock)
Definition: spxbasis.h:399
Debugging, floating point type and parameter definitions.
Simplex basis.Consider the linear program as provided from class SPxLP: where , and ...
Definition: spxbasis.h:82
Set of strings.Class NameSet implements a symbol or name table. It allows to store or remove names (i...
Definition: nameset.h:61
void restoreInitialBasis()
Restores initial basis.
Sequential object-oriented SimPlex.SPxSolver is an LP solver class using the revised Simplex algorith...
Definition: spxsolver.h:85
Real condition(int maxiters=10, Real tolerance=1e-6)
Definition: spxbasis.cpp:1081
const Status * status(void) const
returns the array of variable Statuses.
Definition: spxbasis.h:279
int dim() const
Dimension of vector.
Definition: vectorbase.h:217
void solve4update(SSVector &x, Vector &y, Vector &y2, const SVector &rhsx, SSVector &rhsy, SSVector &rhsy2)
solves three systems in one call.
Definition: spxbasis.h:699
Desc thedesc
the basis&#39; Descriptor
Definition: spxbasis.h:413
Everything should be within this namespace.
Desc & desc()
returns current basis Descriptor.
Definition: spxbasis.h:469
TYPE
types of timers
Definition: timer.h:99
SLinSolver * factor
Definition: spxbasis.h:355
void setOutstream(SPxOut &newOutstream)
Definition: spxbasis.h:943
void solve4update(SSVector &x, const SVector &rhs)
solves linear system with basis matrix.
Definition: spxbasis.h:669
void coSolve(SSVector &x, SSVector &y, const SVector &rhsx, SSVector &rhsy)
Sparse version of solving two systems in one call.
Definition: spxbasis.h:766
SPxId lastLeft() const
returns SPxId of last vector that left the basis.
Definition: spxbasis.h:528
SPxOut * spxout
message handler
Definition: spxbasis.h:415
int prevIteration() const
returns the number of iterations prior to the last break in execution
Definition: spxbasis.h:552
DataArray< SPxId > theBaseId
SPxIds of basic vectors.
Definition: spxbasis.h:345
primal variable is set to its lower bound
Definition: spxbasis.h:187
int totalUpdateCount
number of updates
Definition: spxbasis.h:392
int lastidx
lastIndex(): basis index where last update was done
Definition: spxbasis.h:403
Desc::Status dualStatus(const SPxId &id) const
dual Status for the variable with ID id of the loaded LP.
Definition: spxbasis.h:491
SPxSolver * theLP
the LP
Definition: spxbasis.h:343
const Status * coStatus(void) const
returns the array of covariable Statuses.
Definition: spxbasis.h:294
Saving LPs in a form suitable for SoPlex.
virtual void factorize()
factorizes the basis matrix.
Definition: spxbasis.cpp:928
Status status(int i) const
returns status of variable i.
Definition: spxbasis.h:274
void clear()
Set vector to 0.
Definition: vectorbase.h:262
void removedRow(int i)
inform SPxBasis that row i had been removed.
void coSolve(SSVector &x, const SVector &rhs)
Sparse version of coSolve.
Definition: spxbasis.h:744
dual variable is set to its lower bound
Definition: spxbasis.h:193
DataArray< Status > * costat
cobasis&#39; status.
Definition: spxbasis.h:210
int size() const
return nr. of elements.
Definition: dataarray.h:214
virtual void loadDesc(const Desc &)
sets up basis.
Definition: spxbasis.cpp:201
const Status * rowStatus(void) const
returns the array of row Statuses.
Definition: spxbasis.h:249
SPxStatus
basis status.
Definition: spxbasis.h:90
DataArray< Status > colstat
status of columns.
Definition: spxbasis.h:208
Sparse vectors.Class SVectorBase provides packed sparse vectors. Such are a sparse vectors...
Definition: dvectorbase.h:31
dual variable has two bounds
Definition: spxbasis.h:194
virtual void solve2right4update(SSVector &x, Vector &y, const SVector &b, SSVector &d)=0
Solves and .
SPxId lastEntered() const
returns SPxId of last vector included to the basis.
Definition: spxbasis.h:522
Ids for LP rows.Class SPxRowId provides DataKeys for the row indices of an SPxLP. ...
Definition: spxid.h:55
void solve(SSVector &x, const SVector &rhs)
Definition: spxbasis.h:646
void solve4update(SSVector &x, SSVector &y, const SVector &rhsx, SSVector &rhsy)
solves two systems in one call using only sparse data structures
Definition: spxbasis.h:691
void solve(Vector &x, const Vector &rhs)
Definition: spxbasis.h:632
std::string statistics() const
returns statistical information in form of a string.
Definition: spxbasis.h:930
Save arrays of data objects.
Status & status(int i)
Definition: spxbasis.h:269
Real getTotalUpdateTime() const
time spent in updates
Definition: spxbasis.h:919
int nRows() const
returns number of rows.
Definition: spxbasis.h:224
virtual void solveRight4update(SSVector &x, const SVector &b)=0
Solves . Possibly sets up internal data structures suitable for an optimized subsequent change() call...
virtual void load(SPxSolver *lp, bool initSlackBasis=true)
loads the LP lp to the basis.
Definition: spxbasis.cpp:345
virtual void unLoad()
unloads the LP from the basis.
Definition: spxbasis.h:893
SPxId lastin
lastEntered(): variable entered the base last
Definition: spxbasis.h:401
int iterCount
number of calls to change() since last manipulation
Definition: spxbasis.h:388
Status
Status of a variable.
Definition: spxbasis.h:185
LP has been proven to be primal unbounded.
Definition: spxbasis.h:98
Wrapper for the system time query methods.
Definition: timer.h:76
void printMatrixMTX(int number)
Definition: spxbasis.cpp:740
Timer * theTime
time spent in updates
Definition: spxbasis.h:398
int getTotalUpdateCount() const
number of updates performed
Definition: spxbasis.h:924
Real nonzeroFactor
allowed increase of nonzeros before refactorization.
Definition: spxbasis.h:373
Real stability() const
returns the stability of the basis matrix.
Definition: spxbasis.h:627
const Desc & desc() const
Definition: spxbasis.h:464
bool freeSlinSolver
true iff factor should be freed inside of this object
Definition: spxbasis.h:414
friend std::ostream & operator<<(std::ostream &os, const Status &stat)
Definition: spxdesc.cpp:144
Basis is primal feasible.
Definition: spxbasis.h:96
SPxSolver * solver() const
returns loaded solver.
Definition: spxbasis.h:564
int lastDegenCheck() const
returns the number of iterations since the last degeneracy check
Definition: spxbasis.h:558
bool matrixIsSetup
true iff the pointers in matrix are set up correctly.
Definition: spxbasis.h:349
void addedCols(int n)
inform SPxBasis that n new columns had been added.
LP has been proven to be primal infeasible.
Definition: spxbasis.h:99
No Problem has been loaded to the basis.
Definition: spxbasis.h:92
DataArray< const SVector *> matrix
pointers to the vectors of the basis matrix.
Definition: spxbasis.h:347