1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the class library                   */
4    	/*       SoPlex --- the Sequential object-oriented simPlex.                  */
5    	/*                                                                           */
6    	/*    Copyright (C) 1996-2022 Konrad-Zuse-Zentrum                            */
7    	/*                            fuer Informationstechnik Berlin                */
8    	/*                                                                           */
9    	/*  SoPlex is distributed under the terms of the ZIB Academic Licence.       */
10   	/*                                                                           */
11   	/*  You should have received a copy of the ZIB Academic License              */
12   	/*  along with SoPlex; see the file COPYING. If not email to soplex@zib.de.  */
13   	/*                                                                           */
14   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15   	
16   	#include <assert.h>
17   	#include <iostream>
18   	#include <sstream>
19   	
20   	#include "soplex/spxdefines.h"
21   	// #include "soplex.h"
22   	#include "soplex/spxpricer.h"
23   	#include "soplex/spxratiotester.h"
24   	#include "soplex/spxstarter.h"
25   	#include "soplex/spxout.h"
26   	#include "soplex/timerfactory.h"
27   	
28   	namespace soplex
29   	{
30   	template <class R>
31   	bool SPxSolverBase<R>::read(std::istream& in, NameSet* rowNames,
32   	                            NameSet* colNames, DIdxSet* intVars)
33   	{
34   	   if(initialized)
35   	   {
36   	      clear();
37   	      unInit();
38   	
39   	      if(thepricer)
40   	         thepricer->clear();
41   	
42   	      if(theratiotester)
43   	         theratiotester->clear();
44   	   }
45   	
46   	   this->unLoad();
47   	
48   	   if(!SPxLPBase<R>::read(in, rowNames, colNames, intVars))
49   	      return false;
50   	
51   	   this->theLP = this;
52   	
53   	   return true;
54   	}
55   	
56   	template <class R>
57   	void SPxSolverBase<R>::reLoad()
58   	{
59   	   forceRecompNonbasicValue();
60   	   unInit();
61   	   this->unLoad();
62   	   this->theLP = this;
63   	   m_status = SPxSolverBase<R>::UNKNOWN;
64   	
65   	   if(thepricer)
66   	      thepricer->clear();
67   	
68   	   if(theratiotester)
69   	      theratiotester->clear();
70   	}
71   	
72   	template <class R>
73   	void SPxSolverBase<R>::loadLP(const SPxLPBase<R>& lp, bool initSlackBasis)
74   	{
75   	   clear();
76   	   unInit();
77   	   this->unLoad();
78   	   resetClockStats();
79   	
80   	   if(thepricer)
81   	      thepricer->clear();
82   	
83   	   if(theratiotester)
84   	      theratiotester->clear();
85   	
86   	   SPxLPBase<R>::operator=(lp);
87   	   reDim();
88   	   SPxBasisBase<R>::load(this, initSlackBasis);
89   	}
90   	
91   	template <class R>
92   	void SPxSolverBase<R>::setBasisSolver(SLinSolver<R>* slu, const bool destroy)
93   	{
94   	   // we need to set the outstream before we load the solver to ensure that the basis
95   	   // can be initialized with this pointer in loadSolver()
96   	   assert(spxout != 0);
97   	   slu->spxout = spxout;
98   	   SPxBasisBase<R>::loadBasisSolver(slu, destroy);
99   	}
100  	
101  	template <class R>
102  	void SPxSolverBase<R>::loadBasis(const typename SPxBasisBase<R>::Desc& p_desc)
103  	{
104  	   unInit();
105  	
106  	   if(SPxBasisBase<R>::status() == SPxBasisBase<R>::NO_PROBLEM)
107  	   {
108  	      SPxBasisBase<R>::load(this, false);
109  	   }
110  	
111  	   setBasisStatus(SPxBasisBase<R>::REGULAR);
112  	   SPxBasisBase<R>::loadDesc(p_desc);
113  	}
114  	
115  	template <class R>
116  	void SPxSolverBase<R>::setPricer(SPxPricer<R>* x, const bool destroy)
117  	{
118  	
119  	   assert(!freePricer || thepricer != 0);
120  	
121  	   if(freePricer)
122  	   {
123  	      delete thepricer;
124  	      thepricer = 0;
125  	   }
126  	
127  	   if(x != 0 && x != thepricer)
128  	   {
129  	      setPricing(FULL);
130  	
131  	      if(isInitialized())
132  	         x->load(this);
133  	      else
134  	         x->clear();
135  	   }
136  	
137  	   if(thepricer && thepricer != x)
138  	      thepricer->clear();
139  	
140  	   thepricer = x;
141  	
142  	   freePricer = destroy;
143  	}
144  	
145  	template <class R>
146  	void SPxSolverBase<R>::setTester(SPxRatioTester<R>* x, const bool destroy)
147  	{
148  	   assert(!freeRatioTester || theratiotester != 0);
149  	
150  	   if(freeRatioTester)
151  	   {
152  	      delete theratiotester;
153  	      theratiotester = 0;
154  	   }
155  	
156  	   theratiotester = x;
157  	
158  	   // set the solver pointer inside the ratiotester
159  	   if(theratiotester != 0)
160  	   {
161  	      if(isInitialized())
162  	         theratiotester->load(this);
163  	      else
164  	         theratiotester->clear();
165  	   }
166  	
167  	   freeRatioTester = destroy;
168  	}
169  	
170  	template <class R>
171  	void SPxSolverBase<R>::setStarter(SPxStarter<R>* x, const bool destroy)
172  	{
173  	
174  	   assert(!freeStarter || thestarter != 0);
175  	
176  	   if(freeStarter)
177  	   {
178  	      delete thestarter;
179  	      thestarter = 0;
180  	   }
181  	
182  	   thestarter = x;
183  	
184  	   freeStarter = destroy;
185  	}
186  	
187  	template <class R>
188  	void SPxSolverBase<R>::setType(Type tp)
189  	{
190  	
191  	   if(theType != tp)
192  	   {
193  	      theType = tp;
194  	
195  	      forceRecompNonbasicValue();
196  	
197  	      unInit();
198  	#if 0
199  	      else
200  	      {
201  	         if(!matrixIsSetup)
202  	         {
203  	            SPxBasisBase<R>::load(this);
204  	            // SPxBasisBase<R>::load(desc());
205  	            // not needed, because load(this) allready loads descriptor
206  	         }
207  	
208  	         factorized = false;
209  	         m_numCycle = 0;
210  	#endif
211  	         MSG_INFO3((*spxout), (*spxout) << "Switching to "
212  	                   << static_cast<const char*>((tp == LEAVE)
213  	                                               ? "leaving" : "entering")
214  	                   << " algorithm" << std::endl;)
215  	      }
216  	   }
217  	
218  	   template <class R>
219  	   void SPxSolverBase<R>::initRep(Representation p_rep)
220  	   {
221  	
222  	      R tmpfeastol = feastol();
223  	      R tmpopttol = opttol();
224  	
225  	      theRep = p_rep;
226  	
227  	      if(theRep == COLUMN)
228  	      {
229  	         thevectors   = this->colSet();
230  	         thecovectors = this->rowSet();
231  	         theFrhs      = &primRhs;
232  	         theFvec      = &primVec;
233  	         theCoPrhs    = &dualRhs;
234  	         theCoPvec    = &dualVec;
235  	         thePvec      = &addVec;
236  	         theRPvec     = theCoPvec;
237  	         theCPvec     = thePvec;
238  	         theUbound    = &theUCbound;
239  	         theLbound    = &theLCbound;
240  	         theCoUbound  = &theURbound;
241  	         theCoLbound  = &theLRbound;
242  	      }
243  	      else
244  	      {
245  	         assert(theRep == ROW);
246  	
247  	         thevectors   = this->rowSet();
248  	         thecovectors = this->colSet();
249  	         theFrhs      = &dualRhs;
250  	         theFvec      = &dualVec;
251  	         theCoPrhs    = &primRhs;
252  	         theCoPvec    = &primVec;
253  	         thePvec      = &addVec;
254  	         theRPvec     = thePvec;
255  	         theCPvec     = theCoPvec;
256  	         theUbound    = &theURbound;
257  	         theLbound    = &theLRbound;
258  	         theCoUbound  = &theUCbound;
259  	         theCoLbound  = &theLCbound;
260  	      }
261  	
262  	      unInit();
263  	      reDim();
264  	
265  	      forceRecompNonbasicValue();
266  	
267  	      setFeastol(tmpfeastol);
268  	      setOpttol(tmpopttol);
269  	
270  	      SPxBasisBase<R>::setRep();
271  	
272  	      if(SPxBasisBase<R>::status() > SPxBasisBase<R>::NO_PROBLEM)
273  	         SPxBasisBase<R>::loadDesc(this->desc());
274  	
275  	      if(thepricer && thepricer->solver() == this)
276  	         thepricer->setRep(p_rep);
277  	   }
278  	
279  	   template <class R>
280  	   void SPxSolverBase<R>::setRep(Representation p_rep)
281  	   {
282  	
283  	      if(p_rep != theRep)
284  	         initRep(p_rep);
285  	   }
286  	
287  	   // needed for strongbranching. use carefully
288  	   template <class R>
289  	   void SPxSolverBase<R>::reinitializeVecs()
290  	   {
291  	
292  	      initialized = true;
293  	
294  	      if(type() == ENTER)
295  	      {
296  	         if(rep() == COLUMN)
297  	            setPrimalBounds();
298  	         else
299  	            setDualRowBounds();
300  	
301  	         setEnterBounds();
302  	         computeEnterCoPrhs();
303  	      }
304  	      else
305  	      {
306  	         if(rep() == ROW)
307  	            setPrimalBounds();
308  	         else
309  	            setDualColBounds();
310  	
311  	         setLeaveBounds();
312  	         computeLeaveCoPrhs();
313  	      }
314  	
315  	      SPxBasisBase<R>::coSolve(*theCoPvec, *theCoPrhs);
316  	      computePvec();
317  	      computeFrhs();
318  	      SPxBasisBase<R>::solve(*theFvec, *theFrhs);
319  	
320  	      theShift  = 0.0;
321  	      lastShift = 0.0;
322  	
323  	      if(type() == ENTER)
324  	      {
325  	         computeCoTest();
326  	         computeTest();
327  	      }
328  	      else
329  	      {
330  	         computeFtest();
331  	      }
332  	
333  	      assert((testBounds(), 1));
334  	   }
335  	
336  	   template <class R>
337  	   void SPxSolverBase<R>::resetClockStats()
338  	   {
339  	      nClckSkipsLeft = 0;
340  	      nCallsToTimelim = 0;
341  	      theCumulativeTime = 0.0;
342  	   }
343  	
344  	   template <class R>
345  	   void SPxSolverBase<R>::init()
346  	   {
347  	
348  	      assert(thepricer      != 0);
349  	      assert(theratiotester != 0);
350  	
351  	      if(!initialized)
352  	      {
353  	         initialized = true;
354  	         clearUpdateVecs();
355  	         reDim();
356  	
357  	         if(SPxBasisBase<R>::status() <= SPxBasisBase<R>::NO_PROBLEM || this->solver() != this)
358  	            SPxBasisBase<R>::load(this);
359  	
360  	         initialized = false;
361  	      }
362  	
363  	      if(!this->matrixIsSetup)
364  	         SPxBasisBase<R>::loadDesc(this->desc());
365  	
366  	      // Inna/Tobi: don't "upgrade" a singular basis to a regular one
367  	      if(SPxBasisBase<R>::status() == SPxBasisBase<R>::SINGULAR)
368  	         return;
369  	
370  	      // catch pathological case for LPs with zero constraints
371  	      if(dim() == 0)
372  	      {
373  	         this->factorized = true;
374  	      }
375  	
376  	      // we better factorize explicitly before solving
377  	      if(!this->factorized)
378  	      {
379  	         try
380  	         {
381  	            SPxBasisBase<R>::factorize();
382  	         }
383  	         catch(const SPxException&)
384  	         {
385  	            // reload inital slack basis in case the factorization failed
386  	            assert(SPxBasisBase<R>::status() <= SPxBasisBase<R>::SINGULAR);
387  	            SPxBasisBase<R>::restoreInitialBasis();
388  	            SPxBasisBase<R>::factorize();
389  	            assert(this->factorized);
390  	         }
391  	      }
392  	
393  	      m_numCycle = 0;
394  	
395  	      if(type() == ENTER)
396  	      {
397  	         if(rep() == COLUMN)
398  	         {
399  	            setPrimalBounds();
400  	            setBasisStatus(SPxBasisBase<R>::PRIMAL);
401  	         }
402  	         else
403  	         {
404  	            setDualRowBounds();
405  	            setBasisStatus(SPxBasisBase<R>::DUAL);
406  	         }
407  	
408  	         setEnterBounds();
409  	         computeEnterCoPrhs();
410  	         // prepare support vectors for sparse pricing
411  	         infeasibilities.setMax(dim());
412  	         infeasibilitiesCo.setMax(coDim());
413  	         isInfeasible.reSize(dim());
414  	         isInfeasibleCo.reSize(coDim());
415  	         theratiotester->setDelta(entertol());
416  	      }
417  	      else
418  	      {
419  	         if(rep() == ROW)
420  	         {
421  	            setPrimalBounds();
422  	            setBasisStatus(SPxBasisBase<R>::PRIMAL);
423  	         }
424  	         else
425  	         {
426  	            setDualColBounds();
427  	            setBasisStatus(SPxBasisBase<R>::DUAL);
428  	         }
429  	
430  	         setLeaveBounds();
431  	         computeLeaveCoPrhs();
432  	         // prepare support vectors for sparse pricing
433  	         infeasibilities.setMax(dim());
434  	         isInfeasible.reSize(dim());
435  	         theratiotester->setDelta(leavetol());
436  	      }
437  	
438  	      SPxBasisBase<R>::coSolve(*theCoPvec, *theCoPrhs);
439  	      computePvec();
440  	      computeFrhs();
441  	      SPxBasisBase<R>::solve(*theFvec, *theFrhs);
442  	
443  	      theShift = 0.0;
444  	
445  	      if(type() == ENTER)
446  	      {
447  	         shiftFvec();
448  	         lastShift = theShift + entertol();
449  	
450  	         computeCoTest();
451  	         computeTest();
452  	      }
453  	      else
454  	      {
455  	         shiftPvec();
456  	         lastShift = theShift + leavetol();
457  	
458  	         computeFtest();
459  	      }
460  	
461  	      if(!initialized)
462  	      {
463  	         // if(thepricer->solver() != this)
464  	         thepricer->load(this);
465  	         // if(theratiotester->solver() != this)
466  	         theratiotester->load(this);
467  	         initialized = true;
468  	      }
469  	   }
470  	
471  	   template <class R>
472  	   void SPxSolverBase<R>::setPricing(Pricing pr)
473  	   {
474  	      thePricing = pr;
475  	
476  	      if(initialized && type() == ENTER)
477  	      {
478  	         computePvec();
479  	         computeCoTest();
480  	         computeTest();
481  	      }
482  	   }
483  	
484  	   template <class R>
485  	   void SPxSolverBase<R>::setDecompStatus(DecompStatus decomp_stat)
486  	   {
487  	      if(decomp_stat == FINDSTARTBASIS)
488  	         getStartingDecompBasis = true;
489  	      else
490  	         getStartingDecompBasis = false;
491  	   }
492  	
493  	   /*
494  	     The following method resizes all vectors and arrays of |SoPlex|
495  	     (excluding inherited vectors).
496  	   */
497  	   template <class R>
498  	   void SPxSolverBase<R>::reDim()
499  	   {
500  	
501  	      int newsize = SPxLPBase<R>::nCols() > SPxLPBase<R>::nRows() ? SPxLPBase<R>::nCols() :
502  	                    SPxLPBase<R>::nRows();
503  	
504  	      if(newsize > unitVecs.size())
505  	      {
506  	         unitVecs.reSize(newsize);
507  	
508  	         while(newsize-- > 0)
509  	            unitVecs[newsize] = UnitVectorBase<R>(newsize);
510  	      }
511  	
512  	      if(isInitialized())
513  	      {
514  	         theFrhs->reDim(dim());
515  	         theFvec->reDim(dim());
516  	         thePvec->reDim(coDim());
517  	
518  	         theCoPrhs->reDim(dim());
519  	         theCoPvec->reDim(dim());
520  	
521  	         theTest.reDim(coDim());
522  	         theCoTest.reDim(dim());
523  	
524  	         theURbound.reDim(SPxLPBase<R>::nRows());
525  	         theLRbound.reDim(SPxLPBase<R>::nRows());
526  	         theUCbound.reDim(SPxLPBase<R>::nCols());
527  	         theLCbound.reDim(SPxLPBase<R>::nCols());
528  	         theUBbound.reDim(dim());
529  	         theLBbound.reDim(dim());
530  	      }
531  	   }
532  	
533  	   template <class R>
534  	   void SPxSolverBase<R>::clear()
535  	   {
536  	      unitVecs.reSize(0);
537  	
538  	      dualRhs.clear();
539  	      dualVec.clear();
540  	      primRhs.clear();
541  	      primVec.clear();
542  	      addVec.clear();
543  	      theURbound.clear();
544  	      theLRbound.clear();
545  	      theUCbound.clear();
546  	      theLCbound.clear();
547  	      theTest.clear();
548  	      theCoTest.clear();
549  	
550  	      forceRecompNonbasicValue();
551  	      unInit();
552  	      SPxLPBase<R>::clear();
553  	      setBasisStatus(SPxBasisBase<R>::NO_PROBLEM);
554  	
555  	      // clear the basis only when theLP is present, because LP data (nrows, ncols) is used in reDim()
556  	      if(this->theLP != 0)
557  	         SPxBasisBase<R>::reDim();
558  	
559  	      infeasibilities.clear();
560  	      infeasibilitiesCo.clear();
561  	      isInfeasible.clear();
562  	      isInfeasibleCo.clear();
563  	   }
564  	
565  	   template <class R>
566  	   void SPxSolverBase<R>::unscaleLPandReloadBasis()
567  	   {
568  	      SPxLPBase<R>::unscaleLP();
569  	      SPxBasisBase<R>::invalidate();
570  	      unInit();
571  	      init();
572  	   }
573  	
574  	   template <class R>
575  	   void SPxSolverBase<R>::invalidateBasis()
576  	   {
577  	      SPxBasisBase<R>::invalidate();
578  	      unInit();
579  	      init();
580  	   }
581  	
582  	   template <class R>
583  	   void SPxSolverBase<R>::clearUpdateVecs(void)
584  	   {
585  	      theFvec->clearUpdate();
586  	      thePvec->clearUpdate();
587  	      theCoPvec->clearUpdate();
588  	      solveVector2 = 0;
589  	      solveVector3 = 0;
590  	      coSolveVector2 = 0;
591  	      coSolveVector3 = 0;
592  	   }
593  	
594  	   /*
595  	     When the basis matrix factorization is recomputed from scratch,
596  	     we also recompute the vectors.
597  	   */
598  	   template <class R>
599  	   void SPxSolverBase<R>::factorize()
600  	   {
601  	
602  	      MSG_INFO3((*spxout), (*spxout) << " --- refactorizing basis matrix" << std::endl;)
603  	
604  	      try
605  	      {
606  	         SPxBasisBase<R>::factorize();
607  	      }
608  	      catch(const SPxStatusException&)
609  	      {
610  	         assert(SPxBasisBase<R>::status() == SPxBasisBase<R>::SINGULAR);
611  	         m_status = SINGULAR;
612  	         std::stringstream s;
613  	         s << "Basis is singular (numerical troubles, feastol = " << feastol() << ", opttol = " << opttol()
614  	           << ")";
615  	         throw SPxStatusException(s.str());
616  	      }
617  	
618  	      if(!initialized)
619  	      {
620  	         init();  // not sure if init() is neccessary here
621  	         // we must not go on here because not all vectors (e.g. fVec) may be set up correctly
622  	         return;
623  	      }
624  	
625  	      if(SPxBasisBase<R>::status() >= SPxBasisBase<R>::REGULAR)
626  	      {
627  	#ifndef NDEBUG
628  	         VectorBase<R> ftmp(fVec());
629  	         VectorBase<R> ptmp(pVec());
630  	         VectorBase<R> ctmp(coPvec());
631  	#endif  // NDEBUG
632  	
633  	         if(type() == LEAVE)
634  	         {
635  	            /* we have to recompute theFrhs, because roundoff errors can occur during updating, especially when
636  	             * columns/rows with large bounds are present
637  	             */
638  	            computeFrhs();
639  	            SPxBasisBase<R>::solve(*theFvec, *theFrhs);
640  	            SPxBasisBase<R>::coSolve(*theCoPvec, *theCoPrhs);
641  	
642  	#ifndef NDEBUG
643  	            ftmp -= fVec();
644  	            ptmp -= pVec();
645  	            ctmp -= coPvec();
646  	
647  	            if(ftmp.length() > DEFAULT_BND_VIOL)
648  	            {
649  	               MSG_DEBUG(std::cout << "DSOLVE21 fVec:   " << ftmp.length() << std::endl;)
650  	               ftmp = fVec();
651  	               this->multBaseWith(ftmp);
652  	               ftmp -= fRhs();
653  	
654  	               if(ftmp.length() > DEFAULT_BND_VIOL)
655  	                  MSG_INFO1((*spxout), (*spxout) << "ESOLVE29 " << this->iteration() << ": fVec error = "
656  	                            << ftmp.length() << " exceeding DEFAULT_BND_VIOL = " << DEFAULT_BND_VIOL << std::endl;)
657  	               }
658  	
659  	            if(ctmp.length() > DEFAULT_BND_VIOL)
660  	            {
661  	               MSG_DEBUG(std::cout << "DSOLVE23 coPvec: " << ctmp.length() << std::endl;)
662  	               ctmp = coPvec();
663  	               this->multWithBase(ctmp);
664  	               ctmp -= coPrhs();
665  	
666  	               if(ctmp.length() > DEFAULT_BND_VIOL)
667  	                  MSG_INFO1((*spxout), (*spxout) << "ESOLVE30 " << this->iteration() << ": coPvec error = "
668  	                            << ctmp.length() << " exceeding DEFAULT_BND_VIOL = " << DEFAULT_BND_VIOL << std::endl;)
669  	               }
670  	
671  	            if(ptmp.length() > DEFAULT_BND_VIOL)
672  	            {
673  	               MSG_DEBUG(std::cout << "DSOLVE24 pVec:   " << ptmp.length() << std::endl;)
674  	            }
675  	
676  	#endif  // NDEBUG
677  	
678  	            computeFtest();
679  	         }
680  	         else
681  	         {
682  	            assert(type() == ENTER);
683  	
684  	            SPxBasisBase<R>::coSolve(*theCoPvec, *theCoPrhs);
685  	            computeCoTest();
686  	
687  	            if(pricing() == FULL)
688  	            {
689  	               /* to save time only recompute the row activities (in row rep) when we are already nearly optimal to
690  	                * avoid missing any violations from previous updates */
691  	               if(rep() == ROW && m_pricingViolCo < entertol() && m_pricingViol < entertol())
692  	                  computePvec();
693  	
694  	               /* was deactivated, but this leads to warnings in testVecs() */
695  	               computeTest();
696  	            }
697  	         }
698  	      }
699  	
700  	#ifdef ENABLE_ADDITIONAL_CHECKS
701  	
702  	      /* moved this test after the computation of fTest and coTest below, since these vectors might not be set up at top, e.g. for an initial basis */
703  	      if(SPxBasisBase<R>::status() > SPxBasisBase<R>::SINGULAR)
704  	         testVecs();
705  	
706  	#endif
707  	   }
708  	
709  	   /* We compute how much the current solution violates (primal or dual) feasibility. In the
710  	      row/enter or column/leave algorithm the maximum violation of dual feasibility is
711  	      computed. In the row/leave or column/enter algorithm the primal feasibility is checked.
712  	      Additionally, the violation from pricing is taken into account. */
713  	   template <class R>
714  	   R SPxSolverBase<R>::maxInfeas() const
715  	   {
716  	      R inf = 0.0;
717  	
718  	      if(type() == ENTER)
719  	      {
720  	         if(m_pricingViolUpToDate && m_pricingViolCoUpToDate)
721  	            inf = m_pricingViol + m_pricingViolCo;
722  	
723  	         for(int i = 0; i < dim(); i++)
724  	         {
725  	            if((*theFvec)[i] > theUBbound[i])
726  	               inf = MAXIMUM(inf, (*theFvec)[i] - theUBbound[i]);
727  	            else if((*theFvec)[i] < theLBbound[i])
728  	               inf = MAXIMUM(inf, theLBbound[i] - (*theFvec)[i]);
729  	         }
730  	      }
731  	      else
732  	      {
733  	         assert(type() == LEAVE);
734  	
735  	         if(m_pricingViolUpToDate)
736  	            inf = m_pricingViol;
737  	
738  	         for(int i = 0; i < dim(); i++)
739  	         {
740  	            if((*theCoPvec)[i] > (*theCoUbound)[i])
741  	               inf = MAXIMUM(inf, (*theCoPvec)[i] - (*theCoUbound)[i]);
742  	            else if((*theCoPvec)[i] < (*theCoLbound)[i])
743  	               inf = MAXIMUM(inf, (*theCoLbound)[i] - (*theCoPvec)[i]);
744  	         }
745  	
746  	         for(int i = 0; i < coDim(); i++)
747  	         {
748  	            if((*thePvec)[i] > (*theUbound)[i])
749  	               inf = MAXIMUM(inf, (*thePvec)[i] - (*theUbound)[i]);
750  	            else if((*thePvec)[i] < (*theLbound)[i])
751  	               inf = MAXIMUM(inf, (*theLbound)[i] - (*thePvec)[i]);
752  	         }
753  	      }
754  	
755  	      return inf;
756  	   }
757  	
758  	   /* check for (dual) violations above tol and immediately return false w/o checking the remaining values
759  	      This method is useful for verifying whether an objective limit can be used as termination criterion */
760  	   template <class R>
761  	   bool SPxSolverBase<R>::noViols(R tol) const
762  	   {
763  	      assert(tol >= 0.0);
764  	
765  	      if(type() == ENTER)
766  	      {
767  	         for(int i = 0; i < dim(); i++)
768  	         {
769  	            if((*theFvec)[i] - theUBbound[i] > tol)
770  	               return false;
771  	
772  	            if(theLBbound[i] - (*theFvec)[i] > tol)
773  	               return false;
774  	         }
775  	      }
776  	      else
777  	      {
778  	         assert(type() == LEAVE);
779  	
780  	         for(int i = 0; i < dim(); i++)
781  	         {
782  	            if((*theCoPvec)[i] - (*theCoUbound)[i] > tol)
783  	               return false;
784  	
785  	            if((*theCoLbound)[i] - (*theCoPvec)[i] > tol)
786  	               return false;
787  	         }
788  	
789  	         for(int i = 0; i < coDim(); i++)
790  	         {
791  	            if((*thePvec)[i] - (*theUbound)[i] > tol)
792  	               return false;
793  	
794  	            if((*theLbound)[i] - (*thePvec)[i] > tol)
795  	               return false;
796  	         }
797  	      }
798  	
799  	      return true;
800  	   }
801  	
802  	   template <class R>
803  	   R SPxSolverBase<R>::nonbasicValue()
804  	   {
805  	      int i;
806  	      StableSum<R> val;
807  	      const typename SPxBasisBase<R>::Desc& ds = this->desc();
808  	
809  	#ifndef ENABLE_ADDITIONAL_CHECKS
810  	
811  	      // if the value is available we don't need to recompute it
812  	      if(m_nonbasicValueUpToDate)
813  	         return m_nonbasicValue;
814  	
815  	#endif
816  	
817  	      if(rep() == COLUMN)
818  	      {
819  	         if(type() == LEAVE)
820  	         {
821  	            for(i = this->nCols() - 1; i >= 0; --i)
822  	            {
823  	               switch(ds.colStatus(i))
824  	               {
825  	               case SPxBasisBase<R>::Desc::P_ON_UPPER :
826  	                  val += theUCbound[i] * SPxLPBase<R>::upper(i);
827  	                  //@ val += maxObj(i) * SPxLPBase<R>::upper(i);
828  	                  break;
829  	
830  	               case SPxBasisBase<R>::Desc::P_ON_LOWER :
831  	                  val += theLCbound[i] * SPxLPBase<R>::lower(i);
832  	                  //@ val += maxObj(i) * SPxLPBase<R>::lower(i);
833  	                  break;
834  	
835  	               case SPxBasisBase<R>::Desc::P_FIXED :
836  	                  assert(EQ(SPxLPBase<R>::lower(i), SPxLPBase<R>::upper(i)));
837  	                  val += this->maxObj(i) * SPxLPBase<R>::lower(i);
838  	                  break;
839  	
840  	               default:
841  	                  break;
842  	               }
843  	            }
844  	
845  	            for(i = this->nRows() - 1; i >= 0; --i)
846  	            {
847  	               switch(ds.rowStatus(i))
848  	               {
849  	               case SPxBasisBase<R>::Desc::P_ON_UPPER :
850  	                  val += theLRbound[i] * SPxLPBase<R>::rhs(i);
851  	                  break;
852  	
853  	               case SPxBasisBase<R>::Desc::P_ON_LOWER :
854  	                  val += theURbound[i] * SPxLPBase<R>::lhs(i);
855  	                  break;
856  	
857  	               case SPxBasisBase<R>::Desc::P_FIXED :
858  	                  assert(EQ(SPxLPBase<R>::lhs(i), SPxLPBase<R>::rhs(i)));
859  	                  val += this->maxRowObj(i) * SPxLPBase<R>::lhs(i);
860  	                  break;
861  	
862  	               default:
863  	                  break;
864  	               }
865  	            }
866  	         }
867  	         else
868  	         {
869  	            assert(type() == ENTER);
870  	
871  	            for(i = this->nCols() - 1; i >= 0; --i)
872  	            {
873  	               switch(ds.colStatus(i))
874  	               {
875  	               case SPxBasisBase<R>::Desc::P_ON_UPPER :
876  	                  val += this->maxObj(i) * theUCbound[i];
877  	                  break;
878  	
879  	               case SPxBasisBase<R>::Desc::P_ON_LOWER :
880  	                  val += this->maxObj(i) * theLCbound[i];
881  	                  break;
882  	
883  	               case SPxBasisBase<R>::Desc::P_FIXED :
884  	                  assert(EQ(theLCbound[i], theUCbound[i]));
885  	                  val += this->maxObj(i) * theLCbound[i];
886  	                  break;
887  	
888  	               default:
889  	                  break;
890  	               }
891  	            }
892  	
893  	            for(i = this->nRows() - 1; i >= 0; --i)
894  	            {
895  	               switch(ds.rowStatus(i))
896  	               {
897  	               case SPxBasisBase<R>::Desc::P_ON_UPPER :
898  	                  val += this->maxRowObj(i) * theLRbound[i];
899  	                  break;
900  	
901  	               case SPxBasisBase<R>::Desc::P_ON_LOWER :
902  	                  val += this->maxRowObj(i) * theURbound[i];
903  	                  break;
904  	
905  	               case SPxBasisBase<R>::Desc::P_FIXED :
906  	                  assert(EQ(theLRbound[i], theURbound[i]));
907  	                  val += this->maxRowObj(i) * theURbound[i];
908  	                  break;
909  	
910  	               default:
911  	                  break;
912  	               }
913  	            }
914  	         }
915  	      }
916  	      else
917  	      {
918  	         assert(rep() == ROW);
919  	         assert(type() == ENTER);
920  	
921  	         for(i = this->nCols() - 1; i >= 0; --i)
922  	         {
923  	            switch(ds.colStatus(i))
924  	            {
925  	            case SPxBasisBase<R>::Desc::D_ON_UPPER :
926  	               val += theUCbound[i] * this->lower(i);
927  	               break;
928  	
929  	            case SPxBasisBase<R>::Desc::D_ON_LOWER :
930  	               val += theLCbound[i] * this->upper(i);
931  	               break;
932  	
933  	            case SPxBasisBase<R>::Desc::D_ON_BOTH :
934  	               val += theLCbound[i] * this->upper(i);
935  	               val += theUCbound[i] * this->lower(i);
936  	               break;
937  	
938  	            default:
939  	               break;
940  	            }
941  	         }
942  	
943  	         for(i = this->nRows() - 1; i >= 0; --i)
944  	         {
945  	            switch(ds.rowStatus(i))
946  	            {
947  	            case SPxBasisBase<R>::Desc::D_ON_UPPER :
948  	               val += theURbound[i] * this->lhs(i);
949  	               break;
950  	
951  	            case SPxBasisBase<R>::Desc::D_ON_LOWER :
952  	               val += theLRbound[i] * this->rhs(i);
953  	               break;
954  	
955  	            case SPxBasisBase<R>::Desc::D_ON_BOTH :
956  	               val += theLRbound[i] * this->rhs(i);
957  	               val += theURbound[i] * this->lhs(i);
958  	               break;
959  	
960  	            default:
961  	               break;
962  	            }
963  	         }
964  	      }
965  	
966  	#ifdef ENABLE_ADDITIONAL_CHECKS
967  	
968  	      if(m_nonbasicValueUpToDate && NE(m_nonbasicValue, val))
969  	      {
970  	         MSG_ERROR(std::cerr << "stored nonbasic value: " << m_nonbasicValue
971  	                   << ", correct nonbasic value: " << val
972  	                   << ", violation: " << val - m_nonbasicValue << std::endl;)
973  	         assert(EQrel(m_nonbasicValue, val, 1e-12));
974  	      }
975  	
976  	#endif
977  	
978  	      if(!m_nonbasicValueUpToDate)
979  	      {
980  	         m_nonbasicValue = R(val);
981  	         m_nonbasicValueUpToDate = true;
982  	      }
983  	
984  	      return val;
985  	   }
986  	
987  	   template <class R>
988  	   R SPxSolverBase<R>::value()
989  	   {
990  	      assert(isInitialized());
991  	
992  	      R x;
993  	
994  	      // calling value() without having a suitable status is an error.
995  	      if(!isInitialized())
996  	         return R(infinity);
997  	
998  	      if(rep() == ROW)
999  	      {
1000 	         if(type() == LEAVE)
1001 	            x = int(SPxLPBase<R>::spxSense()) * (coPvec() *
1002 	                                                 fRhs()); // the contribution of maxRowObj() is missing
1003 	         else
1004 	            x = int(SPxLPBase<R>::spxSense()) * (nonbasicValue() + (coPvec() * fRhs()));
1005 	      }
1006 	      else
1007 	         x = int(SPxLPBase<R>::spxSense()) * (nonbasicValue() + fVec() * coPrhs());
1008 	
1009 	      return x + this->objOffset();
1010 	   }
1011 	
1012 	   template <class R>
1013 	   bool SPxSolverBase<R>::updateNonbasicValue(R objChange)
1014 	   {
1015 	      if(m_nonbasicValueUpToDate)
1016 	         m_nonbasicValue += objChange;
1017 	
1018 	      MSG_DEBUG(std::cout
1019 	                << "Iteration: " << this->iteration()
1020 	                << ": updated objValue: " << objChange
1021 	                << ", new value: " << m_nonbasicValue
1022 	                << ", correct value: " << nonbasicValue()
1023 	                << std::endl;
1024 	               )
1025 	
1026 	      return m_nonbasicValueUpToDate;
1027 	   }
1028 	
1029 	
1030 	
1031 	   template <class R>
1032 	   void SPxSolverBase<R>::setFeastol(R d)
1033 	   {
1034 	
1035 	      if(d <= 0.0)
1036 	         throw SPxInterfaceException("XSOLVE30 Cannot set feastol less than or equal to zero.");
1037 	
1038 	      if(theRep == COLUMN)
1039 	         m_entertol = d;
1040 	      else
1041 	         m_leavetol = d;
1042 	   }
1043 	
1044 	   template <class R>
1045 	   void SPxSolverBase<R>::setOpttol(R d)
1046 	   {
1047 	
1048 	      if(d <= 0.0)
1049 	         throw SPxInterfaceException("XSOLVE31 Cannot set opttol less than or equal to zero.");
1050 	
1051 	      if(theRep == COLUMN)
1052 	         m_leavetol = d;
1053 	      else
1054 	         m_entertol = d;
1055 	   }
1056 	
1057 	   template <class R>
1058 	   void SPxSolverBase<R>::setDelta(R d)
1059 	   {
1060 	
1061 	      if(d <= 0.0)
1062 	         throw SPxInterfaceException("XSOLVE32 Cannot set delta less than or equal to zero.");
1063 	
1064 	      m_entertol = d;
1065 	      m_leavetol = d;
1066 	   }
1067 	
1068 	   template <class R>
1069 	   void SPxSolverBase<R>::hyperPricing(bool h)
1070 	   {
1071 	      hyperPricingEnter = h;
1072 	      hyperPricingLeave = h;
1073 	
1074 	      if(h)
1075 	      {
1076 	         updateViols.setMax(dim());
1077 	         updateViolsCo.setMax(coDim());
1078 	      }
1079 	   }
1080 	
1081 	   template <class R>
1082 	   SPxSolverBase<R>::SPxSolverBase(
1083 	      Type            p_type,
1084 	      Representation  p_rep,
1085 	      Timer::TYPE     ttype)
1086 	      : theType(p_type)
1087 	      , thePricing(FULL)
1088 	      , theRep(p_rep)
1089 	      , polishObj(POLISH_OFF)
1090 	      , theTime(nullptr)
1091 	      , timerType(ttype)
1092 	      , theCumulativeTime(0.0)
1093 	      , maxIters(-1)
1094 	      , maxTime(R(infinity))
1095 	      , nClckSkipsLeft(0)
1096 	      , nCallsToTimelim(0)
1097 	      , objLimit(R(infinity))
1098 	      , m_status(UNKNOWN)
1099 	      , m_nonbasicValue(0.0)
1100 	      , m_nonbasicValueUpToDate(false)
1101 	      , m_pricingViol(0.0)
1102 	      , m_pricingViolUpToDate(false)
1103 	      , m_pricingViolCo(0.0)
1104 	      , m_pricingViolCoUpToDate(false)
1105 	      , m_numViol(0)
1106 	      , theShift(0)
1107 	      , m_maxCycle(100)
1108 	      , m_numCycle(0)
1109 	      , initialized(false)
1110 	      , solveVector2(0)
1111 	      , solveVector3(0)
1112 	      , coSolveVector2(0)
1113 	      , coSolveVector3(0)
1114 	      , freePricer(false)
1115 	      , freeRatioTester(false)
1116 	      , freeStarter(false)
1117 	      , displayLine(0)
1118 	      , displayFreq(200)
1119 	      , sparsePricingFactor(SPARSITYFACTOR)
1120 	      , getStartingDecompBasis(false)
1121 	      , computeDegeneracy(false)
1122 	      , degenCompIterOffset(0)
1123 	      , fullPerturbation(false)
1124 	      , printBasisMetric(0)
1125 	      , unitVecs(0)
1126 	      , primVec(0, Param::epsilon())
1127 	      , dualVec(0, Param::epsilon())
1128 	      , addVec(0, Param::epsilon())
1129 	      , thepricer(0)
1130 	      , theratiotester(0)
1131 	      , thestarter(0)
1132 	      , boundrange(0.0)
1133 	      , siderange(0.0)
1134 	      , objrange(0.0)
1135 	      , infeasibilities(0)
1136 	      , infeasibilitiesCo(0)
1137 	      , isInfeasible(0)
1138 	      , isInfeasibleCo(0)
1139 	      , sparsePricingLeave(false)
1140 	      , sparsePricingEnter(false)
1141 	      , sparsePricingEnterCo(false)
1142 	      , hyperPricingLeave(true)
1143 	      , hyperPricingEnter(true)
1144 	      , remainingRoundsLeave(0)
1145 	      , remainingRoundsEnter(0)
1146 	      , remainingRoundsEnterCo(0)
1147 	      , weights(0)
1148 	      , coWeights(0)
1149 	      , weightsAreSetup(false)
1150 	      , multSparseCalls(0)
1151 	      , multFullCalls(0)
1152 	      , multColwiseCalls(0)
1153 	      , multUnsetupCalls(0)
1154 	      , integerVariables(0)
1155 	   {
1156 	      theTime = TimerFactory::createTimer(timerType);
1157 	
1158 	      multTimeSparse = TimerFactory::createTimer(timerType);
1159 	      multTimeFull = TimerFactory::createTimer(timerType);
1160 	      multTimeColwise = TimerFactory::createTimer(timerType);
1161 	      multTimeUnsetup = TimerFactory::createTimer(timerType);
1162 	
1163 	      setDelta(DEFAULT_BND_VIOL);
1164 	
1165 	      this->theLP = this;
1166 	      initRep(p_rep);
1167 	
1168 	      // info: SPxBasisBase is not consistent in this moment.
1169 	      //assert(SPxSolverBase<R>::isConsistent());
(3) Event template_instantiation_context: instantiation of "soplex::SPxSolverBase<R>::Status soplex::SPxSolverBase<R>::solve(volatile bool *) [with R=soplex::Real]" at line 1170 of "/sapmnt/home1/d029903/my_work/SCIPSoPlex_coverity/scipoptsuite-8.0.1/soplex/src/soplex/spxsolver.hpp"
Also see events: [switch_selector_expr_is_constant][caretline][template_instantiation_context][template_instantiation_context]
1170 	   }
1171 	
1172 	   template <class R>
1173 	   SPxSolverBase<R>::~SPxSolverBase()
1174 	   {
1175 	      assert(!freePricer || thepricer != 0);
1176 	      assert(!freeRatioTester || theratiotester != 0);
1177 	      assert(!freeStarter || thestarter != 0);
1178 	
1179 	      if(freePricer)
1180 	      {
1181 	         delete thepricer;
1182 	         thepricer = 0;
1183 	      }
1184 	
1185 	      if(freeRatioTester)
1186 	      {
1187 	         delete theratiotester;
1188 	         theratiotester = 0;
1189 	      }
1190 	
1191 	      if(freeStarter)
1192 	      {
1193 	         delete thestarter;
1194 	         thestarter = 0;
1195 	      }
1196 	
1197 	      // free the timers
1198 	      assert(theTime);
1199 	      assert(multTimeSparse);
1200 	      assert(multTimeFull);
1201 	      assert(multTimeColwise);
1202 	      assert(multTimeUnsetup);
1203 	      theTime->~Timer();
1204 	      multTimeSparse->~Timer();
1205 	      multTimeFull->~Timer();
1206 	      multTimeColwise->~Timer();
1207 	      multTimeUnsetup->~Timer();
1208 	      spx_free(theTime);
1209 	      spx_free(multTimeSparse);
1210 	      spx_free(multTimeFull);
1211 	      spx_free(multTimeColwise);
1212 	      spx_free(multTimeUnsetup);
1213 	   }
1214 	
1215 	
1216 	   template <class R>
1217 	   SPxSolverBase<R>& SPxSolverBase<R>::operator=(const SPxSolverBase<R>& base)
1218 	   {
1219 	      if(this != &base)
1220 	      {
1221 	         SPxLPBase<R>::operator=(base);
1222 	         SPxBasisBase<R>::operator=(base);
1223 	         theType = base.theType;
1224 	         thePricing = base.thePricing;
1225 	         theRep = base.theRep;
1226 	         polishObj = base.polishObj;
1227 	         timerType = base.timerType;
1228 	         maxIters = base.maxIters;
1229 	         maxTime = base.maxTime;
1230 	         objLimit = base.objLimit;
1231 	         m_status = base.m_status;
1232 	         m_nonbasicValue = base.m_nonbasicValue;
1233 	         m_nonbasicValueUpToDate = base.m_nonbasicValueUpToDate;
1234 	         m_pricingViol = base.m_pricingViol;
1235 	         m_pricingViolUpToDate = base.m_pricingViolUpToDate;
1236 	         m_pricingViolCo = base.m_pricingViolCo;
1237 	         m_pricingViolCoUpToDate = base.m_pricingViolCoUpToDate;
1238 	         m_numViol = base.m_numViol;
1239 	         m_entertol = base.m_entertol;
1240 	         m_leavetol = base.m_leavetol;
1241 	         theShift = base.theShift;
1242 	         lastShift = base.lastShift;
1243 	         m_maxCycle = base.m_maxCycle;
1244 	         m_numCycle = base.m_numCycle;
1245 	         initialized = base.initialized;
1246 	         instableLeaveNum = base.instableLeaveNum;
1247 	         instableLeave = base.instableLeave;
1248 	         instableLeaveVal = base.instableLeaveVal;
1249 	         instableEnterId = base.instableEnterId;
1250 	         instableEnter = base.instableEnter;
1251 	         instableEnterVal = base.instableEnterVal;
1252 	         displayLine = base.displayLine;
1253 	         displayFreq = base.displayFreq;
1254 	         sparsePricingFactor = base.sparsePricingFactor;
1255 	         getStartingDecompBasis = base.getStartingDecompBasis;
1256 	         computeDegeneracy = base.computeDegeneracy;
1257 	         degenCompIterOffset = base.degenCompIterOffset;
1258 	         decompIterationLimit = base.decompIterationLimit;
1259 	         fullPerturbation = base.fullPerturbation;
1260 	         printBasisMetric = base.printBasisMetric;
1261 	         unitVecs = base.unitVecs;
1262 	         primRhs = base.primRhs;
1263 	         primVec = base.primVec;
1264 	         dualRhs = base.dualRhs;
1265 	         dualVec = base.dualVec;
1266 	         addVec = base.addVec;
1267 	         theURbound = base.theURbound;
1268 	         theLRbound = base.theLRbound;
1269 	         theUCbound = base.theUCbound;
1270 	         theLCbound = base.theLCbound;
1271 	         theUBbound = base.theUBbound;
1272 	         theLBbound = base.theLBbound;
1273 	         theCoTest = base.theCoTest;
1274 	         theTest = base.theTest;
1275 	         primalRay = base.primalRay;
1276 	         dualFarkas = base.dualFarkas;
1277 	         leaveCount = base.leaveCount;
1278 	         enterCount = base.enterCount;
1279 	         theCumulativeTime = base.theCumulativeTime;
1280 	         primalCount = base.primalCount;
1281 	         polishCount = base.polishCount;
1282 	         boundflips = base.boundflips;
1283 	         totalboundflips = base.totalboundflips;
1284 	         enterCycles = base.enterCycles;
1285 	         leaveCycles = base.leaveCycles;
1286 	         enterDegenCand = base.enterDegenCand;
1287 	         leaveDegenCand = base.leaveDegenCand;
1288 	         primalDegenSum = base.primalDegenSum;
1289 	         boundrange = base.boundrange;
1290 	         siderange = base.siderange;
1291 	         objrange = base.objrange;
1292 	         infeasibilities = base.infeasibilities;
1293 	         infeasibilitiesCo = base.infeasibilitiesCo;
1294 	         isInfeasible = base.isInfeasible;
1295 	         isInfeasibleCo = base.isInfeasibleCo;
1296 	         sparsePricingLeave = base.sparsePricingLeave;
1297 	         sparsePricingEnter = base.sparsePricingEnter;
1298 	         sparsePricingEnterCo = base.sparsePricingEnterCo;
1299 	         sparsePricingFactor = base.sparsePricingFactor;
1300 	         hyperPricingLeave = base.hyperPricingLeave;
1301 	         hyperPricingEnter = base.hyperPricingEnter;
1302 	         remainingRoundsLeave = base.remainingRoundsLeave;
1303 	         remainingRoundsEnter = base.remainingRoundsEnter;
1304 	         remainingRoundsEnterCo = base.remainingRoundsEnterCo;
1305 	         weights = base.weights;
1306 	         coWeights = base.coWeights;
1307 	         weightsAreSetup = base.weightsAreSetup;
1308 	         multSparseCalls = base.multSparseCalls;
1309 	         multFullCalls = base.multFullCalls;
1310 	         multColwiseCalls = base.multColwiseCalls;
1311 	         multUnsetupCalls = base.multUnsetupCalls;
1312 	         spxout = base.spxout;
1313 	         integerVariables = base.integerVariables;
1314 	
1315 	         if(base.theRep == COLUMN)
1316 	         {
1317 	            thevectors   = this->colSet();
1318 	            thecovectors = this->rowSet();
1319 	            theFrhs      = &primRhs;
1320 	            theFvec      = &primVec;
1321 	            theCoPrhs    = &dualRhs;
1322 	            theCoPvec    = &dualVec;
1323 	            thePvec      = &addVec;
1324 	            theRPvec     = theCoPvec;
1325 	            theCPvec     = thePvec;
1326 	            theUbound    = &theUCbound;
1327 	            theLbound    = &theLCbound;
1328 	            theCoUbound  = &theURbound;
1329 	            theCoLbound  = &theLRbound;
1330 	         }
1331 	         else
1332 	         {
1333 	            assert(base.theRep == ROW);
1334 	
1335 	            thevectors   = this->rowSet();
1336 	            thecovectors = this->colSet();
1337 	            theFrhs      = &dualRhs;
1338 	            theFvec      = &dualVec;
1339 	            theCoPrhs    = &primRhs;
1340 	            theCoPvec    = &primVec;
1341 	            thePvec      = &addVec;
1342 	            theRPvec     = thePvec;
1343 	            theCPvec     = theCoPvec;
1344 	            theUbound    = &theURbound;
1345 	            theLbound    = &theLRbound;
1346 	            theCoUbound  = &theUCbound;
1347 	            theCoLbound  = &theLCbound;
1348 	         }
1349 	
1350 	         SPxBasisBase<R>::theLP = this;
1351 	
1352 	         assert(!freePricer || thepricer != 0);
1353 	         assert(!freeRatioTester || theratiotester != 0);
1354 	         assert(!freeStarter || thestarter != 0);
1355 	
1356 	         // thepricer
1357 	         if(freePricer)
1358 	         {
1359 	            delete thepricer;
1360 	            thepricer = 0;
1361 	         }
1362 	
1363 	         if(base.thepricer == 0)
1364 	         {
1365 	            thepricer = 0;
1366 	            freePricer = false;
1367 	         }
1368 	         else
1369 	         {
1370 	            thepricer = base.thepricer->clone();
1371 	            freePricer = true;
1372 	            thepricer->load(this);
1373 	         }
1374 	
1375 	         // theratiotester
1376 	         if(freeRatioTester)
1377 	         {
1378 	            delete theratiotester;
1379 	            theratiotester = 0;
1380 	         }
1381 	
1382 	         if(base.theratiotester == 0)
1383 	         {
1384 	            theratiotester = 0;
1385 	            freeRatioTester = false;
1386 	         }
1387 	         else
1388 	         {
1389 	            theratiotester = base.theratiotester->clone();
1390 	            freeRatioTester = true;
1391 	            theratiotester->load(this);
1392 	         }
1393 	
1394 	         // thestarter
1395 	         if(freeStarter)
1396 	         {
1397 	            delete thestarter;
1398 	            thestarter = 0;
1399 	         }
1400 	
1401 	         if(base.thestarter == 0)
1402 	         {
1403 	            thestarter = 0;
1404 	            freeStarter = false;
1405 	         }
1406 	         else
1407 	         {
1408 	            thestarter = base.thestarter->clone();
1409 	            freeStarter = true;
1410 	         }
1411 	
1412 	         assert(SPxSolverBase<R>::isConsistent());
1413 	      }
1414 	
1415 	      return *this;
1416 	   }
1417 	
1418 	
1419 	   template <class R>
1420 	   SPxSolverBase<R>::SPxSolverBase(const SPxSolverBase<R>& base)
1421 	      : SPxLPBase<R> (base)
1422 	      , SPxBasisBase<R>(this->basSe)
1423 	      , theType(base.theType)
1424 	      , thePricing(base.thePricing)
1425 	      , theRep(base.theRep)
1426 	      , polishObj(base.polishObj)
1427 	      , timerType(base.timerType)
1428 	      , theCumulativeTime(base.theCumulativeTime)
1429 	      , maxIters(base.maxIters)
1430 	      , maxTime(base.maxTime)
1431 	      , nClckSkipsLeft(base.nClckSkipsLeft)
1432 	      , nCallsToTimelim(base.nCallsToTimelim)
1433 	      , objLimit(base.objLimit)
1434 	      , m_status(base.m_status)
1435 	      , m_nonbasicValue(base.m_nonbasicValue)
1436 	      , m_nonbasicValueUpToDate(base.m_nonbasicValueUpToDate)
1437 	      , m_pricingViol(base.m_pricingViol)
1438 	      , m_pricingViolUpToDate(base.m_pricingViolUpToDate)
1439 	      , m_pricingViolCo(base.m_pricingViolCo)
1440 	      , m_pricingViolCoUpToDate(base.m_pricingViolCoUpToDate)
1441 	      , m_numViol(base.m_numViol)
1442 	      , m_entertol(base.m_entertol)
1443 	      , m_leavetol(base.m_leavetol)
1444 	      , theShift(base.theShift)
1445 	      , lastShift(base.lastShift)
1446 	      , m_maxCycle(base.m_maxCycle)
1447 	      , m_numCycle(base.m_numCycle)
1448 	      , initialized(base.initialized)
1449 	      , solveVector2(0)
1450 	      , solveVector2rhs(base.solveVector2rhs)
1451 	      , solveVector3(0)
1452 	      , solveVector3rhs(base.solveVector3rhs)
1453 	      , coSolveVector2(0)
1454 	      , coSolveVector2rhs(base.coSolveVector2rhs)
1455 	      , coSolveVector3(0)
1456 	      , coSolveVector3rhs(base.coSolveVector3rhs)
1457 	      , instableLeaveNum(base.instableLeaveNum)
1458 	      , instableLeave(base.instableLeave)
1459 	      , instableLeaveVal(base.instableLeaveVal)
1460 	      , instableEnterId(base.instableEnterId)
1461 	      , instableEnter(base.instableEnter)
1462 	      , instableEnterVal(base.instableEnterVal)
1463 	      , displayLine(base.displayLine)
1464 	      , displayFreq(base.displayFreq)
1465 	      , sparsePricingFactor(base.sparsePricingFactor)
1466 	      , getStartingDecompBasis(base.getStartingDecompBasis)
1467 	      , computeDegeneracy(base.computeDegeneracy)
1468 	      , degenCompIterOffset(base.degenCompIterOffset)
1469 	      , decompIterationLimit(base.decompIterationLimit)
1470 	      , fullPerturbation(base.fullPerturbation)
1471 	      , printBasisMetric(base.printBasisMetric)
1472 	      , unitVecs(base.unitVecs)
1473 	      , primRhs(base.primRhs)
1474 	      , primVec(base.primVec)
1475 	      , dualRhs(base.dualRhs)
1476 	      , dualVec(base.dualVec)
1477 	      , addVec(base.addVec)
1478 	      , theURbound(base.theURbound)
1479 	      , theLRbound(base.theLRbound)
1480 	      , theUCbound(base.theUCbound)
1481 	      , theLCbound(base.theLCbound)
1482 	      , theUBbound(base.theUBbound)
1483 	      , theLBbound(base.theLBbound)
1484 	      , theCoTest(base.theCoTest)
1485 	      , theTest(base.theTest)
1486 	      , primalRay(base.primalRay)
1487 	      , dualFarkas(base.dualFarkas)
1488 	      , leaveCount(base.leaveCount)
1489 	      , enterCount(base.enterCount)
1490 	      , primalCount(base.primalCount)
1491 	      , polishCount(base.polishCount)
1492 	      , boundflips(base.boundflips)
1493 	      , totalboundflips(base.totalboundflips)
1494 	      , enterCycles(base.enterCycles)
1495 	      , leaveCycles(base.leaveCycles)
1496 	      , enterDegenCand(base.enterDegenCand)
1497 	      , leaveDegenCand(base.leaveDegenCand)
1498 	      , primalDegenSum(base.primalDegenSum)
1499 	      , dualDegenSum(base.dualDegenSum)
1500 	      , boundrange(base.boundrange)
1501 	      , siderange(base.siderange)
1502 	      , objrange(base.objrange)
1503 	      , infeasibilities(base.infeasibilities)
1504 	      , infeasibilitiesCo(base.infeasibilitiesCo)
1505 	      , isInfeasible(base.isInfeasible)
1506 	      , isInfeasibleCo(base.isInfeasibleCo)
1507 	      , sparsePricingLeave(base.sparsePricingLeave)
1508 	      , sparsePricingEnter(base.sparsePricingEnter)
1509 	      , sparsePricingEnterCo(base.sparsePricingEnterCo)
1510 	      , hyperPricingLeave(base.hyperPricingLeave)
1511 	      , hyperPricingEnter(base.hyperPricingEnter)
1512 	      , remainingRoundsLeave(base.remainingRoundsLeave)
1513 	      , remainingRoundsEnter(base.remainingRoundsEnter)
1514 	      , remainingRoundsEnterCo(base.remainingRoundsEnterCo)
1515 	      , weights(base.weights)
1516 	      , coWeights(base.coWeights)
1517 	      , weightsAreSetup(base.weightsAreSetup)
1518 	      , multSparseCalls(base.multSparseCalls)
1519 	      , multFullCalls(base.multFullCalls)
1520 	      , multColwiseCalls(base.multColwiseCalls)
1521 	      , multUnsetupCalls(base.multUnsetupCalls)
1522 	      , spxout(base.spxout)
1523 	      , integerVariables(base.integerVariables)
1524 	   {
1525 	      theTime = TimerFactory::createTimer(timerType);
1526 	      multTimeSparse = TimerFactory::createTimer(timerType);
1527 	      multTimeFull = TimerFactory::createTimer(timerType);
1528 	      multTimeColwise = TimerFactory::createTimer(timerType);
1529 	      multTimeUnsetup = TimerFactory::createTimer(timerType);
1530 	
1531 	      if(base.theRep == COLUMN)
1532 	      {
1533 	         thevectors   = this->colSet();
1534 	         thecovectors = this->rowSet();
1535 	         theFrhs      = &primRhs;
1536 	         theFvec      = &primVec;
1537 	         theCoPrhs    = &dualRhs;
1538 	         theCoPvec    = &dualVec;
1539 	         thePvec      = &addVec;
1540 	         theRPvec     = theCoPvec;
1541 	         theCPvec     = thePvec;
1542 	         theUbound    = &theUCbound;
1543 	         theLbound    = &theLCbound;
1544 	         theCoUbound  = &theURbound;
1545 	         theCoLbound  = &theLRbound;
1546 	      }
1547 	      else
1548 	      {
1549 	         assert(base.theRep == ROW);
1550 	
1551 	         thevectors   = this->rowSet();
1552 	         thecovectors = this->colSet();
1553 	         theFrhs      = &dualRhs;
1554 	         theFvec      = &dualVec;
1555 	         theCoPrhs    = &primRhs;
1556 	         theCoPvec    = &primVec;
1557 	         thePvec      = &addVec;
1558 	         theRPvec     = thePvec;
1559 	         theCPvec     = theCoPvec;
1560 	         theUbound    = &theURbound;
1561 	         theLbound    = &theLRbound;
1562 	         theCoUbound  = &theUCbound;
1563 	         theCoLbound  = &theLCbound;
1564 	      }
1565 	
1566 	      SPxBasisBase<R>::theLP = this;
1567 	
1568 	      if(base.thepricer == 0)
1569 	      {
1570 	         thepricer = 0;
1571 	         freePricer = false;
1572 	      }
1573 	      else
1574 	      {
1575 	         thepricer = base.thepricer->clone();
1576 	         freePricer = true;
1577 	         thepricer->clear();
1578 	         thepricer->load(this);
1579 	      }
1580 	
1581 	      if(base.theratiotester == 0)
1582 	      {
1583 	         theratiotester = 0;
1584 	         freeRatioTester = false;
1585 	      }
1586 	      else
1587 	      {
1588 	         theratiotester = base.theratiotester->clone();
1589 	         freeRatioTester = true;
1590 	         theratiotester->clear();
1591 	         theratiotester->load(this);
1592 	      }
1593 	
1594 	      if(base.thestarter == 0)
1595 	      {
1596 	         thestarter = 0;
1597 	         freeStarter = false;
1598 	      }
1599 	      else
1600 	      {
1601 	         thestarter = base.thestarter->clone();
1602 	         freeStarter = true;
1603 	      }
1604 	
1605 	      assert(SPxSolverBase<R>::isConsistent());
1606 	   }
1607 	
1608 	   template <class R>
1609 	   bool SPxSolverBase<R>::isConsistent() const
1610 	   {
1611 	#ifdef ENABLE_CONSISTENCY_CHECKS
1612 	
1613 	      if(epsilon() < 0)
1614 	         return MSGinconsistent("SPxSolverBase");
1615 	
1616 	      if(primVec.delta().getEpsilon() != dualVec.delta().getEpsilon())
1617 	         return MSGinconsistent("SPxSolverBase");
1618 	
1619 	      if(dualVec.delta().getEpsilon() != addVec.delta().getEpsilon())
1620 	         return MSGinconsistent("SPxSolverBase");
1621 	
1622 	      if(unitVecs.size() < SPxLPBase<R>::nCols() || unitVecs.size() < SPxLPBase<R>::nRows())
1623 	         return MSGinconsistent("SPxSolverBase");
1624 	
1625 	      if(initialized)
1626 	      {
1627 	         if(theFrhs->dim() != dim())
1628 	            return MSGinconsistent("SPxSolverBase");
1629 	
1630 	         if(theFvec->dim() != dim())
1631 	            return MSGinconsistent("SPxSolverBase");
1632 	
1633 	         if(theCoPrhs->dim() != dim())
1634 	            return MSGinconsistent("SPxSolverBase");
1635 	
1636 	         if(thePvec->dim() != coDim())
1637 	            return MSGinconsistent("SPxSolverBase");
1638 	
1639 	         if(theCoPvec->dim() != dim())
1640 	            return MSGinconsistent("SPxSolverBase");
1641 	
1642 	         if(theTest.dim() != coDim())
1643 	            return MSGinconsistent("SPxSolverBase");
1644 	
1645 	         if(theCoTest.dim() != dim())
1646 	            return MSGinconsistent("SPxSolverBase");
1647 	
1648 	         if(theURbound.dim() != SPxLPBase<R>::nRows())
1649 	            return MSGinconsistent("SPxSolverBase");
1650 	
1651 	         if(theLRbound.dim() != SPxLPBase<R>::nRows())
1652 	            return MSGinconsistent("SPxSolverBase");
1653 	
1654 	         if(theUCbound.dim() != SPxLPBase<R>::nCols())
1655 	            return MSGinconsistent("SPxSolverBase");
1656 	
1657 	         if(theLCbound.dim() != SPxLPBase<R>::nCols())
1658 	            return MSGinconsistent("SPxSolverBase");
1659 	
1660 	         if(theUBbound.dim() != dim())
1661 	            return MSGinconsistent("SPxSolverBase");
1662 	
1663 	         if(theLBbound.dim() != dim())
1664 	            return MSGinconsistent("SPxSolverBase");
1665 	      }
1666 	
1667 	      if(rep() == COLUMN)
1668 	      {
1669 	         if(thecovectors !=
1670 	               reinterpret_cast<const SVSetBase<R> *>(static_cast<const LPRowSetBase<R>*>(this))
1671 	               || thevectors !=
1672 	               reinterpret_cast<const SVSetBase<R> *>(static_cast<const LPColSet*>(this))
1673 	               || theFrhs != &primRhs ||
1674 	               theFvec != &primVec ||
1675 	               theCoPrhs != &dualRhs ||
1676 	               theCoPvec != &dualVec ||
1677 	               thePvec != &addVec ||
1678 	               theRPvec != theCoPvec ||
1679 	               theCPvec != thePvec ||
1680 	               theUbound != &theUCbound ||
1681 	               theLbound != &theLCbound ||
1682 	               theCoUbound != &theURbound ||
1683 	               theCoLbound != &theLRbound)
1684 	            return MSGinconsistent("SPxSolverBase");
1685 	      }
1686 	      else
1687 	      {
1688 	         if(thecovectors
1689 	               != reinterpret_cast<const SVSetBase<R> *>(static_cast<const LPColSet*>(this))
1690 	               || thevectors
1691 	               != reinterpret_cast<const SVSetBase<R> *>(static_cast<const LPRowSetBase<R>*>(this))
1692 	               || theFrhs != &dualRhs ||
1693 	               theFvec != &dualVec ||
1694 	               theCoPrhs != &primRhs ||
1695 	               theCoPvec != &primVec ||
1696 	               thePvec != &addVec ||
1697 	               theRPvec != thePvec ||
1698 	               theCPvec != theCoPvec ||
1699 	               theUbound != &theURbound ||
1700 	               theLbound != &theLRbound ||
1701 	               theCoUbound != &theUCbound ||
1702 	               theCoLbound != &theLCbound)
1703 	            return MSGinconsistent("SPxSolverBase");
1704 	      }
1705 	
1706 	      return SPxLPBase<R>::isConsistent()
1707 	             && primRhs.isConsistent()
1708 	             && primVec.isConsistent()
1709 	             && dualRhs.isConsistent()
1710 	             && dualVec.isConsistent()
1711 	             && addVec.isConsistent()
1712 	             && theTest.isConsistent()
1713 	             && theCoTest.isConsistent()
1714 	             && theURbound.isConsistent()
1715 	             && theLRbound.isConsistent()
1716 	             && theUCbound.isConsistent()
1717 	             && theLCbound.isConsistent()
1718 	             && SPxBasisBase<R>::isConsistent()
1719 	             ;
1720 	#else
1721 	      return true;
1722 	#endif
1723 	   }
1724 	
1725 	
1726 	   template <class R>
1727 	   void SPxSolverBase<R>::setTerminationTime(Real p_time)
1728 	   {
1729 	      if(p_time < 0.0)
1730 	         p_time = 0.0;
1731 	
1732 	      maxTime = p_time;
1733 	   }
1734 	
1735 	   template <class R>
1736 	   Real SPxSolverBase<R>::terminationTime() const
1737 	   {
1738 	      return maxTime;
1739 	   }
1740 	
1741 	   template <class R>
1742 	   void SPxSolverBase<R>::setTerminationIter(int p_iteration)
1743 	   {
1744 	      if(p_iteration < 0)
1745 	         p_iteration = -1;
1746 	
1747 	      maxIters = p_iteration;
1748 	   }
1749 	
1750 	   template <class R>
1751 	   int SPxSolverBase<R>::terminationIter() const
1752 	   {
1753 	      return maxIters;
1754 	   }
1755 	
1756 	   // returns whether current time limit is reached; call to time() may be skipped unless \p forceCheck is true
1757 	   template <class R>
1758 	   bool SPxSolverBase<R>::isTimeLimitReached(const bool forceCheck)
1759 	   {
1760 	      // always update the number of calls, since the user might set a time limit later in the solving process
1761 	      ++nCallsToTimelim;
1762 	
1763 	      // check if a time limit is actually set
1764 	      if(maxTime >= R(infinity))
1765 	         return false;
1766 	
1767 	      // check if the expensive system call to update the time should be skipped again
1768 	      if(forceCheck || nCallsToTimelim < NINITCALLS ||  nClckSkipsLeft <= 0)
1769 	      {
1770 	         Real currtime = time();
1771 	
1772 	         if(currtime >= maxTime)
1773 	            return true;
1774 	
1775 	         // determine the number of times the clock can be skipped again.
1776 	         int nClckSkips = MAXNCLCKSKIPS;
1777 	         Real avgtimeinterval = (currtime + cumulativeTime()) / (Real)(nCallsToTimelim);
1778 	
1779 	         // it would not be safe to skip the clock so many times since we are approaching the time limit
1780 	         if(SAFETYFACTOR * (maxTime - currtime) / (avgtimeinterval + 1e-6) < nClckSkips)
1781 	            nClckSkips = 0;
1782 	
1783 	         nClckSkipsLeft = nClckSkips;
1784 	      }
1785 	      else
1786 	         --nClckSkipsLeft;
1787 	
1788 	      return false;
1789 	   }
1790 	
1791 	
1792 	   /**@todo A first version for the termination value is
1793 	    *       implemented. Currently we check if no bound violations (shifting)
1794 	    *       is present. It might be even possible to use this termination
1795 	    *       value in case of bound violations (shifting) but in this case it
1796 	    *       is quite difficult to determine if we already reached the limit.
1797 	    */
1798 	   template <class R>
1799 	   void SPxSolverBase<R>::setTerminationValue(R p_value)
1800 	   {
1801 	      objLimit = p_value;
1802 	   }
1803 	
1804 	   template <class R>
1805 	   R SPxSolverBase<R>::terminationValue() const
1806 	   {
1807 	      return objLimit;
1808 	   }
1809 	
1810 	   template <class R>
1811 	   typename SPxSolverBase<R>::VarStatus
1812 	   SPxSolverBase<R>::basisStatusToVarStatus(typename SPxBasisBase<R>::Desc::Status stat) const
1813 	   {
1814 	      VarStatus vstat;
1815 	
1816 	      switch(stat)
1817 	      {
1818 	      case SPxBasisBase<R>::Desc::P_ON_LOWER:
1819 	         vstat = ON_LOWER;
1820 	         break;
1821 	
1822 	      case SPxBasisBase<R>::Desc::P_ON_UPPER:
1823 	         vstat = ON_UPPER;
1824 	         break;
1825 	
1826 	      case SPxBasisBase<R>::Desc::P_FIXED:
1827 	         vstat = FIXED;
1828 	         break;
1829 	
1830 	      case SPxBasisBase<R>::Desc::P_FREE:
1831 	         vstat = ZERO;
1832 	         break;
1833 	
1834 	      case SPxBasisBase<R>::Desc::D_ON_UPPER:
1835 	      case SPxBasisBase<R>::Desc::D_ON_LOWER:
1836 	      case SPxBasisBase<R>::Desc::D_ON_BOTH:
1837 	      case SPxBasisBase<R>::Desc::D_UNDEFINED:
1838 	      case SPxBasisBase<R>::Desc::D_FREE:
1839 	         vstat = BASIC;
1840 	         break;
1841 	
1842 	      default:
1843 	         MSG_ERROR(std::cerr << "ESOLVE26 ERROR: unknown basis status (" << static_cast<int>(stat) << ")"
1844 	                   << std::endl;)
1845 	         throw SPxInternalCodeException("XSOLVE22 This should never happen.");
1846 	      }
1847 	
1848 	      return vstat;
1849 	   }
1850 	
1851 	   template <class R>
1852 	   typename SPxBasisBase<R>::Desc::Status
1853 	   SPxSolverBase<R>::varStatusToBasisStatusRow(int row,
1854 	         typename SPxSolverBase<R>::VarStatus stat) const
1855 	   {
1856 	      typename SPxBasisBase<R>::Desc::Status rstat;
1857 	
1858 	      switch(stat)
1859 	      {
1860 	      case FIXED :
1861 	         assert(EQ(this->rhs(row), this->lhs(row), feastol()));
1862 	         rstat = SPxBasisBase<R>::Desc::P_FIXED;
1863 	         break;
1864 	
1865 	      case ON_UPPER :
1866 	         assert(this->rhs(row) < R(infinity));
1867 	         rstat = this->lhs(row) < this->rhs(row)
1868 	                 ? SPxBasisBase<R>::Desc::P_ON_UPPER
1869 	                 : SPxBasisBase<R>::Desc::P_FIXED;
1870 	         break;
1871 	
1872 	      case ON_LOWER :
1873 	         assert(this->lhs(row) > R(-infinity));
1874 	         rstat = this->lhs(row) < this->rhs(row)
1875 	                 ? SPxBasisBase<R>::Desc::P_ON_LOWER
1876 	                 : SPxBasisBase<R>::Desc::P_FIXED;
1877 	         break;
1878 	
1879 	      case ZERO :
1880 	         /* A 'free' row (i.e., infinite lower & upper bounds) does not really make sense. The user
1881 	          * might (think to) know better, e.g., when temporarily turning off a row. We therefore apply
1882 	          * the same adjustment as in the column case in varStatusToBasisStatusCol(). */
1883 	         rstat = SPxBasisBase<R>::Desc::P_FREE;
1884 	         break;
1885 	
1886 	      case BASIC :
1887 	         rstat = this->dualRowStatus(row);
1888 	         break;
1889 	
1890 	      default:
1891 	         MSG_ERROR(std::cerr << "ESOLVE27 ERROR: unknown VarStatus (" << int(stat) << ")"
1892 	                   << std::endl;)
1893 	         throw SPxInternalCodeException("XSOLVE23 This should never happen.");
1894 	      }
1895 	
1896 	      return rstat;
1897 	   }
1898 	
1899 	   template <class R>
1900 	   typename SPxBasisBase<R>::Desc::Status
1901 	   SPxSolverBase<R>::varStatusToBasisStatusCol(int col,
1902 	         typename SPxSolverBase<R>::VarStatus stat) const
1903 	   {
1904 	      typename SPxBasisBase<R>::Desc::Status cstat;
1905 	
1906 	      switch(stat)
1907 	      {
1908 	      case FIXED :
1909 	         if(this->upper(col) == this->lower(col))
1910 	            cstat = SPxBasisBase<R>::Desc::P_FIXED;
1911 	         else if(this->maxObj(col) > 0.0)
1912 	            cstat = SPxBasisBase<R>::Desc::P_ON_UPPER;
1913 	         else
1914 	            cstat = SPxBasisBase<R>::Desc::P_ON_LOWER;
1915 	
1916 	         break;
1917 	
1918 	      case ON_UPPER :
1919 	         assert(this->upper(col) < R(infinity));
1920 	         cstat = this->lower(col) < this->upper(col)
1921 	                 ? SPxBasisBase<R>::Desc::P_ON_UPPER
1922 	                 : SPxBasisBase<R>::Desc::P_FIXED;
1923 	         break;
1924 	
1925 	      case ON_LOWER :
1926 	         assert(this->lower(col) > R(-infinity));
1927 	         cstat = this->lower(col) < this->upper(col)
1928 	                 ? SPxBasisBase<R>::Desc::P_ON_LOWER
1929 	                 : SPxBasisBase<R>::Desc::P_FIXED;
1930 	         break;
1931 	
1932 	      case ZERO :
1933 	
1934 	         /* In this case the upper and lower bounds on the variable should be infinite. The bounds
1935 	          * might, however, have changed and we try to recover from this by changing the status to
1936 	          * 'resonable' settings. Since the status should be implicit free we still always set it
1937 	          * to P_FREE to be consistent */
1938 	         cstat = SPxBasisBase<R>::Desc::P_FREE;
1939 	         break;
1940 	
1941 	      case BASIC :
1942 	         cstat = this->dualColStatus(col);
1943 	         break;
1944 	
1945 	      default:
1946 	         MSG_ERROR(std::cerr << "ESOLVE28 ERROR: unknown VarStatus (" << int(stat) << ")"
1947 	                   << std::endl;)
1948 	         throw SPxInternalCodeException("XSOLVE24 This should never happen.");
1949 	      }
1950 	
1951 	      return cstat;
1952 	   }
1953 	
1954 	   template <class R>
1955 	   typename SPxSolverBase<R>::VarStatus SPxSolverBase<R>::getBasisRowStatus(int row) const
1956 	   {
1957 	      assert(0 <= row && row < this->nRows());
1958 	      return basisStatusToVarStatus(this->desc().rowStatus(row));
1959 	   }
1960 	
1961 	   template <class R>
1962 	   typename SPxSolverBase<R>::VarStatus SPxSolverBase<R>::getBasisColStatus(int col) const
1963 	   {
1964 	      assert(0 <= col && col < this->nCols());
1965 	      return basisStatusToVarStatus(this->desc().colStatus(col));
1966 	   }
1967 	
1968 	   template <class R>
1969 	   typename SPxSolverBase<R>::Status SPxSolverBase<R>::getBasis(VarStatus row[], VarStatus col[],
1970 	         const int rowsSize, const int colsSize) const
1971 	   {
1972 	      const typename SPxBasisBase<R>::Desc& d = this->desc();
1973 	      int i;
1974 	
1975 	      assert(rowsSize < 0 || rowsSize >= this->nRows());
1976 	      assert(colsSize < 0 || colsSize >= this->nCols());
1977 	
1978 	      if(col)
1979 	         for(i = this->nCols() - 1; i >= 0; --i)
1980 	            col[i] = basisStatusToVarStatus(d.colStatus(i));
1981 	
1982 	      if(row)
1983 	         for(i = this->nRows() - 1; i >= 0; --i)
1984 	            row[i] = basisStatusToVarStatus(d.rowStatus(i));
1985 	
1986 	      return status();
1987 	   }
1988 	
1989 	   template <class R>
1990 	   bool SPxSolverBase<R>::isBasisValid(DataArray<VarStatus> p_rows, DataArray<VarStatus> p_cols)
1991 	   {
1992 	
1993 	      int basisdim;
1994 	
1995 	      if(p_rows.size() != this->nRows() || p_cols.size() != this->nCols())
1996 	         return false;
1997 	
1998 	      basisdim = 0;
1999 	
2000 	      for(int row = this->nRows() - 1; row >= 0; --row)
2001 	      {
2002 	         if(p_rows[row] == UNDEFINED)
2003 	            return false;
2004 	         // row is basic
2005 	         else if(p_rows[row] == BASIC)
2006 	         {
2007 	            basisdim++;
2008 	         }
2009 	         // row is nonbasic
2010 	         else
2011 	         {
2012 	            if((p_rows[row] == FIXED && this->lhs(row) != this->rhs(row))
2013 	                  || (p_rows[row] == ON_UPPER && this->rhs(row) >= R(infinity))
2014 	                  || (p_rows[row] == ON_LOWER && this->lhs(row) <= R(-infinity)))
2015 	               return false;
2016 	         }
2017 	      }
2018 	
2019 	      for(int col = this->nCols() - 1; col >= 0; --col)
2020 	      {
2021 	         if(p_cols[col] == UNDEFINED)
2022 	            return false;
2023 	         // col is basic
2024 	         else if(p_cols[col] == BASIC)
2025 	         {
2026 	            basisdim++;
2027 	         }
2028 	         // col is nonbasic
2029 	         else
2030 	         {
2031 	            if((p_cols[col] == FIXED && this->lower(col) != this->upper(col))
2032 	                  || (p_cols[col] == ON_UPPER && this->upper(col) >= R(infinity))
2033 	                  || (p_cols[col] == ON_LOWER && this->lower(col) <= R(-infinity)))
2034 	               return false;
2035 	         }
2036 	      }
2037 	
2038 	      if(basisdim != dim())
2039 	         return false;
2040 	
2041 	      // basis valid
2042 	      return true;
2043 	   }
2044 	
2045 	   template <class R>
2046 	   void SPxSolverBase<R>::setBasis(const VarStatus p_rows[], const VarStatus p_cols[])
2047 	   {
2048 	      if(SPxBasisBase<R>::status() == SPxBasisBase<R>::NO_PROBLEM)
2049 	         SPxBasisBase<R>::load(this, false);
2050 	
2051 	      typename SPxBasisBase<R>::Desc ds = this->desc();
2052 	      int i;
2053 	
2054 	      for(i = 0; i < this->nRows(); i++)
2055 	         ds.rowStatus(i) = varStatusToBasisStatusRow(i, p_rows[i]);
2056 	
2057 	      for(i = 0; i < this->nCols(); i++)
2058 	         ds.colStatus(i) = varStatusToBasisStatusCol(i, p_cols[i]);
2059 	
2060 	      loadBasis(ds);
2061 	      forceRecompNonbasicValue();
2062 	   }
2063 	
2064 	   // NOTE: This only works for the row representation. Need to update to account for column representation.
2065 	   // The degenvec differs relative to the algorithm being used.
2066 	   // For the primal simplex, degenvec is the primal solution values.
2067 	   // For the dual simplex, the degenvec is the feasvec (ROW) and pVec (COLUMN).
2068 	   template <class R>
2069 	   R SPxSolverBase<R>::getDegeneracyLevel(VectorBase<R> degenvec)
2070 	   {
2071 	      int numDegenerate = 0;
2072 	      R degeneracyLevel = 0;
2073 	
2074 	      // iterating over all columns in the basis matrix
2075 	      // this identifies the basis indices and those that have a zero dual multiplier (rows) or zero reduced cost (cols).
2076 	      if(rep() == ROW)
2077 	      {
2078 	         for(int i = 0; i < this->nCols();
2079 	               ++i)   // @todo Check the use of numColsReal for the reduced problem.
2080 	         {
2081 	            // degeneracy in the dual simplex exists if there are rows with a zero dual multiplier or columns with a zero
2082 	            // reduced costs. This requirement is regardless of the objective sense.
2083 	            if(isZero(degenvec[i], feastol()))
2084 	               numDegenerate++;
2085 	         }
2086 	
2087 	         if(type() == ENTER)     // dual simplex
2088 	            degeneracyLevel = R(numDegenerate) / this->nCols();
2089 	         else                    // primal simplex
2090 	         {
2091 	            assert(type() == LEAVE);
2092 	            R degenVars = (numDegenerate > (this->nCols() - this->nRows())) ? R(numDegenerate -
2093 	                          (this->nCols() - this->nRows())) : 0.0;
2094 	            degeneracyLevel = degenVars / this->nRows();
2095 	         }
2096 	      }
2097 	      else
2098 	      {
2099 	         assert(rep() == COLUMN);
2100 	
2101 	         for(int i = 0; i < this->nCols(); i++)
2102 	         {
2103 	            if(type() == LEAVE)     // dual simplex
2104 	            {
2105 	               if(isZero(this->maxObj()[i] - degenvec[i], feastol()))
2106 	                  numDegenerate++;
2107 	            }
2108 	            else                    // primal simplex
2109 	            {
2110 	               assert(type() == ENTER);
2111 	
2112 	               if(isZero(degenvec[i], feastol()))
2113 	                  numDegenerate++;
2114 	            }
2115 	         }
2116 	
2117 	
2118 	         if(type() == LEAVE)     // dual simplex
2119 	         {
2120 	            R degenVars = this->nRows() > numDegenerate ? R(this->nRows() - numDegenerate) : 0.0;
2121 	            degeneracyLevel = degenVars / this->nCols();
2122 	         }
2123 	         else                    // primal simplex
2124 	         {
2125 	            assert(type() == ENTER);
2126 	            R degenVars = (numDegenerate > (this->nCols() - this->nRows())) ? R(numDegenerate -
2127 	                          (this->nCols() - this->nRows())) : 0.0;
2128 	            degeneracyLevel = degenVars / this->nRows();
2129 	         }
2130 	      }
2131 	
2132 	      return degeneracyLevel;
2133 	   }
2134 	
2135 	   template <class R>
2136 	   void SPxSolverBase<R>::getNdualNorms(int& nnormsRow, int& nnormsCol) const
2137 	   {
2138 	      nnormsRow = 0;
2139 	      nnormsCol = 0;
2140 	
2141 	      if(weightsAreSetup)
2142 	      {
2143 	         if(type() == SPxSolverBase<R>::LEAVE && rep() == SPxSolverBase<R>::COLUMN)
2144 	         {
2145 	            nnormsRow = coWeights.dim();
2146 	            nnormsCol = 0;
2147 	
2148 	            assert(nnormsRow == dim());
2149 	         }
2150 	         else if(type() == SPxSolverBase<R>::ENTER && rep() == SPxSolverBase<R>::ROW)
2151 	         {
2152 	            nnormsRow = weights.dim();
2153 	            nnormsCol = coWeights.dim();
2154 	
2155 	            assert(nnormsRow == coDim());
2156 	            assert(nnormsCol == dim());
2157 	         }
2158 	      }
2159 	   }
2160 	
2161 	   template <class R>
2162 	   bool SPxSolverBase<R>::getDualNorms(int& nnormsRow, int& nnormsCol, R * norms) const
2163 	   {
2164 	      nnormsRow = 0;
2165 	      nnormsCol = 0;
2166 	
2167 	      if(!weightsAreSetup)
2168 	         return false;
2169 	
2170 	      if(type() == SPxSolverBase<R>::LEAVE && rep() == SPxSolverBase<R>::COLUMN)
2171 	      {
2172 	         nnormsCol = 0;
2173 	         nnormsRow = coWeights.dim();
2174 	
2175 	         assert(nnormsRow == dim());
2176 	
2177 	         for(int i = 0; i < nnormsRow; ++i)
2178 	            norms[i] = coWeights[i];
2179 	      }
2180 	      else if(type() == SPxSolverBase<R>::ENTER && rep() == SPxSolverBase<R>::ROW)
2181 	      {
2182 	         nnormsRow = weights.dim();
2183 	         nnormsCol = coWeights.dim();
2184 	
2185 	         assert(nnormsCol == dim());
2186 	         assert(nnormsRow == coDim());
2187 	
2188 	         for(int i = 0; i < nnormsRow; ++i)
2189 	            norms[i] = weights[i];
2190 	
2191 	         for(int i = 0; i < nnormsCol; ++i)
2192 	            norms[nnormsRow + i] = coWeights[i];
2193 	      }
2194 	      else
2195 	         return false;
2196 	
2197 	      return true;
2198 	   }
2199 	
2200 	   template <class R>
2201 	   bool SPxSolverBase<R>::setDualNorms(int nnormsRow, int nnormsCol, R * norms)
2202 	   {
2203 	      weightsAreSetup = false;
2204 	
2205 	      if(type() == SPxSolverBase<R>::LEAVE && rep() == SPxSolverBase<R>::COLUMN)
2206 	      {
2207 	         coWeights.reDim(dim(), false);
2208 	         assert(coWeights.dim() >= nnormsRow);
2209 	
2210 	         for(int i = 0; i < nnormsRow; ++i)
2211 	            coWeights[i] = norms[i];
2212 	
2213 	         weightsAreSetup = true;
2214 	      }
2215 	      else if(type() == SPxSolverBase<R>::ENTER && rep() == SPxSolverBase<R>::ROW)
2216 	      {
2217 	         weights.reDim(coDim(), false);
2218 	         coWeights.reDim(dim(), false);
2219 	         assert(weights.dim() >= nnormsRow);
2220 	         assert(coWeights.dim() >= nnormsCol);
2221 	
2222 	         for(int i = 0; i < nnormsRow; ++i)
2223 	            weights[i] = norms[i];
2224 	
2225 	         for(int i = 0; i < nnormsCol; ++i)
2226 	            coWeights[i] = norms[nnormsRow + i];
2227 	
2228 	         weightsAreSetup = true;
2229 	      }
2230 	      else
2231 	         return false;
2232 	
2233 	      return true;
2234 	   }
2235 	
2236 	   template <class R>
2237 	   void SPxSolverBase<R>::setIntegralityInformation(int ncols, int* intInfo)
2238 	   {
2239 	      assert(ncols == this->nCols() || (ncols == 0 && intInfo == NULL));
2240 	
2241 	      integerVariables.reSize(ncols);
2242 	
2243 	      for(int i = 0; i < ncols; ++i)
2244 	      {
2245 	         integerVariables[i] = intInfo[i];
2246 	      }
2247 	   }
2248 	
2249 	
2250 	
2251 	   //
2252 	   // Auxiliary functions.
2253 	   //
2254 	
2255 	   // Pretty-printing of variable status.
2256 	   template <class R>
2257 	   std::ostream& operator<<(std::ostream & os,
2258 	                            const typename SPxSolverBase<R>::VarStatus & status)
2259 	   {
2260 	      switch(status)
2261 	      {
2262 	      case SPxSolverBase<R>::BASIC:
2263 	         os << "BASIC";
2264 	         break;
2265 	
2266 	      case SPxSolverBase<R>::FIXED:
2267 	         os << "FIXED";
2268 	         break;
2269 	
2270 	      case SPxSolverBase<R>::ON_LOWER:
2271 	         os << "ON_LOWER";
2272 	         break;
2273 	
2274 	      case SPxSolverBase<R>::ON_UPPER:
2275 	         os << "ON_UPPER";
2276 	         break;
2277 	
2278 	      case SPxSolverBase<R>::ZERO:
2279 	         os << "ZERO";
2280 	         break;
2281 	
2282 	      case SPxSolverBase<R>::UNDEFINED:
2283 	         os << "UNDEFINED";
2284 	         break;
2285 	
2286 	      default:
2287 	         os << "?invalid?";
2288 	         break;
2289 	      }
2290 	
2291 	      return os;
2292 	   }
2293 	
2294 	   // Pretty-printing of solver status.
2295 	   template <class R>
2296 	   std::ostream& operator<<(std::ostream & os,
2297 	                            const typename SPxSolverBase<R>::Status & status)
2298 	   {
2299 	      switch(status)
2300 	      {
2301 	      case SPxSolverBase<R>::ERROR:
2302 	         os << "ERROR";
2303 	         break;
2304 	
2305 	      case SPxSolverBase<R>::NO_RATIOTESTER:
2306 	         os << "NO_RATIOTESTER";
2307 	         break;
2308 	
2309 	      case SPxSolverBase<R>::NO_PRICER:
2310 	         os << "NO_PRICER";
2311 	         break;
2312 	
2313 	      case SPxSolverBase<R>::NO_SOLVER:
2314 	         os << "NO_SOLVER";
2315 	         break;
2316 	
2317 	      case SPxSolverBase<R>::NOT_INIT:
2318 	         os << "NOT_INIT";
2319 	         break;
2320 	
2321 	      case SPxSolverBase<R>::ABORT_CYCLING:
2322 	         os << "ABORT_CYCLING";
2323 	         break;
2324 	
2325 	      case SPxSolverBase<R>::ABORT_TIME:
2326 	         os << "ABORT_TIME";
2327 	         break;
2328 	
2329 	      case SPxSolverBase<R>::ABORT_ITER:
2330 	         os << "ABORT_ITER";
2331 	         break;
2332 	
2333 	      case SPxSolverBase<R>::ABORT_VALUE:
2334 	         os << "ABORT_VALUE";
2335 	         break;
2336 	
2337 	      case SPxSolverBase<R>::SINGULAR:
2338 	         os << "SINGULAR";
2339 	         break;
2340 	
2341 	      case SPxSolverBase<R>::NO_PROBLEM:
2342 	         os << "NO_PROBLEM";
2343 	         break;
2344 	
2345 	      case SPxSolverBase<R>::REGULAR:
2346 	         os << "REGULAR";
2347 	         break;
2348 	
2349 	      case SPxSolverBase<R>::RUNNING:
2350 	         os << "RUNNING";
2351 	         break;
2352 	
2353 	      case SPxSolverBase<R>::UNKNOWN:
2354 	         os << "UNKNOWN";
2355 	         break;
2356 	
2357 	      case SPxSolverBase<R>::OPTIMAL:
2358 	         os << "OPTIMAL";
2359 	         break;
2360 	
2361 	      case SPxSolverBase<R>::UNBOUNDED:
2362 	         os << "UNBOUNDED";
2363 	         break;
2364 	
2365 	      case SPxSolverBase<R>::INFEASIBLE:
2366 	         os << "INFEASIBLE";
2367 	         break;
2368 	
2369 	      default:
2370 	         os << "?other?";
2371 	         break;
2372 	      }
2373 	
2374 	      return os;
2375 	   }
2376 	
2377 	   // Pretty-printing of algorithm.
2378 	   template <class R>
2379 	   std::ostream& operator<<(std::ostream & os,
2380 	                            const typename SPxSolverBase<R>::Type & status)
2381 	   {
2382 	      switch(status)
2383 	      {
2384 	      case SPxSolverBase<R>::ENTER:
2385 	         os << "ENTER";
2386 	         break;
2387 	
2388 	      case SPxSolverBase<R>::LEAVE:
2389 	         os << "LEAVE";
2390 	         break;
2391 	
2392 	      default:
2393 	         os << "?other?";
2394 	         break;
2395 	      }
2396 	
2397 	      return os;
2398 	   }
2399 	
2400 	   // Pretty-printing of representation.
2401 	   template <class R>
2402 	   std::ostream& operator<<(std::ostream & os,
2403 	                            const typename SPxSolverBase<R>::Representation & status)
2404 	   {
2405 	      switch(status)
2406 	      {
2407 	      case SPxSolverBase<R>::ROW:
2408 	         os << "ROW";
2409 	         break;
2410 	
2411 	      case SPxSolverBase<R>::COLUMN:
2412 	         os << "COLUMN";
2413 	         break;
2414 	
2415 	      default:
2416 	         os << "?other?";
2417 	         break;
2418 	      }
2419 	
2420 	      return os;
2421 	   }
2422 	
2423 	
2424 	} // namespace soplex
2425