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