Scippy

SoPlex

Sequential object-oriented simPlex

spxbasis.cpp
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-2017 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 #include <assert.h>
17 #include <cstdio>
18 #include <iostream>
19 #include <iomanip>
20 #include <sstream>
21 
22 #include "spxdefines.h"
23 #include "spxbasis.h"
24 #include "didxset.h"
25 #include "dvector.h"
26 #include "spxsolver.h"
27 #include "mpsinput.h"
28 #include "spxout.h"
29 #include "exceptions.h"
30 
31 namespace soplex
32 {
35 {
36  return dualColStatus(static_cast<SPxLP*>(theLP)->number(id));
37 }
38 
41 {
42  return dualRowStatus((static_cast<SPxLP*>(theLP))->number(id));
43 }
44 
47 {
48  assert(theLP != 0);
49 
50  if (theLP->rhs(i) < infinity)
51  {
52  if (theLP->lhs(i) > -infinity)
53  {
54  if (theLP->lhs(i) == theLP->rhs(i))
55  return Desc::D_FREE;
56  else
57  return Desc::D_ON_BOTH;
58  }
59  else
60  return Desc::D_ON_LOWER;
61  }
62  else if (theLP->lhs(i) > -infinity)
63  return Desc::D_ON_UPPER;
64  else
65  return Desc::D_UNDEFINED;
66 }
67 
70 {
71  assert(theLP != 0);
72 
73  if (theLP->SPxLP::upper(i) < infinity)
74  {
75  if (theLP->SPxLP::lower(i) > -infinity)
76  {
77  if (theLP->SPxLP::lower(i) == theLP->SPxLP::upper(i))
78  return Desc::D_FREE;
79  else
80  return Desc::D_ON_BOTH;
81  }
82  else
83  return Desc::D_ON_LOWER;
84  }
85  else if (theLP->SPxLP::lower(i) > -infinity)
86  return Desc::D_ON_UPPER;
87  else
88  return Desc::D_UNDEFINED;
89 }
90 
92 {
93  assert(theLP != 0);
94  assert(theLP->dim() == matrix.size());
95 
96  MSG_INFO3( (*spxout), (*spxout) << "IBASIS01 loadMatrixVecs() invalidates factorization" << std::endl; )
97 
98  int i;
99  nzCount = 0;
100  for (i = theLP->dim() - 1; i >= 0; --i)
101  {
102  matrix[i] = &theLP->vector(baseId(i));
103  nzCount += matrix[i]->size();
104  }
105  matrixIsSetup = true;
106  factorized = false;
107  if (factor != 0)
108  factor->clear();
109 }
110 
112 {
113 
114  assert(status() > NO_PROBLEM);
115  assert(theLP != 0);
116 
117  int basisdim;
118 
119  if ( ds.nRows() != theLP->nRows() || ds.nCols() != theLP->nCols() )
120  {
121  MSG_DEBUG( std::cout << "IBASIS20 Dimension mismatch\n" );
122  return false;
123  }
124 
125  basisdim = 0;
126  for ( int row = ds.nRows()-1; row >= 0; --row )
127  {
128  if ( ds.rowstat[row] >= 0 )
129  {
130  if ( ds.rowstat[row] != dualRowStatus(row) )
131  {
132  MSG_DEBUG( std::cout << "IBASIS21 Basic row " << row << " with incorrect dual status " << dualRowStatus(row) << "\n");
133  return false;
134  }
135  }
136  else
137  {
138  basisdim++;
139  if ( (ds.rowstat[row] == Desc::P_FIXED && theLP->SPxLP::lhs(row) != theLP->SPxLP::rhs(row))
140  || (ds.rowstat[row] == Desc::P_ON_UPPER && theLP->SPxLP::rhs(row) >= infinity)
141  || (ds.rowstat[row] == Desc::P_ON_LOWER && theLP->SPxLP::lhs(row) <= -infinity) )
142  {
143  MSG_DEBUG( std::cout << "IBASIS22 Nonbasic row with incorrect status: lhs=" << theLP->SPxLP::lhs(row) << ", rhs=" << theLP->SPxLP::rhs(row) << ", stat=" << ds.rowstat[row] << "\n");
144  return false;
145  }
146  }
147  }
148 
149  for ( int col = ds.nCols()-1; col >= 0; --col )
150  {
151  if ( ds.colstat[col] >= 0 )
152  {
153  if ( ds.colstat[col] != dualColStatus(col) )
154  {
155  MSG_DEBUG( std::cout << "IBASIS23 Basic column " << col << " with incorrect dual status " << ds.colstat[col] << " != " << dualColStatus(col) << "\n");
156  return false;
157  }
158  }
159  else
160  {
161  basisdim++;
162  if ( (ds.colstat[col] == Desc::P_FIXED && theLP->SPxLP::lower(col) != theLP->SPxLP::upper(col))
163  || (ds.colstat[col] == Desc::P_ON_UPPER && theLP->SPxLP::upper(col) >= infinity)
164  || (ds.colstat[col] == Desc::P_ON_LOWER && theLP->SPxLP::lower(col) <= -infinity) )
165  {
166  MSG_DEBUG( std::cout << "IBASIS24 Nonbasic column with incorrect status: lower=" << theLP->SPxLP::lower(col) << ", upper=" << theLP->SPxLP::upper(col) << ", stat=" << ds.colstat[col] << "\n");
167  return false;
168  }
169  }
170  }
171 
172  if ( basisdim != theLP->nCols() )
173  {
174  MSG_DEBUG( std::cout << "IBASIS25 Incorrect basis dimension " << basisdim << " != " << theLP->nCols() << "\n" );
175  return false;
176  }
177 
178  // basis descriptor valid
179  return true;
180 }
181 
182 /*
183  Loading a #Desc# into the basis can be done more efficiently, by
184  explicitely programming both cases, for the rowwise and for the columnwise
185  representation. This implementation hides this distinction in the use of
186  methods #isBasic()# and #vector()#.
187  */
188 void SPxBasis::loadDesc(const Desc& ds)
189 {
190  assert(status() > NO_PROBLEM);
191  assert(theLP != 0);
192  assert(ds.nRows() == theLP->nRows());
193  assert(ds.nCols() == theLP->nCols());
194 
195  SPxId none;
196  int i;
197  int j;
198  bool consistent = true;
199 
200  MSG_INFO3( (*spxout), (*spxout) << "IBASIS02 loading of Basis invalidates factorization" << std::endl; )
201 
202  lastin = none;
203  lastout = none;
204  lastidx = -1;
205  iterCount = 0;
206  updateCount = 0;
207 
208  if (&ds != &thedesc)
209  {
210  thedesc = ds;
211  setRep();
212  }
213 
214  assert(theLP->dim() == matrix.size());
215 
216  nzCount = 0;
217  for (j = i = 0; i < theLP->nRows(); ++i)
218  {
219  /* for columns and rows with D_... status, the correct D_... status depends on bounds and sides; if a basis
220  * descriptor is loaded after changing bounds or sides, e.g. in the refine() method, we have to correct them
221  */
222  if (thedesc.rowStatus(i) >= 0)
224  else if (thedesc.rowStatus(i) == SPxBasis::Desc::P_FIXED && theLP->SPxLP::lhs(i) != theLP->SPxLP::rhs(i))
225  {
226  if (theLP->SPxLP::lhs(i) > -infinity && theLP->SPxLP::maxRowObj(i) < 0.0)
228  else if (theLP->SPxLP::rhs(i) < infinity)
230  else
232  }
233 
234  if (theLP->isBasic(thedesc.rowStatus(i)))
235  {
236  assert(theLP->dim() == matrix.size());
237  assert(j <= matrix.size());
238 
239  if( j == matrix.size() )
240  {
241  // too many basic variables
242  consistent = false;
243  break;
244  }
245 
246  SPxRowId id = theLP->SPxLP::rId(i);
247  theBaseId[j] = id;
248  matrix[j] = &theLP->vector(id);
249  nzCount += matrix[j++]->size();
250  }
251  }
252 
253  for (i = 0; i < theLP->nCols(); ++i)
254  {
255  /* for columns and rows with D_... status, the correct D_... status depends on bounds and sides; if a basis
256  * descriptor is loaded after changing bounds or sides, e.g. in the refine() method, we have to correct them
257  */
258  if (thedesc.colStatus(i) >= 0)
260  else if (thedesc.colStatus(i) == SPxBasis::Desc::P_FIXED && theLP->SPxLP::lower(i) != theLP->SPxLP::upper(i))
261  {
262  if (theLP->SPxLP::lower(i) <= -infinity && theLP->SPxLP::upper(i) >= infinity)
264  else if (theLP->SPxLP::upper(i) >= infinity || (theLP->SPxLP::lower(i) > -infinity && theLP->SPxLP::maxObj(i) < 0.0))
266  else
268  }
269 
270  if (theLP->isBasic(thedesc.colStatus(i)))
271  {
272  assert(theLP->dim() == matrix.size());
273  assert(j <= matrix.size());
274 
275  if( j == matrix.size() )
276  {
277  // too many basic variables
278  consistent = false;
279  break;
280  }
281 
282  SPxColId id = theLP->SPxLP::cId(i);
283  theBaseId[j] = id;
284  matrix[j] = &theLP->vector(id);
285  nzCount += matrix[j++]->size();
286  }
287  }
288 
289  if( j < matrix.size() )
290  consistent = false; // not enough basic variables
291 
292  /* if dimensions are inconsistent, restore slack basis */
293  if( !consistent )
295 
296  assert(isDescValid(thedesc));
297 
298  matrixIsSetup = true;
299  factorized = false;
300  if (factor != 0)
301  factor->clear();
302 }
303 
305 {
306  assert(theLP != 0);
307 
308  reDim();
309  minStab = 0.0;
310 
311  if (theLP->rep() == SPxSolver::ROW)
312  {
315  }
316  else
317  {
320  }
321 }
322 
323 void SPxBasis::load(SPxSolver* lp, bool initSlackBasis)
324 {
325  assert(lp != 0);
326  theLP = lp;
327 
329 
330  setRep();
331 
332  if( initSlackBasis )
333  {
335  loadDesc(thedesc);
336  }
337 }
338 
339 void SPxBasis::loadBasisSolver(SLinSolver* p_solver, const bool destroy)
340 {
341  assert(!freeSlinSolver || factor != 0);
342 
343  setOutstream(*p_solver->spxout);
344 
345  MSG_INFO3( (*spxout), (*spxout) << "IBASIS03 loading of Solver invalidates factorization"
346  << std::endl; )
347 
348  if(freeSlinSolver)
349  {
350  delete factor;
351  factor = 0;
352  }
353 
354  factor = p_solver;
355  factorized = false;
356  factor->clear();
357  freeSlinSolver = destroy;
358 }
359 
360 
361 
362 
363 /**
364  * The specification is taken from the
365  *
366  * ILOG CPLEX 7.0 Reference Manual, Appendix E, Page 543.
367  *
368  * This routine should read valid BAS format files.
369  *
370  * @return true if the file was read correctly.
371  *
372  * Here is a very brief outline of the format:
373  *
374  * The format is in a form similar to an MPS file. The basic assumption is that all (column)
375  * variables are nonbasic at their lower bound and all row (variables) are basic; only the
376  * differences to this rule are given. Each data line contains an indicator, a variable name and
377  * possibly a row/constraint name. The following meaning applies with respect to the indicators:
378  *
379  * - XU: the variable is basic, the row is nonbasic at its upper bound
380  * - XL: the variable is basic, the row is nonbasic at its lower bound
381  * - UL: the variable is nonbasic and at its upper bound
382  * - LL: the variable is nonbasic and at its lower bound
383  *
384  * The CPLEX format contains an additional indicator 'BS', but this is unsupported here.
385  *
386  * Nonbasic variables without lower bound have the following default status for SoPlex:
387  * - at their upper bound if finite,
388  * - at zero if free.
389  */
391  std::istream& is,
392  const NameSet* rowNames,
393  const NameSet* colNames)
394 {
395  assert(theLP != 0);
396 
397  /* prepare names */
398  const NameSet* rNames = rowNames;
399  const NameSet* cNames = colNames;
400 
401  NameSet* p_colNames = 0;
402  NameSet* p_rowNames = 0;
403 
404  if ( colNames == 0 )
405  {
406  int nCols = theLP->nCols();
407  std::stringstream name;
408 
409  spx_alloc(p_colNames);
410  p_colNames = new (p_colNames) NameSet();
411  p_colNames->reMax(nCols);
412  for (int j = 0; j < nCols; ++j)
413  {
414  name << "x" << j;
415  DataKey key = theLP->colId(j);
416  p_colNames->add(key, name.str().c_str());
417  }
418  cNames = p_colNames;
419  }
420 
421  if ( rNames == 0 )
422  {
423  int nRows = theLP->nRows();
424  std::stringstream name;
425 
426  spx_alloc(p_rowNames);
427  p_rowNames = new (p_rowNames) NameSet();
428  p_rowNames->reMax(nRows);
429  for (int i = 0; i < nRows; ++i)
430  {
431  name << "C" << i;
432  DataKey key = theLP->rowId(i);
433  p_rowNames->add(key, name.str().c_str());
434  }
435  rNames = p_rowNames;
436  }
437 
438  /* load default basis if necessary */
439  if (status() == NO_PROBLEM)
440  load(theLP, false);
441 
442  /* initialize with standard settings */
443  Desc l_desc(thedesc);
444 
445  for (int i = 0; i < theLP->nRows(); i++)
446  l_desc.rowstat[i] = dualRowStatus(i);
447 
448  for (int i = 0; i < theLP->nCols(); i++)
449  {
450  if (theLP->SPxLP::lower(i) == theLP->SPxLP::upper(i))
451  l_desc.colstat[i] = Desc::P_FIXED;
452  else if (theLP->SPxLP::lower(i) <= -infinity && theLP->SPxLP::upper(i) >= infinity)
453  l_desc.colstat[i] = Desc::P_FREE;
454  else if (theLP->SPxLP::lower(i) <= -infinity)
455  l_desc.colstat[i] = Desc::P_ON_UPPER;
456  else
457  l_desc.colstat[i] = Desc::P_ON_LOWER;
458  }
459 
460  MPSInput mps(is);
461 
462  if (mps.readLine() && (mps.field0() != 0) && !strcmp(mps.field0(), "NAME"))
463  {
464  while (mps.readLine())
465  {
466  int c = -1;
467  int r = -1;
468 
469  if ((mps.field0() != 0) && !strcmp(mps.field0(), "ENDATA"))
470  {
472  break;
473  }
474  if ((mps.field1() == 0) || (mps.field2() == 0))
475  break;
476 
477  if ((c = cNames->number(mps.field2())) < 0)
478  break;
479 
480  if (*mps.field1() == 'X')
481  if (mps.field3() == 0 || (r = rNames->number(mps.field3())) < 0)
482  break;
483 
484  if (!strcmp(mps.field1(), "XU"))
485  {
486  l_desc.colstat[c] = dualColStatus(c);
487  if( theLP->LPRowSet::type(r) == LPRow::GREATER_EQUAL )
488  l_desc.rowstat[r] = Desc::P_ON_LOWER;
489  else if( theLP->LPRowSet::type(r) == LPRow::EQUAL )
490  l_desc.rowstat[r] = Desc::P_FIXED;
491  else
492  l_desc.rowstat[r] = Desc::P_ON_UPPER;
493  }
494  else if (!strcmp(mps.field1(), "XL"))
495  {
496  l_desc.colstat[c] = dualColStatus(c);
497  if( theLP->LPRowSet::type(r) == LPRow::LESS_EQUAL )
498  l_desc.rowstat[r] = Desc::P_ON_UPPER;
499  else if( theLP->LPRowSet::type(r) == LPRow::EQUAL )
500  l_desc.rowstat[r] = Desc::P_FIXED;
501  else
502  l_desc.rowstat[r] = Desc::P_ON_LOWER;
503  }
504  else if (!strcmp(mps.field1(), "UL"))
505  {
506  l_desc.colstat[c] = Desc::P_ON_UPPER;
507  }
508  else if (!strcmp(mps.field1(), "LL"))
509  {
510  l_desc.colstat[c] = Desc::P_ON_LOWER;
511  }
512  else
513  {
514  mps.syntaxError();
515  break;
516  }
517  }
518  }
519  if (!mps.hasError())
520  {
521  if (mps.section() == MPSInput::ENDATA)
522  {
523  // force basis to be different from NO_PROBLEM
524  // otherwise the basis will be overwritten at later stages.
526  loadDesc(l_desc);
527  }
528  else
529  mps.syntaxError();
530  }
531 
532  if ( rowNames == 0 )
533  {
534  p_rowNames->~NameSet();
535  spx_free(p_rowNames);
536  }
537  if ( colNames == 0 )
538  {
539  p_colNames->~NameSet();
540  spx_free(p_colNames);
541  }
542 
543 #ifndef NDEBUG
544  MSG_DEBUG( thedesc.dump() );
545 #endif
546 
547  return !mps.hasError();
548 }
549 
550 
551 /* Get row name - copied from spxmpswrite.cpp
552  *
553  * @todo put this in a common file and unify accross different formats (mps, lp, basis).
554  */
555 static const char* getRowName(
556  const SPxLP* lp,
557  int idx,
558  const NameSet* rnames,
559  char* buf)
560 {
561  assert(buf != 0);
562  assert(idx >= 0);
563  assert(idx < lp->nRows());
564 
565  if (rnames != 0)
566  {
567  DataKey key = lp->rId(idx);
568 
569  if (rnames->has(key))
570  return (*rnames)[key];
571  }
572  std::sprintf(buf, "C%d", idx);
573 
574  return buf;
575 }
576 
577 /* Get column name - copied from spxmpswrite.cpp
578  *
579  * @todo put this in a common file and unify accross different formats (mps, lp, basis).
580  */
581 static const char* getColName(
582  const SPxLP* lp,
583  int idx,
584  const NameSet* cnames,
585  char* buf)
586 {
587  assert(buf != 0);
588  assert(idx >= 0);
589  assert(idx < lp->nCols());
590 
591  if (cnames != 0)
592  {
593  DataKey key = lp->cId(idx);
594 
595  if (cnames->has(key))
596  return (*cnames)[key];
597  }
598  std::sprintf(buf, "x%d", idx);
599 
600  return buf;
601 }
602 
603 /* writes a file in MPS basis format to \p os.
604  *
605  * See SPxBasis::readBasis() for a short description of the format.
606  */
608  std::ostream& os,
609  const NameSet* rowNames,
610  const NameSet* colNames,
611  const bool cpxFormat
612  ) const
613 {
614  assert(theLP != 0);
615 
616  os.setf(std::ios::left);
617  os << "NAME soplex.bas\n";
618 
619  /* do not write basis if there is none */
620  if (status() == NO_PROBLEM)
621  {
622  os << "ENDATA" << std::endl;
623  return;
624  }
625 
626  /* start writing */
627  char buf[255];
628  int row = 0;
629  for (int col = 0; col < theLP->nCols(); col++)
630  {
631  if ( thedesc.colStatus(col) > 0 )
632  {
633  /* Find non basic row */
634  for (; row < theLP->nRows(); row++)
635  {
636  if ( thedesc.rowStatus(row) < 0 )
637  break;
638  }
639 
640  assert( row != theLP->nRows() );
641 
642  if( thedesc.rowStatus( row ) == Desc::P_ON_UPPER && (!cpxFormat || theLP->LPRowSet::type(row) == LPRow::RANGE) )
643  os << " XU ";
644  else
645  os << " XL ";
646 
647  os << std::setw(8) << getColName(theLP, col, colNames, buf);
648 
649  /* break in two parts since buf is reused */
650  os << " "
651  << getRowName(theLP, row, rowNames, buf)
652  << std::endl;
653 
654  row++;
655  }
656  else
657  {
658  if ( thedesc.colStatus( col ) == Desc::P_ON_UPPER )
659  {
660  os << " UL "
661  << getColName(theLP, col, colNames, buf)
662  << std::endl;
663  }
664  else
665  {
666  /* Default is all non-basic variables on lower bound (if finite) or at zero (if free).
667  * nothing to do in this case.
668  */
669  assert(theLP->lower(col) <= -infinity || thedesc.colStatus(col) == Desc::P_ON_LOWER || thedesc.colStatus(col) == Desc::P_FIXED);
670  assert(theLP->lower(col) > -infinity || theLP->upper(col) < infinity || thedesc.colStatus(col) == Desc::P_FREE);
671  }
672  }
673  }
674 
675 #ifndef NDEBUG
676  MSG_DEBUG( thedesc.dump() );
677 
678  // Check that we covered all nonbasic rows - the remaining should be basic.
679  for (; row < theLP->nRows(); row++)
680  {
681  if ( thedesc.rowStatus(row) < 0 )
682  break;
683  }
684  assert( row == theLP->nRows() );
685 
686 #endif // NDEBUG
687 
688  os << "ENDATA" << std::endl;
689 }
690 
692 {
693 
694  assert(matrixIsSetup);
695 
696  for( int i = 0; i < matrix.size(); i++ )
697  {
698  std::cout << "C" << i << "=" << *matrix[i] << std::endl;
699  }
700 }
701 
702 void SPxBasis::printMatrixMTX(int number)
703 {
704  int dim;
705  int nnz;
706  char filename[30];
707 
708  dim = matrix.size();
709  nnz = nzCount;
710  sprintf(filename, "basis/basis%d.mtx",number);
711  std::cout << "printing basis matrix to file " << filename << "\n";
712  FILE * basisfile;
713  basisfile = fopen (filename,"w");
714  // print marker necessary for reading the file in Matlab
715  fprintf(basisfile, "%%%%MatrixMarket matrix coordinate real general\n");
716  // print matrix information
717  fprintf(basisfile, "%d %d %d\n", dim, dim, nnz );
718  // print matrix data
719  for( int i = 0; i < matrix.size(); ++i )
720  {
721  for( int j = 0; j < baseVec(i).size(); ++j )
722  {
723  int idx = baseVec(i).index(j);
724  Real val = baseVec(i).value(j);
725  fprintf(basisfile, "%d %d %.13" REAL_FORMAT "\n",i+1,idx+1,val);
726  }
727  }
728  fclose (basisfile);
729 
730  return;
731 }
732 
734  int i,
735  SPxId& id,
736  const SVector* enterVec,
737  const SSVector* eta)
738 {
739 
740  assert(matrixIsSetup);
741  assert(!id.isValid() || (enterVec != 0));
742  assert(factor != 0);
743 
744  lastidx = i;
745  lastin = id;
746 
747  if (id.isValid() && i >= 0)
748  {
749  assert(enterVec != 0);
750 
751  // update the counter for nonzeros in the basis matrix
752  nzCount = nzCount - matrix[i]->size() + enterVec->size();
753  // let the new id enter the basis
754  matrix[i] = enterVec;
755  lastout = theBaseId[i];
756  theBaseId[i] = id;
757 
758  ++iterCount;
759  ++updateCount;
760 
761  MSG_DEBUG( std::cout << "factor_stats: iteration= " << iteration()
762  << " update= " << updateCount
763  << " total_update= " << totalUpdateCount
764  << " nonzero_B= " << nzCount
765  << " nonzero_LU= " << factor->memory()
766  << " factor_fill= " << lastFill
767  << " time= " << theLP->time()
768  << std::endl; )
769 
770  // never factorize? Just do it !
771  if (!factorized)
772  factorize();
773 
774  // too much memory growth ?
775  else if (Real(factor->memory()) > 1000 + factor->dim() + lastMem * memFactor)
776  {
777  MSG_INFO3( (*spxout), (*spxout) << "IBASIS04 memory growth factor triggers refactorization"
778  << " memory= " << factor->memory()
779  << " lastMem= " << lastMem
780  << " memFactor= " << memFactor
781  << std::endl; )
782  factorize();
783  }
784 
785  // relative fill too high ?
786  else if (Real(factor->memory()) > lastFill * Real(nzCount))
787  {
788  MSG_INFO3( (*spxout), (*spxout) << "IBASIS04 fill factor triggers refactorization"
789  << " memory= " << factor->memory()
790  << " nzCount= " << nzCount
791  << " lastFill= " << lastFill
792  << std::endl; )
793 
794  factorize();
795  }
796  // absolute fill in basis matrix too high ?
797  else if (nzCount > lastNzCount)
798  {
799  MSG_INFO3( (*spxout), (*spxout) << "IBASIS05 nonzero factor triggers refactorization"
800  << " nzCount= " << nzCount
801  << " lastNzCount= " << lastNzCount
802  << " nonzeroFactor= " << nonzeroFactor
803  << std::endl; )
804  factorize();
805  }
806  // too many updates ?
807  else if (updateCount >= maxUpdates)
808  {
809  MSG_INFO3( (*spxout), (*spxout) << "IBASIS06 update count triggers refactorization"
810  << " updateCount= " << updateCount
811  << " maxUpdates= " << maxUpdates
812  << std::endl; )
813  factorize();
814  }
815  else
816  {
817  try
818  {
819 #ifdef MEASUREUPDATETIME
820  theTime.start();
821 #endif
822  factor->change(i, *enterVec, eta);
824 #ifdef MEASUREUPDATETIME
825  theTime.stop();
826 #endif
827  }
828  catch( ... )
829  {
830  MSG_INFO3( (*spxout), (*spxout) << "IBASIS13 problems updating factorization; refactorizing basis"
831  << std::endl; )
832 
833 #ifdef MEASUREUPDATETIME
834  theTime.stop();
835 #endif
836 
837  // singularity was detected in update; we refactorize
838  factorize();
839 
840  // if factorize() detects singularity, an exception is thrown, hence at this point we have a regular basis
841  // and can try the update again
842  assert(status() >= SPxBasis::REGULAR);
843  try
844  {
845 #ifdef MEASUREUPDATETIME
846  theTime.start();
847 #endif
848  factor->change(i, *enterVec, eta);
850 #ifdef MEASUREUPDATETIME
851  theTime.stop();
852 #endif
853  }
854  // with a freshly factorized, regular basis, the update is unlikely to fail; if this happens nevertheless,
855  // we have to invalidate the basis to have the statuses correct
856  catch( const SPxException& F )
857  {
858  MSG_INFO3( (*spxout), (*spxout) << "IBASIS14 problems updating factorization; invalidating factorization"
859  << std::endl; )
860 
861 #ifdef MEASUREUPDATETIME
862  theTime.stop();
863 #endif
864 
865  factorized = false;
866  throw F;
867  }
868  }
869 
870  assert(minStab > 0.0);
871 
873  {
874  MSG_INFO3( (*spxout), (*spxout) << "IBASIS07 stability triggers refactorization"
875  << " stability= " << factor->stability()
876  << " minStab= " << minStab
877  << std::endl; )
878  factorize();
879  }
880  }
881  }
882  else
883  lastout = id;
884 }
885 
887 {
888 
889  assert(factor != 0);
890 
891  if (!matrixIsSetup)
892  loadDesc(thedesc);
893 
894  assert(matrixIsSetup);
895 
896  updateCount = 0;
897 
898  switch(factor->load(matrix.get_ptr(), matrix.size()))
899  {
900  case SLinSolver::OK :
901  if (status() == SINGULAR)
903 
904  factorized = true;
905  minStab = factor->stability();
906 
907  // This seems always to be about 1e-7
908  if (minStab > 1e-4)
909  minStab *= 0.001;
910  if (minStab > 1e-5)
911  minStab *= 0.01;
912  if (minStab > 1e-6)
913  minStab *= 0.1;
914  break;
915  case SLinSolver::SINGULAR :
917  factorized = false;
918  break;
919  default :
920  MSG_ERROR( std::cerr << "EBASIS08 error: unknown status of factorization.\n"; )
921  factorized = false;
922  throw SPxInternalCodeException("XBASIS01 This should never happen.");
923  }
924 
925  // get nonzero count of factorization
926  lastMem = factor->memory();
927  // compute fill ratio between factorization and basis matrix (multiplied with tolerance)
928  lastFill = fillFactor * Real(lastMem) / Real(nzCount > 0 ? nzCount : 1);
929  lastNzCount = int(nonzeroFactor * Real(nzCount > 0 ? nzCount : 1));
930 
931  if (status() == SINGULAR)
932  {
933  throw SPxStatusException("Cannot factorize singular matrix");
934  }
935 }
936 
938 {
939  assert(status() > SINGULAR);
940  assert(theLP->dim() == x.dim());
941 
942  int i;
943  DVector tmp(x);
944 
945  if (!matrixIsSetup)
946  (const_cast<SPxBasis*>(this))->loadDesc(thedesc);
947 
948  assert( matrixIsSetup );
949 
950  for (i = x.dim() - 1; i >= 0; --i)
951  x[i] = *(matrix[i]) * tmp;
952 
953  return x;
954 }
955 
956 void SPxBasis::multWithBase(SSVector& x, SSVector& result) const
957 {
958  assert(status() > SINGULAR);
959  assert(theLP->dim() == x.dim());
960  assert(x.dim() == result.dim());
961 
962  if (!matrixIsSetup)
963  (const_cast<SPxBasis*>(this))->loadDesc(thedesc);
964 
965  result.clear();
966 
967  assert(matrixIsSetup);
968 
969  for( int i = 0; i < x.dim(); ++i )
970  result.add(i, (*matrix[i]) * x);
971 
972  return;
973 }
974 
975 
977 {
978  assert(status() > SINGULAR);
979  assert(theLP->dim() == x.dim());
980 
981  int i;
982  DVector tmp(x);
983 
984  if (!matrixIsSetup)
985  (const_cast<SPxBasis*>(this))->loadDesc(thedesc);
986 
987  assert( matrixIsSetup );
988 
989  x.clear();
990  for (i = x.dim() - 1; i >= 0; --i)
991  {
992  if (tmp[i] != 0.0)
993  x.multAdd(tmp[i], *(matrix[i]));
994  }
995 
996  return x;
997 }
998 
999 void SPxBasis::multBaseWith(SSVector& x, SSVector& result) const
1000 {
1001  assert(status() > SINGULAR);
1002  assert(theLP->dim() == x.dim());
1003  assert(x.dim() == result.dim());
1004 
1005  if (!matrixIsSetup)
1006  (const_cast<SPxBasis*>(this))->loadDesc(thedesc);
1007 
1008  assert(matrixIsSetup);
1009 
1010  result.clear();
1011  for( int i = 0; i < x.size(); ++i )
1012  {
1013  result.multAdd(x[i], (*matrix[i]));
1014  }
1015 
1016  return;
1017 }
1018 
1019 /* compute an estimated condition number for the current basis matrix
1020  * by computing estimates of the norms of B and B^-1 using the power method.
1021  * maxiters and tolerance control the accuracy of the estimate.
1022  */
1023 Real SPxBasis::condition(int maxiters, Real tolerance)
1024 {
1025  int dimension = matrix.size();
1026  int i;
1027  int c;
1028  Real norm;
1029  Real norminv;
1030  Real norm1;
1031  Real norm2;
1032 
1033  SSVector x(dimension);
1034  SSVector y(dimension);
1035 
1036  // check whether a regular basis matrix is available
1037  if( status() < REGULAR )
1038  return 0;
1039 
1040  if (!matrixIsSetup)
1041  (const_cast<SPxBasis*>(this))->loadDesc(thedesc);
1042 
1043  // initialize vectors
1044  norm1 = 1.0 / (Real) dimension;
1045  for( i = 0; i < dimension; i++ )
1046  x.add(i, norm1);
1047  y = x;
1048 
1049  // compute norm of B
1050  for( c = 0; c < maxiters; ++c )
1051  {
1052  norm2 = norm1;
1053 
1054  // y = B*x
1055  multBaseWith(x, y);
1056  norm1 = y.length();
1057 
1058  // stop if converged
1059  if( spxAbs(norm1 - norm2) < tolerance * norm1 )
1060  break;
1061 
1062  // x = B^T*y and normalize
1063  multWithBase(y, x);
1064  norm2 = 1.0 / x.length();
1065  x *= norm2;
1066  }
1067  norm = norm1;
1068 
1069  // reinitialize vectors
1070  x.clear();
1071  y.clear();
1072  norm1 = 1.0 / (Real) dimension;
1073  for( i = 0; i < dimension; i++ )
1074  x.add(i, norm1);
1075  y = x;
1076 
1077  // compute norm of B^-1
1078  for( c = 0; c < maxiters; ++c )
1079  {
1080  norm2 = norm1;
1081 
1082  // y = B^-1*x
1083  factor->solveRight(x, y);
1084  norm1 = x.length();
1085 
1086  // stop if converged
1087  if( spxAbs(norm1 - norm2) < tolerance * norm1 )
1088  break;
1089 
1090  // x = B^-T*y and normalize
1091  factor->solveLeft(y, x);
1092  norm2 = 1.0 / y.length();
1093  y *= norm2;
1094  }
1095  norminv = norm1;
1096 
1097  return norm * norminv;
1098 }
1099 
1101 {
1102  assert(status() > NO_PROBLEM);
1103  assert(theLP != 0);
1104  assert(thedesc.nRows() == theLP->nRows());
1105  assert(thedesc.nCols() == theLP->nCols());
1106  assert(theLP->dim() == matrix.size());
1107 
1108  int i, basesize;
1109 
1110  // Dump regardless of the verbosity level if this method is called.
1111 
1112  std::cout << "DBASIS09 Basis entries:";
1113  basesize = 0;
1114  for (i = 0; i < theLP->nRows(); ++i)
1115  {
1116  if (theLP->isBasic(thedesc.rowStatus(i)))
1117  {
1118  if(basesize % 10 == 0)
1119  std::cout << std::endl << "DBASIS10 ";
1120  SPxRowId id = theLP->SPxLP::rId(i);
1121  std::cout << "\tR" << theLP->number(id);
1122  basesize++;
1123  }
1124  }
1125 
1126  for (i = 0; i < theLP->nCols(); ++i)
1127  {
1128  if (theLP->isBasic(thedesc.colStatus(i)))
1129  {
1130  if(basesize % 10 == 0)
1131  std::cout << std::endl << "DBASIS11 ";
1132  SPxColId id = theLP->SPxLP::cId(i);
1133  std::cout << "\tC" << theLP->number(id);
1134  basesize++;
1135  }
1136  }
1137  std::cout << std::endl;
1138 
1139  assert(basesize == matrix.size());
1140 }
1141 
1142 
1144 {
1145 #ifdef ENABLE_CONSISTENCY_CHECKS
1146  int primals = 0;
1147  int i;
1148 
1149  if (status() > NO_PROBLEM)
1150  {
1151  if (theLP == 0)
1152  return MSGinconsistent("SPxBasis");
1153 
1154  if (theBaseId.size() != theLP->dim() || matrix.size() != theLP->dim())
1155  return MSGinconsistent("SPxBasis");
1156 
1157  if (thedesc.nCols() != theLP->nCols() || thedesc.nRows() != theLP->nRows())
1158  return MSGinconsistent("SPxBasis");
1159 
1160  for (i = 0; i < thedesc.nRows(); ++i)
1161  {
1162  if (thedesc.rowStatus(i) >= 0)
1163  {
1164  if (thedesc.rowStatus(i) != dualRowStatus(i))
1165  return MSGinconsistent("SPxBasis");
1166  }
1167  else
1168  ++primals;
1169  }
1170 
1171  for (i = 0; i < thedesc.nCols(); ++i)
1172  {
1173  if (thedesc.colStatus(i) >= 0)
1174  {
1175  if (thedesc.colStatus(i) != dualColStatus(i))
1176  return MSGinconsistent("SPxBasis");
1177  }
1178  else
1179  ++primals;
1180  }
1181  if (primals != thedesc.nCols())
1182  return MSGinconsistent("SPxBasis");
1183  }
1184  return thedesc.isConsistent() && theBaseId.isConsistent()
1185  && matrix.isConsistent() && factor->isConsistent();
1186 #else
1187  return true;
1188 #endif // CONSISTENCY_CHECKS
1189 }
1190 
1192  : theLP (0)
1193  , matrixIsSetup (false)
1194  , factor (0)
1195  , factorized (false)
1196  , maxUpdates (200)
1197  , nonzeroFactor(10.0)
1198  , fillFactor(5.0)
1199  , memFactor(1.5)
1200  , iterCount (0)
1201  , lastIterCount(0)
1202  , iterDegenCheck(0)
1203  , updateCount(0)
1204  , totalUpdateCount(0)
1205  , nzCount (1)
1206  , lastMem(0)
1207  , lastFill(0)
1208  , lastNzCount(0)
1209  , theTime(0)
1210  , timerType(ttype)
1211  , lastidx(0)
1212  , minStab(0.0)
1213  , thestatus (NO_PROBLEM)
1214  , freeSlinSolver(false)
1215  , spxout(0)
1216 {
1217  // info: is not consistent at this moment, e.g. because theLP == 0
1218 
1220 }
1221 
1222 /**@warning Do not change the LP object.
1223  * Only pointer to that object is copied.
1224  * Hint: no problem, we use this function for copy
1225  * constructor of SPxSolver
1226  */
1228  : theLP(old.theLP)
1229  , theBaseId(old.theBaseId)
1230  , matrix(old.matrix)
1232  , factor(old.factor)
1233  , factorized(old.factorized)
1234  , maxUpdates(old.maxUpdates)
1236  , fillFactor(old.fillFactor)
1237  , memFactor(old.memFactor)
1238  , iterCount(old.iterCount)
1241  , updateCount(old.updateCount)
1243  , nzCount(old.nzCount)
1244  , lastMem(old.lastMem)
1245  , lastFill(old.lastFill)
1246  , lastNzCount(old.lastNzCount)
1247  , theTime(old.theTime)
1248  , timerType(old.timerType)
1249  , lastin(old.lastin)
1250  , lastout(old.lastout)
1251  , lastidx(old.lastidx)
1252  , minStab(old.minStab)
1253  , thestatus(old.thestatus)
1254  , thedesc(old.thedesc)
1255  , spxout(old.spxout)
1256 {
1257 
1258  this->factor = old.factor->clone();
1259  freeSlinSolver = true;
1260 
1261  assert(SPxBasis::isConsistent());
1262 }
1263 
1265 {
1266 
1267  assert(!freeSlinSolver || factor != 0);
1268 
1269  if(freeSlinSolver)
1270  {
1271  delete factor;
1272  factor = 0;
1273  }
1274 
1275  spx_free(theTime);
1276 }
1277 
1278 
1279 /**@warning Note that we do not create a deep copy of the corresponding SPxSolver object.
1280  * Only the reference to that object is copied.
1281  */
1283 {
1284 
1285  assert(!freeSlinSolver || factor != 0);
1286 
1287  if (this != &rhs)
1288  {
1289  theLP = rhs.theLP;
1290  theBaseId = rhs.theBaseId;
1291  matrix = rhs.matrix;
1293 
1294  if(freeSlinSolver)
1295  {
1296  delete factor;
1297  factor = 0;
1298  }
1299  factor = rhs.factor->clone();
1300  freeSlinSolver = true;
1301 
1302  factorized = rhs.factorized;
1303  maxUpdates = rhs.maxUpdates;
1305  fillFactor = rhs.fillFactor;
1306  memFactor = rhs.memFactor;
1307  iterCount = rhs.iterCount;
1308  nzCount = rhs.nzCount;
1309  lastFill = rhs.lastFill;
1310  lastNzCount = rhs.lastNzCount;
1311  lastin = rhs.lastin;
1312  lastout = rhs.lastout;
1313  lastidx = rhs.lastidx;
1314  minStab = rhs.minStab;
1315  thestatus = rhs.thestatus;
1316  thedesc = rhs.thedesc;
1317 
1318  assert(SPxBasis::isConsistent());
1319  }
1320 
1321  return *this;
1322 }
1323 
1324 
1325 //
1326 // Auxiliary functions.
1327 //
1328 
1329 // Pretty-printing of basis status.
1330 std::ostream& operator<<( std::ostream& os,
1331  const SPxBasis::SPxStatus& status )
1332 {
1333  switch ( status )
1334  {
1335  case SPxBasis::NO_PROBLEM:
1336  os << "NO_PROBLEM";
1337  break;
1338  case SPxBasis::SINGULAR:
1339  os << "SINGULAR";
1340  break;
1341  case SPxBasis::REGULAR:
1342  os << "REGULAR";
1343  break;
1344  case SPxBasis::DUAL:
1345  os << "DUAL";
1346  break;
1347  case SPxBasis::PRIMAL:
1348  os << "PRIMAL";
1349  break;
1350  case SPxBasis::OPTIMAL:
1351  os << "OPTIMAL";
1352  break;
1353  case SPxBasis::UNBOUNDED:
1354  os << "UNBOUNDED";
1355  break;
1356  case SPxBasis::INFEASIBLE:
1357  os << "INFEASIBLE";
1358  break;
1359  default:
1360  os << "?other?";
1361  break;
1362  }
1363  return os;
1364 }
1365 
1366 
1367 } // namespace soplex
const VectorBase< R > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:219
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
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:3909
virtual Status change(int idx, const SVector &subst, const SSVector *eta=0)=0
Substitute column idx with subst.
int iteration() const
returns number of basis changes since last load().
Definition: spxbasis.h:545
Exception class for things that should NEVER happen.This class is derived from the SoPlex exception b...
Definition: exceptions.h:109
Vector & multWithBase(Vector &x) const
Vector-basis product.
Definition: spxbasis.cpp:937
Basis is dual feasible.
Definition: spxbasis.h:95
SPxRowId rId(int n) const
Returns the row identifier for row n.
Definition: spxlpbase.h:542
Real fillFactor
allowed increase in relative fill before refactorization
Definition: spxbasis.h:379
virtual Status load(const SVector *vec[], int dim)=0
loads dim column vectors vec into the solver.
Basis is not known to be dual nor primal feasible.
Definition: spxbasis.h:94
virtual void clear()=0
unloads any matrix.
primal variable is fixed to both bounds
Definition: spxbasis.h:190
SPxOut * spxout
message handler
Definition: slinsolver.h:209
primal or dual variable has no status
Definition: spxbasis.h:195
const VectorBase< R > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:456
Desc::Status dualColStatus(int i) const
dual Status for the i&#39;th column variable of the loaded LP.
Definition: spxbasis.cpp:69
SPxOut * spxout
message handler
Definition: spxsolver.h:426
virtual void printMatrix() const
Definition: spxbasis.cpp:691
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
bool isConsistent() const
consistency check.
Definition: spxdesc.cpp:130
Read MPS format files.
static const char * getRowName(const SPxLP *lp, int idx, const NameSet *rnames, char *buf)
Definition: spxbasis.cpp:555
void reMax(int newmax=0)
resets max() to newmax.
Definition: nameset.cpp:138
virtual void solveRight(Vector &x, const Vector &b)=0
Solves .
int size() const
Number of used indices.
Definition: svectorbase.h:152
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
virtual int dim() const =0
returns dimension of loaded matrix.
Dymnamic index set.
Exception classes for SoPlex.
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:111
DataArray< Status > * stat
basis&#39; status.
Definition: spxbasis.h:209
virtual ~SPxBasis()
destructor.
Definition: spxbasis.cpp:1264
void syntaxError()
Definition: mpsinput.h:198
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:522
int lastNzCount
number of nonzeros in basis matrix after last fresh factorization
Definition: spxbasis.h:396
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:1035
Vector & multBaseWith(Vector &x) const
Basis-vector product.
Definition: spxbasis.cpp:976
bool hasError() const
Definition: mpsinput.h:162
R & value(int n)
Reference to value of n &#39;th nonzero.
Definition: svectorbase.h:254
void dump() const
Prints out status.
Definition: spxdesc.cpp:113
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
Real time() const
time spent in last call to method solve().
Definition: spxsolver.h:2095
static const char * getColName(const SPxLP *lp, int idx, const NameSet *cnames, char *buf)
Definition: spxbasis.cpp:581
bool factorized
true iff factor = matrix .
Definition: spxbasis.h:357
virtual void writeBasis(std::ostream &os, const NameSet *rownames, const NameSet *colnames, const bool cpxFormat=false) const
Definition: spxbasis.cpp:607
void setRep()
sets descriptor representation according to loaded LP.
Definition: spxbasis.cpp:304
Sparse Linear Solver virtual base class.Class SLinSolver provides a class for solving sparse linear s...
Definition: slinsolver.h:43
#define REAL_FORMAT
Definition: spxdefines.h:218
rowwise representation.
Definition: spxsolver.h:107
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
SPxColId cId(int n) const
Returns the column identifier for column n.
Definition: spxlpbase.h:548
int nCols() const
returns number of columns.
Definition: spxbasis.h:219
Entry identifier class for items of a DataSet.Every item in a DataSet is assigned a DataKey by which ...
Definition: datakey.h:46
dual variable is left free, but unset
Definition: spxbasis.h:191
Wrapper for different output streams and verbosity levels.
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:151
virtual void start()=0
start timer, resume accounting user, system and real time.
int dim() const
Dimension of VectorBase.
Definition: ssvectorbase.h:559
virtual Real stop()=0
stop timer, return accounted user time.
void spx_alloc(T &p, int n=1)
Allocate memory.
Definition: spxalloc.h:48
int maxUpdates
number of updates before refactorization.
Definition: spxbasis.h:366
bool readLine()
reads an MPS format data line and parse the fields.
Definition: mpsinput.cpp:57
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).
SPxStatus status() const
returns current SPxStatus.
Definition: spxbasis.h:425
virtual Status status() const =0
returns the Status of the SLinSolver.
const SVector & baseVec(int i) const
returns the i&#39;th basic vector.
Definition: spxbasis.h:514
void reDim()
resizes internal arrays.
double Real
Definition: spxdefines.h:214
virtual SLinSolver * clone() const =0
clone function for polymorphism
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
#define MSG_DEBUG(x)
Definition: spxdefines.h:128
int & index(int n)
Reference to index of n &#39;th nonzero.
Definition: svectorbase.h:236
Section section() const
Definition: mpsinput.h:140
std::ostream & operator<<(std::ostream &s, const VectorBase< R > &vec)
Output operator.
Definition: basevectors.h:1151
SPxColId colId(int i) const
ColId of i &#39;th column.
Definition: spxsolver.h:2232
Dynamic vectors.
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:110
dual variable is set to its upper bound
Definition: spxbasis.h:192
virtual bool readBasis(std::istream &in, const NameSet *rowNames, const NameSet *colNames)
Definition: spxbasis.cpp:390
main LP solver class
bool isBasic(SPxBasis::Desc::Status stat) const
does stat describe a basic index ?
Definition: spxsolver.h:1223
primal variable is left free, but unset
Definition: spxbasis.h:189
const VectorBase< R > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:253
const char * field3() const
Definition: mpsinput.h:150
void clear()
Clears vector.
Definition: ssvectorbase.h:599
Basis descriptor.
Definition: spxbasis.h:104
virtual void loadBasisSolver(SLinSolver *solver, const bool destroy=false)
sets up linear solver to use.
Definition: spxbasis.cpp:339
void add(const char *str)
Definition: nameset.cpp:25
SPxId lastout
lastLeft(): variable left the base last
Definition: spxbasis.h:402
const char * field0() const
Definition: mpsinput.h:144
Real minStab
minimum stability
Definition: spxbasis.h:404
SSVectorBase< R > & multAdd(S xx, const SVectorBase< T > &vec)
Addition of a scaled vector.
Definition: basevectors.h:445
static Timer * createTimer(Timer::TYPE ttype)
create timers and allocate memory for them
Definition: timerfactory.h:43
Status & colStatus(int i)
Definition: spxbasis.h:254
void setSection(Section p_section)
Definition: mpsinput.h:171
SPxId & baseId(int i)
Definition: spxbasis.h:503
DataArray< Status > rowstat
status of rows.
Definition: spxbasis.h:207
virtual bool isConsistent() const =0
consistency check.
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
Definition: spxdefines.h:118
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:733
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.
Simplex basis.
void dump()
output basis entries.
Definition: spxbasis.cpp:1100
Sequential object-oriented SimPlex.SPxSolver is an LP solver class using the revised Simplex algorith...
Definition: spxsolver.h:84
Real condition(int maxiters=10, Real tolerance=1e-6)
Definition: spxbasis.cpp:1023
VectorBase< R > & multAdd(const S &x, const VectorBase< T > &vec)
Addition of scaled vector.
Definition: vectorbase.h:410
int dim() const
Dimension of vector.
Definition: vectorbase.h:215
Exception base class.This class implements a base class for our SoPlex exceptions We provide a what()...
Definition: exceptions.h:32
int size() const
Returns the number of nonzeros.
Definition: ssvectorbase.h:199
Desc thedesc
the basis&#39; Descriptor
Definition: spxbasis.h:413
Everything should be within this namespace.
virtual int memory() const =0
returns current memory consumption.
TYPE
types of timers
Definition: timer.h:99
SLinSolver * factor
Definition: spxbasis.h:355
void setOutstream(SPxOut &newOutstream)
Definition: spxbasis.h:916
Saving LPs in a form suitable for SoPlex.Class SPxLPBase provides the data structures required for sa...
Definition: spxlpbase.h:80
SPxOut * spxout
message handler
Definition: spxbasis.h:415
SPxBasis & operator=(const SPxBasis &rhs)
assignment operator
Definition: spxbasis.cpp:1282
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
SPxSolver * theLP
the LP
Definition: spxbasis.h:343
virtual void factorize()
factorizes the basis matrix.
Definition: spxbasis.cpp:886
void clear()
Set vector to 0.
Definition: vectorbase.h:260
dual variable is set to its lower bound
Definition: spxbasis.h:193
DataArray< Status > * costat
cobasis&#39; status.
Definition: spxbasis.h:210
virtual void loadDesc(const Desc &)
sets up basis.
Definition: spxbasis.cpp:188
Real length() const
Floating point approximation of euclidian norm (without any approximation guarantee).
Definition: ssvectorbase.h:547
SPxStatus
basis status.
Definition: spxbasis.h:90
const char * field1() const
Definition: mpsinput.h:146
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:157
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
Exception class for status exceptions during the computationsThis class is derived from the SoPlex ex...
Definition: exceptions.h:89
The loaded matrix is singular.
Definition: slinsolver.h:60
Ids for LP rows.Class SPxRowId provides DataKeys for the row indices of an SPxLP. ...
Definition: spxid.h:55
#define MSGinconsistent(name)
Definition: spxdefines.h:122
const SVector & vector(int i) const
i &#39;th vector.
Definition: spxsolver.h:1117
const char * field2() const
Definition: mpsinput.h:148
int nRows() const
returns number of rows.
Definition: spxbasis.h:224
virtual void load(SPxSolver *lp, bool initSlackBasis=true)
loads the LP lp to the basis.
Definition: spxbasis.cpp:323
SPxId lastin
lastEntered(): variable entered the base last
Definition: spxbasis.h:401
int number(const DataKey &pkey) const
returns number of name with DataKey pkey in NameSet.
Definition: nameset.h:212
int iterCount
number of calls to change() since last manipulation
Definition: spxbasis.h:388
Status
Status of a variable.
Definition: spxbasis.h:185
void add(int i, R x)
Adds nonzero (i, x) to SSVectorBase.
Definition: ssvectorbase.h:208
LP has been proven to be primal unbounded.
Definition: spxbasis.h:98
void printMatrixMTX(int number)
Definition: spxbasis.cpp:702
Timer * theTime
time spent in updates
Definition: spxbasis.h:398
const VectorBase< R > & lower() const
Returns (internal and possibly scaled) lower bound vector.
Definition: spxlpbase.h:483
~NameSet()
destructor.
Definition: nameset.cpp:259
Real nonzeroFactor
allowed increase of nonzeros before refactorization.
Definition: spxbasis.h:373
SPxRowId rowId(int i) const
RowId of i &#39;th inequality.
Definition: spxsolver.h:2227
SPxBasis(Timer::TYPE ttype=Timer::USER_TIME)
default constructor.
Definition: spxbasis.cpp:1191
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:468
bool freeSlinSolver
true iff factor should be freed inside of this object
Definition: spxbasis.h:414
void spx_free(T &p)
Release memory.
Definition: spxalloc.h:109
bool has(int pnum) const
does NameSet has a name with number pnum?
Definition: nameset.h:231
bool isConsistent() const
consistency check.
Definition: spxbasis.cpp:1143
Basis is primal feasible.
Definition: spxbasis.h:96
bool matrixIsSetup
true iff the pointers in matrix are set up correctly.
Definition: spxbasis.h:349
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