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-2015 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 "spxdefines.h"
35 #include "spxlp.h"
36 #include "svector.h"
37 #include "ssvector.h"
38 #include "dataarray.h"
39 #include "slinsolver.h"
40 #include "nameset.h"
41 #include "spxout.h"
42 #include "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 nonsingular 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 nonsigular matrix. The
69  dimension of the vectors is refered 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 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 dual variables 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 has no status
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 realtive fill before refactorization
376  /** When the real relative fill is bigger than fillFactor times lastFill
377  * the Basis will be refactorized.
378  */
380  /* Rank-1-updates to the basis may be performed via method #change(). In
381  this case, the factorization is updated, and the following members are
382  reset.
383  */
384  int iterCount; ///< number of calls to change() since last manipulation
385  int updateCount; ///< number of calls to change() since last factorize()
386  int totalUpdateCount; ///< number of updates
387  int nzCount; ///< number of nonzeros in basis matrix
388  int lastMem; ///< memory needed after last fresh factorization
389  Real lastFill; ///< fill ratio that occured during last factorization
390  int lastNzCount; ///< number of nonzeros in basis matrix after last fresh factorization
391 
392  Timer* theTime; ///< time spent in updates
393  Timer::TYPE timerType; ///< type of timer (user or wallclock)
394 
395  SPxId lastin; ///< lastEntered(): variable entered the base last
396  SPxId lastout; ///< lastLeft(): variable left the base last
397  int lastidx; ///< lastIndex(): basis index where last update was done
398  Real minStab; ///< minimum stability
399  //@}
400 
401 private:
402 
403  //------------------------------------
404  //**@name Private data */
405  //@{
406  SPxStatus thestatus; ///< current status of the basis.
407  Desc thedesc; ///< the basis' Descriptor
408  bool freeSlinSolver; ///< true iff factor should be freed inside of this object
409  SPxOut* spxout; ///< message handler
410 
411  //@}
412 
413 public:
414 
415  //------------------------------------------------
416  /**@name Status and Descriptor related Methods */
417  //@{
418  /// returns current SPxStatus.
420  {
421  return thestatus;
422  }
423 
424  /// sets basis SPxStatus to \p stat.
425  void setStatus(SPxStatus stat)
426  {
427 
428  if( thestatus != stat )
429  {
430 #ifdef SOPLEX_DEBUG
431  MSG_DEBUG( std::cout << "DBSTAT01 SPxBasis::setStatus(): status: "
432  << int(thestatus) << " (" << thestatus << ") -> "
433  << int(stat) << " (" << stat << ")" << std::endl; )
434 #endif
435 
436  thestatus = stat;
437  if( stat == NO_PROBLEM )
438  invalidate();
439  }
440  }
441 
442  // TODO control factorization frequency dynamically
443  /// change maximum number of iterations until a refactorization is performed
444  void setMaxUpdates( int maxUp )
445  {
446  assert(maxUp >= 0);
447  maxUpdates = maxUp;
448  }
449 
450  /// returns maximum number of updates before a refactorization is performed
451  int getMaxUpdates() const
452  {
453  return maxUpdates;
454  }
455 
456  ///
457  const Desc& desc() const
458  {
459  return thedesc;
460  }
461  /// returns current basis Descriptor.
463  {
464  return thedesc;
465  }
466 
467  /// dual Status for the \p i'th column variable of the loaded LP.
468  Desc::Status dualColStatus(int i) const;
469 
470  /// dual Status for the column variable with ID \p id of the loaded LP.
471  Desc::Status dualStatus(const SPxColId& id) const;
472 
473  /// dual Status for the \p i'th row variable of the loaded LP.
474  Desc::Status dualRowStatus(int i) const;
475 
476  /// dual Status for the row variable with ID \p id of the loaded LP.
477  Desc::Status dualStatus(const SPxRowId& id) const;
478 
479  /// dual Status for the variable with ID \p id of the loaded LP.
480  /** It is automatically detected, whether the \p id is one of a
481  row or a column variable, and the correct row or column status
482  is returned.
483  */
484  Desc::Status dualStatus(const SPxId& id) const
485  {
486  return id.isSPxRowId()
487  ? dualStatus(SPxRowId(id))
488  : dualStatus(SPxColId(id));
489  }
490  //@}
491 
492 
493  //-----------------------------------
494  /**@name Inquiry Methods */
495  //@{
496  ///
497  inline SPxId& baseId(int i)
498  {
499  return theBaseId[i];
500  }
501  /// returns the Id of the \p i'th basis vector.
502  inline SPxId baseId(int i) const
503  {
504  return theBaseId[i];
505  }
506 
507  /// returns the \p i'th basic vector.
508  const SVector& baseVec(int i) const
509  {
510  assert( matrixIsSetup );
511  return *matrix[i];
512  }
513 
514  /// returns SPxId of last vector included to the basis.
515  inline SPxId lastEntered() const
516  {
517  return lastin;
518  }
519 
520  /// returns SPxId of last vector that left the basis.
521  inline SPxId lastLeft() const
522  {
523  return lastout;
524  }
525 
526  /// returns index in basis where last update was done.
527  inline int lastIndex() const
528  {
529  return lastidx;
530  }
531 
532  /// returns number of basis changes since last refactorization.
533  inline int lastUpdate() const
534  {
535  return updateCount;
536  }
537 
538  /// returns number of basis changes since last \ref soplex::SPxBasis::load() "load()".
539  inline int iteration() const
540  {
541  return iterCount;
542  }
543  /// returns loaded solver.
544  inline SPxSolver* solver() const
545  {
546  return theLP;
547  }
548  //@}
549 
550  //-----------------------------------
551  /**@name Linear Algebra */
552  //@{
553  /// Basis-vector product.
554  /** Depending on the representation, for an SPxBasis B,
555  B.multBaseWith(x) computes
556  - \f$x \leftarrow Bx\f$ in the columnwise case, and
557  - \f$x \leftarrow x^TB\f$ in the rowwise case.
558 
559  Both can be seen uniformly as multiplying the basis matrix \p B with
560  a vector \p x aligned the same way as the \em vectors of \p B.
561  */
562  Vector& multBaseWith(Vector& x) const;
563 
564  /// Basis-vector product
565  void multBaseWith(SSVector& x, SSVector& result) const;
566 
567  /// Vector-basis product.
568  /** Depending on the representation, for a #SPxBasis B,
569  B.multWithBase(x) computes
570  - \f$x \leftarrow x^TB\f$ in the columnwise case and
571  - \f$x \leftarrow Bx\f$ in the rowwise case.
572 
573  Both can be seen uniformly as multiplying the basis matrix \p B with
574  a vector \p x aligned the same way as the \em covectors of \p B.
575  */
576  Vector& multWithBase(Vector& x) const;
577 
578  /// Vector-basis product
579  void multWithBase(SSVector& x, SSVector& result) const;
580 
581  /* compute an estimated condition number for the current basis matrix
582  * by computing estimates of the norms of B and B^-1 using the power method.
583  * maxiters and tolerance control the accuracy of the estimate.
584  */
585  Real condition(int maxiters = 10, Real tolerance = 1e-6);
586 
587  /* wrapper to compute an estimate of the condition number of the current basis matrix */
589  {
590  return condition(20, 1e-6);
591  }
592 
593  /* wrapper to compute the exact condition number of the current basis matrix */
595  {
596  return condition(1000, 1e-9);
597  }
598 
599  /// returns the stability of the basis matrix.
600  Real stability() const
601  {
602  return factor->stability();
603  }
604  ///
605  void solve(Vector& x, const Vector& rhs)
606  {
607  if (!factorized)
609  factor->solveRight(x, rhs);
610  }
611  ///
612  void solve(SSVector& x, const SVector& rhs)
613  {
614  if (!factorized)
616  factor->solveRight(x, rhs);
617  }
618  /// solves linear system with basis matrix.
619  /** Depending on the representation, for a SPxBasis B,
620  B.solve(x) computes
621  - \f$x \leftarrow B^{-1}rhs\f$ in the columnwise case and
622  - \f$x \leftarrow rhs^TB^{-1}\f$ in the rowwise case.
623 
624  Both can be seen uniformly as solving a linear system with the basis
625  matrix \p B and a right handside vector \p x aligned the same way as
626  the \em vectors of \p B.
627  */
628  void solve4update(SSVector& x, const SVector& rhs)
629  {
630  if (!factorized)
632  factor->solveRight4update(x, rhs);
633  }
634  /// solves two systems in one call.
635  void solve4update(SSVector& x, Vector& y, const SVector& rhsx, SSVector& rhsy)
636  {
637  if (!factorized)
639  factor->solve2right4update(x, y, rhsx, rhsy);
640  }
641  /// solves two systems in one call using only sparse data structures
642  void solve4update(SSVector& x, SSVector& y, const SVector& rhsx, SSVector& rhsy)
643  {
644  if (!factorized)
646  factor->solve2right4update(x, y, rhsx, rhsy);
647  }
648  /// solves three systems in one call.
649  void solve4update(SSVector& x, Vector& y, Vector& y2,
650  const SVector& rhsx, SSVector& rhsy, SSVector& rhsy2)
651  {
652  if (!factorized)
654  assert(rhsy.isSetup());
655  assert(rhsy2.isSetup());
656  factor->solve3right4update(x, y, y2, rhsx, rhsy, rhsy2);
657  }
658  /// solves three systems in one call using only sparse data structures
660  const SVector& rhsx, SSVector& rhsy, SSVector& rhsy2)
661  {
662  if (!factorized)
664  assert(rhsy.isSetup());
665  assert(rhsy2.isSetup());
666  factor->solve3right4update(x, y, y2, rhsx, rhsy, rhsy2);
667  }
668  /// Cosolves linear system with basis matrix.
669  /** Depending on the representation, for a SPxBasis B,
670  B.coSolve(x) computes
671  - \f$x \leftarrow rhs^TB^{-1}\f$ in the columnwise case and
672  - \f$x \leftarrow B^{-1}rhs\f$ in the rowwise case.
673 
674  Both can be seen uniformly as solving a linear system with the basis
675  matrix \p B and a right handside vector \p x aligned the same way as
676  the \em covectors of \p B.
677  */
678  void coSolve(Vector& x, const Vector& rhs)
679  {
680  if (!factorized)
682  factor->solveLeft(x, rhs);
683  }
684  /// Sparse version of coSolve
685  void coSolve(SSVector& x, const SVector& rhs)
686  {
687  if (!factorized)
689  factor->solveLeft(x, rhs);
690  }
691  /// solves two systems in one call.
692  void coSolve(SSVector& x, Vector& y, const SVector& rhsx, SSVector& rhsy)
693  {
694  if (!factorized)
696  factor->solveLeft(x, y, rhsx, rhsy);
697  }
698  /// Sparse version of solving two systems in one call.
699  void coSolve(SSVector& x, SSVector& y, const SVector& rhsx, SSVector& rhsy)
700  {
701  if (!factorized)
703  factor->solveLeft(x, y, rhsx, rhsy);
704  }
705  /// solves three systems in one call. May be improved by using just one pass through the basis.
706  void coSolve(SSVector& x, Vector& y, Vector& z, const SVector& rhsx, SSVector& rhsy, SSVector& rhsz)
707  {
708  if (!factorized)
710  factor->solveLeft(x, y, z, rhsx, rhsy, rhsz);
711  }
712  /// Sparse version of solving three systems in one call.
713  void coSolve(SSVector& x, SSVector& y, SSVector& z, const SVector& rhsx, SSVector& rhsy, SSVector& rhsz)
714  {
715  if (!factorized)
717  factor->solveLeft(x, y, z, rhsx, rhsy, rhsz);
718  }
719  //@}
720 
721 
722  //------------------------------------
723  /**@name Modification notification.
724  These methods must be called after the loaded LP has been modified.
725  */
726  //@{
727  /// inform SPxBasis, that \p n new rows had been added.
728  void addedRows(int n);
729  /// inform SPxBasis that row \p i had been removed.
730  void removedRow(int i);
731  /// inform SPxBasis that rows in \p perm with negative entry were removed.
732  void removedRows(const int perm[]);
733  /// inform SPxBasis that \p n new columns had been added.
734  void addedCols(int n);
735  /// inform SPxBasis that column \p i had been removed.
736  void removedCol(int i);
737  /// inform SPxBasis that columns in \p perm with negative entry were removed.
738  void removedCols(const int perm[]);
739  /// inform SPxBasis that a row had been changed.
740  void changedRow(int);
741  /// inform SPxBasis that a column had been changed.
742  void changedCol(int);
743  /// inform SPxBasis that a matrix entry had been changed.
744  void changedElement(int, int);
745  //@}
746 
747 
748  //--------------------------------
749  /**@name Miscellaneous */
750  //@{
751  /// performs basis update.
752  /** Changes the \p i 'th vector of the basis with the vector associated to
753  \p id. This includes:
754  - updating the factorization, or recomputing it from scratch by
755  calling \ref soplex::SPxSolver::factorize() "factorize()",
756  - resetting \ref soplex::SPxSolver::lastEntered() "lastEntered()",
757  - resetting \ref soplex::SPxSolver::lastIndex() "lastIndex()",
758  - resetting \ref soplex::SPxSolver::lastLeft() "lastLeft()",
759  - resetting \ref soplex::SPxSolver::lastUpdate() "lastUpdate()",
760  - resetting \ref soplex::SPxSolver::iterations() "iterations()".
761 
762  The basis descriptor is \em not \em modified, since #factor()
763  cannot know about how to set up the status of the involved variables
764  correctly.
765 
766  A vector \p enterVec may be passed for a fast ETA update of the LU
767  factorization associated to the basis. It must be initialized with
768  the solution vector \f$x\f$ of the right linear system \f$Bx = b\f$
769  with the entering vector as right-hand side vector \f$b\f$, where \f$B\f$
770  denotes the basis matrix. This can be computed using method #solve().
771  When using FAST updates, a vector \p eta may be passed for
772  improved performance. It must be initialized by a call to
773  factor->solveRightUpdate() as described in SLinSolver. The
774  implementation hidden behind FAST updates depends on the
775  SLinSolver implementation class.
776  */
777  virtual void change(int i, SPxId& id,
778  const SVector* enterVec, const SSVector* eta = 0);
779 
780  /** Load basis from \p in in MPS format. If \p rowNames and \p colNames
781  * are \c NULL, default names are used for the constraints and variables.
782  */
783  virtual bool readBasis(std::istream& in,
784  const NameSet* rowNames, const NameSet* colNames);
785 
786  /** Write basis to \p os in MPS format. If \p rowNames and \p colNames are
787  * \c NULL, default names are used for the constraints and variables.
788  */
789  virtual void writeBasis(std::ostream& os,
790  const NameSet* rownames, const NameSet* colnames, const bool cpxFormat = false) const;
791 
792  virtual void printMatrix() const;
793 
794  /** Prints current basis matrix to a file using the MatrixMarket format:
795  * row col value
796  * The filename is basis/basis[number].mtx where number is a parameter.
797  */
798  void printMatrixMTX(int number);
799 
800  /// checks if a Descriptor is valid for the current LP w.r.t. its bounds
801  virtual bool isDescValid(const Desc& ds);
802 
803  /// sets up basis.
804  /** Loads a Descriptor to the basis and sets up the basis matrix and
805  all vectors accordingly. The Descriptor must have the same number of
806  rows and columns as the currently loaded LP.
807  */
808  virtual void loadDesc(const Desc&);
809 
810  /// sets up linear solver to use.
811  /** If destroy is true, solver will be freed inside this object, e.g. in the destructor.
812  */
813  virtual void loadSolver(SLinSolver* solver, const bool destroy = false);
814 
815  /// loads the LP \p lp to the basis.
816  /** This involves resetting all counters to 0 and setting up a regular
817  default basis consisting of slacks, artificial variables or bounds.
818  */
819  virtual void load(SPxSolver* lp);
820 
821  /// unloads the LP from the basis.
822  virtual void unLoad()
823  {
824  theLP = 0;
826  }
827 
828  /// invalidates actual basis.
829  /** This method makes the basis matrix and vectors invalid. The basis will
830  be reinitialized if needed.
831  */
832  void invalidate();
833 
834  /// Restores initial basis.
835  /** This method changes the basis to that present just after loading the LP
836  (see addedRows() and addedCols()). This may be necessary if a row or a
837  column is changed, since then the current basis may become singular.
838  */
839  void restoreInitialBasis();
840 
841  /// output basis entries.
842  void dump();
843 
844  /// consistency check.
845  bool isConsistent() const;
846 
847  /// time spent in updates
849  {
850  return theTime->time();
851  }
852  /// number of updates performed
854  {
855  return totalUpdateCount;
856  }
857 
858  /// returns statistical information in form of a string.
859  std::string statistics() const
860  {
861  std::stringstream s;
862  s << factor->statistics()
863 #ifdef MEASUREUPDATETIME
864  << "Updates : " << std::setw(10) << getTotalUpdateCount() << std::endl
865  << " Time spent : " << std::setw(10) << getTotalUpdateTime() << std::endl
866 #endif
867  ;
868 
869  return s.str();
870  }
871 
872  void setOutstream(SPxOut& newOutstream)
873  {
874  spxout = &newOutstream;
875  }
876  //@}
877 
878  //--------------------------------------
879  /**@name Constructors / Destructors */
880  //@{
881  /// default constructor.
883  /// copy constructor
884  SPxBasis(const SPxBasis& old);
885  /// assignment operator
886  SPxBasis& operator=(const SPxBasis& rhs);
887  /// destructor.
888  virtual ~SPxBasis();
889  //@}
890 
891 
892 protected:
893 
894  //--------------------------------------
895  /**@name Protected helpers */
896  //@{
897  /// loads \ref soplex::SPxBasis::matrix "matrix" according to the SPxId%s stored in \ref soplex::SPxBasis::theBaseId "theBaseId".
898  /** This method must be called whenever there is a chance, that the vector
899  pointers may have changed due to manipulations of the LP.
900  */
901  void loadMatrixVecs();
902 
903  /// resizes internal arrays.
904  /** When a new LP is loaded, the basis matrix and vectors become invalid
905  and possibly also of the wrong dimension. Hence, after loading an
906  LP, #reDim() is called to reset all arrays etc. accoriding to the
907  dimensions of the loaded LP.
908  */
909  void reDim();
910 
911  /// factorizes the basis matrix.
912  virtual void factorize();
913 
914  /// sets descriptor representation according to loaded LP.
915  void setRep();
916  //@}
917 
918 };
919 
920 
921 //
922 // Auxiliary functions.
923 //
924 
925 /// Pretty-printing of basis status.
926 std::ostream& operator<<( std::ostream& os,
927  const SPxBasis::SPxStatus& status );
928 
929 
930 } // namespace soplex
931 
932 /* reset the SOPLEX_DEBUG flag to its original value */
933 #undef SOPLEX_DEBUG
934 #ifdef SOPLEX_DEBUG_SPXBASIS
935 #define SOPLEX_DEBUG
936 #undef SOPLEX_DEBUG_SPXBASIS
937 #endif
938 
939 #endif // _SPXBASIS_H_