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