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 "soplex/spxdefines.h"
(1) Event include_recursion: #include file "/sapmnt/home1/d029903/my_work/SCIPSoPlex_coverity/scipoptsuite-8.0.1/soplex/src/soplex/spxdevexpr.h" includes itself: spxdevexpr.h -> spxdevexpr.hpp -> spxdevexpr.h
(2) Event caretline: ^
17   	#include "soplex/spxdevexpr.h"
18   	
19   	#define DEVEX_REFINETOL 2.0
20   	
21   	namespace soplex
22   	{
23   	// Definition of signature to avoid the specialization after instantiation error
24   	
25   	template <class R>
26   	void SPxDevexPR<R>::load(SPxSolverBase<R>* base)
27   	{
28   	   this->thesolver = base;
29   	   setRep(base->rep());
30   	   assert(isConsistent());
31   	}
32   	
33   	template <class R>
34   	bool SPxDevexPR<R>::isConsistent() const
35   	{
36   	#ifdef ENABLE_CONSISTENCY_CHECKS
37   	
38   	   if(this->thesolver != 0)
39   	      if(this->thesolver->weights.dim() != this->thesolver->coDim()
40   	            || this->thesolver->coWeights.dim() != this->thesolver->dim())
41   	         return MSGinconsistent("SPxDevexPR");
42   	
43   	#endif
44   	
45   	   return true;
46   	}
47   	
48   	template <class R>
49   	void SPxDevexPR<R>::setupWeights(typename SPxSolverBase<R>::Type tp)
50   	{
51   	   int i;
52   	   int coWeightSize = 0;
53   	   int weightSize = 0;
54   	
55   	   VectorBase<R>& weights = this->thesolver->weights;
56   	   VectorBase<R>& coWeights = this->thesolver->coWeights;
57   	
58   	   if(tp == SPxSolverBase<R>::ENTER)
59   	   {
60   	      coWeights.reDim(this->thesolver->dim(), false);
61   	
62   	      for(i = this->thesolver->dim() - 1; i >= coWeightSize; --i)
63   	         coWeights[i] = 2.0;
64   	
65   	      weights.reDim(this->thesolver->coDim(), false);
66   	
67   	      for(i = this->thesolver->coDim() - 1; i >= weightSize; --i)
68   	         weights[i] = 2.0;
69   	   }
70   	   else
71   	   {
72   	      coWeights.reDim(this->thesolver->dim(), false);
73   	
74   	      for(i = this->thesolver->dim() - 1; i >= coWeightSize; --i)
75   	         coWeights[i] = 1.0;
76   	   }
77   	
78   	   this->thesolver->weightsAreSetup = true;
79   	}
80   	
81   	template <class R>
82   	void SPxDevexPR<R>::setType(typename SPxSolverBase<R>::Type tp)
83   	{
84   	   setupWeights(tp);
85   	   refined = false;
86   	
87   	   bestPrices.clear();
88   	   bestPrices.setMax(this->thesolver->dim());
89   	   prices.reSize(this->thesolver->dim());
90   	
91   	   if(tp == SPxSolverBase<R>::ENTER)
92   	   {
93   	      bestPricesCo.clear();
94   	      bestPricesCo.setMax(this->thesolver->coDim());
95   	      pricesCo.reSize(this->thesolver->coDim());
96   	   }
97   	
98   	   assert(isConsistent());
99   	}
100  	
101  	/**@todo suspicious: Shouldn't the relation between dim, coDim, Vecs,
102  	 *       and CoVecs be influenced by the representation ?
103  	 */
104  	template <class R>
105  	void SPxDevexPR<R>::setRep(typename SPxSolverBase<R>::Representation)
106  	{
107  	   if(this->thesolver != 0)
108  	   {
109  	      // resize weights and initialize new entries
110  	      addedVecs(this->thesolver->coDim());
111  	      addedCoVecs(this->thesolver->dim());
112  	      assert(isConsistent());
113  	   }
114  	}
115  	
116  	// A namespace to avoid collision with other pricers
117  	namespace devexpr
118  	{
119  	template <class R>
120  	R computePrice(R viol, R weight, R tol)
121  	{
122  	   if(weight < tol)
123  	      return viol * viol / tol;
124  	   else
125  	      return viol * viol / weight;
126  	}
127  	}
128  	
129  	template <class R>
130  	int SPxDevexPR<R>::buildBestPriceVectorLeave(R feastol)
131  	{
132  	   int idx;
133  	   int nsorted;
134  	   R fTesti;
135  	   const R* fTest = this->thesolver->fTest().get_const_ptr();
136  	   const R* cpen = this->thesolver->coWeights.get_const_ptr();
137  	   typename SPxPricer<R>::IdxElement price;
138  	   prices.clear();
139  	   bestPrices.clear();
140  	
141  	   // TODO we should check infeasiblities for duplicates or loop over dimension
142  	   //      bestPrices may then also contain duplicates!
143  	   // construct vector of all prices
144  	   for(int i = this->thesolver->infeasibilities.size() - 1; i >= 0; --i)
145  	   {
146  	      idx = this->thesolver->infeasibilities.index(i);
147  	      fTesti = fTest[idx];
148  	
149  	      if(fTesti < -feastol)
150  	      {
151  	         this->thesolver->isInfeasible[idx] = this->VIOLATED;
152  	         price.idx = idx;
153  	         price.val = devexpr::computePrice(fTesti, cpen[idx], feastol);
154  	         prices.append(price);
155  	      }
156  	   }
157  	
158  	   // set up structures for the quicksort implementation
159  	   this->compare.elements = prices.get_const_ptr();
160  	   // do a partial sort to move the best ones to the front
161  	   // TODO this can be done more efficiently, since we only need the indices
162  	   nsorted = SPxQuicksortPart(prices.get_ptr(), this->compare, 0, prices.size(), HYPERPRICINGSIZE);
163  	
164  	   // copy indices of best values to bestPrices
165  	   for(int i = 0; i < nsorted; ++i)
166  	   {
167  	      bestPrices.addIdx(prices[i].idx);
168  	      this->thesolver->isInfeasible[prices[i].idx] = this->VIOLATED_AND_CHECKED;
169  	   }
170  	
171  	   if(nsorted > 0)
172  	      return prices[0].idx;
173  	   else
174  	      return -1;
175  	}
176  	
177  	template <class R>
178  	int SPxDevexPR<R>::selectLeave()
179  	{
180  	   int retid;
181  	
182  	   if(this->thesolver->hyperPricingLeave && this->thesolver->sparsePricingLeave)
183  	   {
184  	      if(bestPrices.size() < 2 || this->thesolver->basis().lastUpdate() == 0)
185  	      {
186  	         // call init method to build up price-vector and return index of largest price
187  	         retid = buildBestPriceVectorLeave(this->theeps);
188  	      }
189  	      else
190  	         retid = selectLeaveHyper(this->theeps);
191  	   }
192  	   else if(this->thesolver->sparsePricingLeave)
193  	      retid = selectLeaveSparse(this->theeps);
194  	   else
195  	      retid = selectLeaveX(this->theeps);
196  	
197  	   if(retid < 0 && !refined)
198  	   {
199  	      refined = true;
200  	      MSG_INFO3((*this->thesolver->spxout),
201  	                (*this->thesolver->spxout) << "WDEVEX02 trying refinement step..\n";)
202  	      retid = selectLeaveX(this->theeps / DEVEX_REFINETOL);
203  	   }
204  	
205  	   assert(retid < this->thesolver->dim());
206  	
207  	   return retid;
208  	}
209  	
210  	template <class R>
211  	int SPxDevexPR<R>::selectLeaveX(R feastol, int start, int incr)
212  	{
213  	   R x;
214  	
215  	   const R* fTest = this->thesolver->fTest().get_const_ptr();
216  	   const R* cpen = this->thesolver->coWeights.get_const_ptr();
217  	   R best = 0;
218  	   int bstI = -1;
219  	   int end = this->thesolver->coWeights.dim();
220  	
221  	   for(; start < end; start += incr)
222  	   {
223  	      if(fTest[start] < -feastol)
224  	      {
225  	         x = devexpr::computePrice(fTest[start], cpen[start], feastol);
226  	
227  	         if(x > best)
228  	         {
229  	            best = x;
230  	            bstI = start;
231  	            last = cpen[start];
232  	         }
233  	      }
234  	   }
235  	
236  	   return bstI;
237  	}
238  	
239  	template <class R>
240  	int SPxDevexPR<R>::selectLeaveSparse(R feastol)
241  	{
242  	   R x;
243  	
244  	   const R* fTest = this->thesolver->fTest().get_const_ptr();
245  	   const R* cpen = this->thesolver->coWeights.get_const_ptr();
246  	   R best = 0;
247  	   int bstI = -1;
248  	   int idx = -1;
249  	
250  	   for(int i = this->thesolver->infeasibilities.size() - 1; i >= 0; --i)
251  	   {
252  	      idx = this->thesolver->infeasibilities.index(i);
253  	      x = fTest[idx];
254  	
255  	      if(x < -feastol)
256  	      {
257  	         x = devexpr::computePrice(x, cpen[idx], feastol);
258  	
259  	         if(x > best)
260  	         {
261  	            best = x;
262  	            bstI = idx;
263  	            last = cpen[idx];
264  	         }
265  	      }
266  	      else
267  	      {
268  	         this->thesolver->infeasibilities.remove(i);
269  	         assert(this->thesolver->isInfeasible[idx] == this->VIOLATED
270  	                || this->thesolver->isInfeasible[idx] == this->VIOLATED_AND_CHECKED);
271  	         this->thesolver->isInfeasible[idx] = this->NOT_VIOLATED;
272  	      }
273  	   }
274  	
275  	   return bstI;
276  	}
277  	
278  	template <class R>
279  	int SPxDevexPR<R>::selectLeaveHyper(R feastol)
280  	{
281  	   R x;
282  	
283  	   const R* fTest = this->thesolver->fTest().get_const_ptr();
284  	   const R* cpen = this->thesolver->coWeights.get_const_ptr();
285  	   R best = 0;
286  	   R leastBest = -1;
287  	   int bstI = -1;
288  	   int idx = -1;
289  	
290  	   // find the best price from the short candidate list
291  	   for(int i = bestPrices.size() - 1; i >= 0; --i)
292  	   {
293  	      idx = bestPrices.index(i);
294  	      x = fTest[idx];
295  	
296  	      if(x < -feastol)
297  	      {
298  	         x = devexpr::computePrice(x, cpen[idx], feastol);
299  	
300  	         assert(x >= 0);
301  	
302  	         // update the best price of candidate list
303  	         if(x > best)
304  	         {
305  	            best = x;
306  	            bstI = idx;
307  	            last = cpen[idx];
308  	         }
309  	
310  	         // update the smallest price of candidate list
311  	         if(x < leastBest || leastBest < 0)
312  	            leastBest = x;
313  	      }
314  	      else
315  	      {
316  	         bestPrices.remove(i);
317  	         this->thesolver->isInfeasible[idx] = this->NOT_VIOLATED;
318  	      }
319  	   }
320  	
321  	   // scan the updated indices for a better price
322  	   for(int i = this->thesolver->updateViols.size() - 1; i >= 0; --i)
323  	   {
324  	      idx = this->thesolver->updateViols.index(i);
325  	
326  	      // only look at indeces that were not checked already
327  	      if(this->thesolver->isInfeasible[idx] == this->VIOLATED)
328  	      {
329  	         x = fTest[idx];
330  	         assert(x < -feastol);
331  	         x = devexpr::computePrice(x, cpen[idx], feastol);
332  	
333  	         if(x > leastBest)
334  	         {
335  	            if(x > best)
336  	            {
337  	               best = x;
338  	               bstI = idx;
339  	               last = cpen[idx];
340  	            }
341  	
342  	            // put index into candidate list
343  	            this->thesolver->isInfeasible[idx] = this->VIOLATED_AND_CHECKED;
344  	            bestPrices.addIdx(idx);
345  	         }
346  	      }
347  	   }
348  	
349  	   return bstI;
350  	}
351  	
352  	template <class R>
353  	void SPxDevexPR<R>::left4(int n, SPxId id)
354  	{
355  	   VectorBase<R>& coWeights = this->thesolver->coWeights;
356  	
357  	   if(id.isValid())
358  	   {
359  	      int i, j;
360  	      R x;
361  	      const R* rhoVec = this->thesolver->fVec().delta().values();
362  	      R rhov_1 = 1 / rhoVec[n];
363  	      R beta_q = this->thesolver->coPvec().delta().length2() * rhov_1 * rhov_1;
364  	
365  	#ifndef NDEBUG
366  	
367  	      if(spxAbs(rhoVec[n]) < this->theeps)
368  	      {
369  	         MSG_INFO3((*this->thesolver->spxout), (*this->thesolver->spxout) << "WDEVEX01: rhoVec = "
370  	                   << rhoVec[n] << " with smaller absolute value than this->theeps = " << this->theeps << std::endl;)
371  	      }
372  	
373  	#endif  // NDEBUG
374  	
375  	      //  Update #coPenalty# vector
376  	      const IdxSet& rhoIdx = this->thesolver->fVec().idx();
377  	      int len = this->thesolver->fVec().idx().size();
378  	
379  	      for(i = len - 1; i >= 0; --i)
380  	      {
381  	         j = rhoIdx.index(i);
382  	         x = rhoVec[j] * rhoVec[j] * beta_q;
383  	         // if(x > coPenalty[j])
384  	         coWeights[j] += x;
385  	      }
386  	
387  	      coWeights[n] = beta_q;
388  	   }
389  	}
390  	
391  	template <class R>
392  	SPxId SPxDevexPR<R>::buildBestPriceVectorEnterDim(R& best, R feastol)
393  	{
394  	   int idx;
395  	   int nsorted;
396  	   R x;
397  	   const R* coTest = this->thesolver->coTest().get_const_ptr();
398  	   const R* cpen = this->thesolver->coWeights.get_const_ptr();
399  	   typename SPxPricer<R>::IdxElement price;
400  	   prices.clear();
401  	   bestPrices.clear();
402  	
403  	   // construct vector of all prices
404  	   for(int i = this->thesolver->infeasibilities.size() - 1; i >= 0; --i)
405  	   {
406  	      idx = this->thesolver->infeasibilities.index(i);
407  	      x = coTest[idx];
408  	
409  	      if(x < -feastol)
410  	      {
411  	         this->thesolver->isInfeasible[idx] = this->VIOLATED;
412  	         price.idx = idx;
413  	         price.val = devexpr::computePrice(x, cpen[idx], feastol);
414  	         prices.append(price);
415  	      }
416  	      else
417  	      {
418  	         this->thesolver->infeasibilities.remove(i);
419  	         this->thesolver->isInfeasible[idx] = this->NOT_VIOLATED;
420  	      }
421  	   }
422  	
423  	   // set up structures for the quicksort implementation
424  	   this->compare.elements = prices.get_const_ptr();
425  	   // do a partial sort to move the best ones to the front
426  	   // TODO this can be done more efficiently, since we only need the indices
427  	   nsorted = SPxQuicksortPart(prices.get_ptr(), this->compare, 0, prices.size(), HYPERPRICINGSIZE);
428  	
429  	   // copy indices of best values to bestPrices
430  	   for(int i = 0; i < nsorted; ++i)
431  	   {
432  	      bestPrices.addIdx(prices[i].idx);
433  	      this->thesolver->isInfeasible[prices[i].idx] = this->VIOLATED_AND_CHECKED;
434  	   }
435  	
436  	   if(nsorted > 0)
437  	   {
438  	      best = prices[0].val;
439  	      return this->thesolver->coId(prices[0].idx);
440  	   }
441  	   else
442  	      return SPxId();
443  	}
444  	
445  	template <class R>
446  	SPxId SPxDevexPR<R>::buildBestPriceVectorEnterCoDim(R& best, R feastol)
447  	{
448  	   int idx;
449  	   int nsorted;
450  	   R x;
451  	   const R* test = this->thesolver->test().get_const_ptr();
452  	   const R* pen = this->thesolver->weights.get_const_ptr();
453  	   typename SPxPricer<R>::IdxElement price;
454  	   pricesCo.clear();
455  	   bestPricesCo.clear();
456  	
457  	   // construct vector of all prices
458  	   for(int i = this->thesolver->infeasibilitiesCo.size() - 1; i >= 0; --i)
459  	   {
460  	      idx = this->thesolver->infeasibilitiesCo.index(i);
461  	      x = test[idx];
462  	
463  	      if(x < -feastol)
464  	      {
465  	         this->thesolver->isInfeasibleCo[idx] = this->VIOLATED;
466  	         price.idx = idx;
467  	         price.val = devexpr::computePrice(x, pen[idx], feastol);
468  	         pricesCo.append(price);
469  	      }
470  	      else
471  	      {
472  	         this->thesolver->infeasibilitiesCo.remove(i);
473  	         this->thesolver->isInfeasibleCo[idx] = this->NOT_VIOLATED;
474  	      }
475  	   }
476  	
477  	   // set up structures for the quicksort implementation
478  	   this->compare.elements = pricesCo.get_const_ptr();
479  	   // do a partial sort to move the best ones to the front
480  	   // TODO this can be done more efficiently, since we only need the indices
481  	   nsorted = SPxQuicksortPart(pricesCo.get_ptr(), this->compare, 0, pricesCo.size(), HYPERPRICINGSIZE);
482  	
483  	   // copy indices of best values to bestPrices
484  	   for(int i = 0; i < nsorted; ++i)
485  	   {
486  	      bestPricesCo.addIdx(pricesCo[i].idx);
487  	      this->thesolver->isInfeasibleCo[pricesCo[i].idx] = this->VIOLATED_AND_CHECKED;
488  	   }
489  	
490  	   if(nsorted > 0)
491  	   {
492  	      best = pricesCo[0].val;
493  	      return this->thesolver->id(pricesCo[0].idx);
494  	   }
495  	   else
496  	      return SPxId();
497  	}
498  	
499  	template <class R>
500  	SPxId SPxDevexPR<R>::selectEnter()
501  	{
502  	   assert(this->thesolver != 0);
503  	
504  	   SPxId enterId;
505  	
506  	   enterId = selectEnterX(this->theeps);
507  	
508  	   if(enterId.isSPxColId() && this->thesolver->isBasic(SPxColId(enterId)))
509  	      enterId.info = 0;
510  	
511  	   if(enterId.isSPxRowId() && this->thesolver->isBasic(SPxRowId(enterId)))
512  	      enterId.info = 0;
513  	
514  	   if(!enterId.isValid() && !refined)
515  	   {
516  	      refined = true;
517  	      MSG_INFO3((*this->thesolver->spxout),
518  	                (*this->thesolver->spxout) << "WDEVEX02 trying refinement step..\n";)
519  	      enterId = selectEnterX(this->theeps / DEVEX_REFINETOL);
520  	
521  	      if(enterId.isSPxColId() && this->thesolver->isBasic(SPxColId(enterId)))
522  	         enterId.info = 0;
523  	
524  	      if(enterId.isSPxRowId() && this->thesolver->isBasic(SPxRowId(enterId)))
525  	         enterId.info = 0;
526  	   }
527  	
528  	   return enterId;
529  	}
530  	
531  	// choose the best entering index among columns and rows but prefer sparsity
532  	template <class R>
533  	SPxId SPxDevexPR<R>::selectEnterX(R tol)
534  	{
535  	   SPxId enterId;
536  	   SPxId enterCoId;
537  	   R best;
538  	   R bestCo;
539  	
540  	   best = 0;
541  	   bestCo = 0;
542  	   last = 1.0;
543  	
544  	   // avoid uninitialized value later on in entered4X()
545  	   last = 1.0;
546  	
547  	   if(this->thesolver->hyperPricingEnter && !refined)
548  	   {
549  	      if(bestPrices.size() < 2 || this->thesolver->basis().lastUpdate() == 0)
550  	         enterCoId = (this->thesolver->sparsePricingEnter) ? buildBestPriceVectorEnterDim(best,
551  	                     tol) : selectEnterDenseDim(best, tol);
552  	      else
553  	         enterCoId = (this->thesolver->sparsePricingEnter) ? selectEnterHyperDim(best,
554  	                     tol) : selectEnterDenseDim(best, tol);
555  	
556  	      if(bestPricesCo.size() < 2 || this->thesolver->basis().lastUpdate() == 0)
557  	         enterId = (this->thesolver->sparsePricingEnterCo) ? buildBestPriceVectorEnterCoDim(bestCo,
558  	                   tol) : selectEnterDenseCoDim(bestCo, tol);
559  	      else
560  	         enterId = (this->thesolver->sparsePricingEnterCo) ? selectEnterHyperCoDim(bestCo,
561  	                   tol) : selectEnterDenseCoDim(bestCo, tol);
562  	   }
563  	   else
564  	   {
565  	      enterCoId = (this->thesolver->sparsePricingEnter
566  	                   && !refined) ? selectEnterSparseDim(best, tol) : selectEnterDenseDim(best, tol);
567  	      enterId = (this->thesolver->sparsePricingEnterCo
568  	                 && !refined) ? selectEnterSparseCoDim(bestCo, tol) : selectEnterDenseCoDim(bestCo, tol);
569  	   }
570  	
571  	   // prefer coIds to increase the number of unit vectors in the basis matrix, i.e., rows in colrep and cols in rowrep
572  	   if(enterCoId.isValid() && (best > SPARSITY_TRADEOFF * bestCo || !enterId.isValid()))
573  	      return enterCoId;
574  	   else
575  	      return enterId;
576  	}
577  	
578  	template <class R>
579  	SPxId SPxDevexPR<R>::selectEnterHyperDim(R& best, R feastol)
580  	{
581  	   const R* cTest = this->thesolver->coTest().get_const_ptr();
582  	   const R* cpen = this->thesolver->coWeights.get_const_ptr();
583  	   R leastBest = -1;
584  	   R x;
585  	   int enterIdx = -1;
586  	   int idx;
587  	
588  	   // find the best price from short candidate list
589  	   for(int i = bestPrices.size() - 1; i >= 0; --i)
590  	   {
591  	      idx = bestPrices.index(i);
592  	      x = cTest[idx];
593  	
594  	      if(x < -feastol)
595  	      {
596  	         x = devexpr::computePrice(x, cpen[idx], feastol);
597  	
598  	         assert(x >= 0);
599  	
600  	         // update the best price of candidate list
601  	         if(x > best)
602  	         {
603  	            best = x;
604  	            enterIdx = idx;
605  	            last = cpen[idx];
606  	         }
607  	
608  	         // update the smallest price of candidate list
609  	         if(x < leastBest || leastBest < 0)
610  	            leastBest = x;
611  	      }
612  	      else
613  	      {
614  	         bestPrices.remove(i);
615  	         this->thesolver->isInfeasible[idx] = this->NOT_VIOLATED;
616  	      }
617  	   }
618  	
619  	   // scan the updated indeces for a better price
620  	   for(int i = this->thesolver->updateViols.size() - 1; i >= 0; --i)
621  	   {
622  	      idx = this->thesolver->updateViols.index(i);
623  	
624  	      // only look at indeces that were not checked already
625  	      if(this->thesolver->isInfeasible[idx] == this->VIOLATED)
626  	      {
627  	         x = cTest[idx];
628  	
629  	         if(x < -feastol)
630  	         {
631  	            x = devexpr::computePrice(x, cpen[idx], feastol);
632  	
633  	            if(x > leastBest)
634  	            {
635  	               if(x > best)
636  	               {
637  	                  best = x;
638  	                  enterIdx = idx;
639  	                  last = cpen[idx];
640  	               }
641  	
642  	               // put index into candidate list
643  	               this->thesolver->isInfeasible[idx] = this->VIOLATED_AND_CHECKED;
644  	               bestPrices.addIdx(idx);
645  	            }
646  	         }
647  	         else
648  	         {
649  	            this->thesolver->isInfeasible[idx] = this->NOT_VIOLATED;
650  	         }
651  	      }
652  	   }
653  	
654  	   if(enterIdx >= 0)
655  	      return this->thesolver->coId(enterIdx);
656  	   else
657  	      return SPxId();
658  	}
659  	
660  	template <class R>
661  	SPxId SPxDevexPR<R>::selectEnterHyperCoDim(R& best, R feastol)
662  	{
663  	   const R* test = this->thesolver->test().get_const_ptr();
664  	   const R* pen = this->thesolver->weights.get_const_ptr();
665  	   R leastBest = -1;
666  	   R x;
667  	   int enterIdx = -1;
668  	   int idx;
669  	
670  	   // find the best price from short candidate list
671  	   for(int i = bestPricesCo.size() - 1; i >= 0; --i)
672  	   {
673  	      idx = bestPricesCo.index(i);
674  	      x = test[idx];
675  	
676  	      if(x < -feastol)
677  	      {
678  	         x = devexpr::computePrice(x, pen[idx], feastol);
679  	
680  	         assert(x >= 0);
681  	
682  	         // update the best price of candidate list
683  	         if(x > best)
684  	         {
685  	            best = x;
686  	            enterIdx = idx;
687  	            last = pen[idx];
688  	         }
689  	
690  	         // update the smallest price of candidate list
691  	         if(x < leastBest || leastBest < 0)
692  	            leastBest = x;
693  	      }
694  	      else
695  	      {
696  	         bestPricesCo.remove(i);
697  	         this->thesolver->isInfeasibleCo[idx] = this->NOT_VIOLATED;
698  	      }
699  	   }
700  	
701  	   //scan the updated indeces for a better price
702  	   for(int i = this->thesolver->updateViolsCo.size() - 1; i >= 0; --i)
703  	   {
704  	      idx = this->thesolver->updateViolsCo.index(i);
705  	
706  	      // only look at indeces that were not checked already
707  	      if(this->thesolver->isInfeasibleCo[idx] == this->VIOLATED)
708  	      {
709  	         x = test[idx];
710  	
711  	         if(x < -feastol)
712  	         {
713  	            x = devexpr::computePrice(x, pen[idx], feastol);
714  	
715  	            if(x > leastBest)
716  	            {
717  	               if(x > best)
718  	               {
719  	                  best = x;
720  	                  enterIdx = idx;
721  	                  last = pen[idx];
722  	               }
723  	
724  	               // put index into candidate list
725  	               this->thesolver->isInfeasibleCo[idx] = this->VIOLATED_AND_CHECKED;
726  	               bestPricesCo.addIdx(idx);
727  	            }
728  	         }
729  	         else
730  	         {
731  	            this->thesolver->isInfeasibleCo[idx] = this->NOT_VIOLATED;
732  	         }
733  	      }
734  	   }
735  	
736  	   if(enterIdx >= 0)
737  	      return this->thesolver->id(enterIdx);
738  	   else
739  	      return SPxId();
740  	}
741  	
742  	
743  	template <class R>
744  	SPxId SPxDevexPR<R>::selectEnterSparseDim(R& best, R feastol)
745  	{
746  	   const R* cTest = this->thesolver->coTest().get_const_ptr();
747  	   const R* cpen = this->thesolver->coWeights.get_const_ptr();
748  	   int enterIdx = -1;
749  	   int idx;
750  	   R x;
751  	
752  	   assert(this->thesolver->coWeights.dim() == this->thesolver->coTest().dim());
753  	
754  	   for(int i = this->thesolver->infeasibilities.size() - 1; i >= 0; --i)
755  	   {
756  	      idx = this->thesolver->infeasibilities.index(i);
757  	      x = cTest[idx];
758  	
759  	      if(x < -feastol)
760  	      {
761  	         x = devexpr::computePrice(x, cpen[idx], feastol);
762  	
763  	         if(x > best)
764  	         {
765  	            best = x;
766  	            enterIdx = idx;
767  	            last = cpen[idx];
768  	         }
769  	      }
770  	      else
771  	      {
772  	         this->thesolver->infeasibilities.remove(i);
773  	         this->thesolver->isInfeasible[idx] = this->NOT_VIOLATED;
774  	      }
775  	   }
776  	
777  	   if(enterIdx >= 0)
778  	      return this->thesolver->coId(enterIdx);
779  	
780  	   return SPxId();
781  	}
782  	
783  	
784  	template <class R>
785  	SPxId SPxDevexPR<R>::selectEnterSparseCoDim(R& best, R feastol)
786  	{
787  	   const R* test = this->thesolver->test().get_const_ptr();
788  	   const R* pen = this->thesolver->weights.get_const_ptr();
789  	   int enterIdx = -1;
790  	   int idx;
791  	   R x;
792  	
793  	   assert(this->thesolver->weights.dim() == this->thesolver->test().dim());
794  	
795  	   for(int i = this->thesolver->infeasibilitiesCo.size() - 1; i >= 0; --i)
796  	   {
797  	      idx = this->thesolver->infeasibilitiesCo.index(i);
798  	      x = test[idx];
799  	
800  	      if(x < -feastol)
801  	      {
802  	         x = devexpr::computePrice(x, pen[idx], feastol);
803  	
804  	         if(x > best)
805  	         {
806  	            best = x;
807  	            enterIdx = idx;
808  	            last = pen[idx];
809  	         }
810  	      }
811  	      else
812  	      {
813  	         this->thesolver->infeasibilitiesCo.remove(i);
814  	         this->thesolver->isInfeasibleCo[idx] = this->NOT_VIOLATED;
815  	      }
816  	   }
817  	
818  	   if(enterIdx >= 0)
819  	      return this->thesolver->id(enterIdx);
820  	
821  	   return SPxId();
822  	}
823  	
824  	
825  	template <class R>
826  	SPxId SPxDevexPR<R>::selectEnterDenseDim(R& best, R feastol, int start, int incr)
827  	{
828  	   const R* cTest = this->thesolver->coTest().get_const_ptr();
829  	   const R* cpen = this->thesolver->coWeights.get_const_ptr();
830  	   int end = this->thesolver->coWeights.dim();
831  	   int enterIdx = -1;
832  	   R x;
833  	
834  	   assert(end == this->thesolver->coTest().dim());
835  	
836  	   for(; start < end; start += incr)
837  	   {
838  	      x = cTest[start];
839  	
840  	      if(x < -feastol)
841  	      {
842  	         x = devexpr::computePrice(x, cpen[start], feastol);
843  	
844  	         if(x > best)
845  	         {
846  	            best = x;
847  	            enterIdx = start;
848  	            last = cpen[start];
849  	         }
850  	      }
851  	   }
852  	
853  	   if(enterIdx >= 0)
854  	      return this->thesolver->coId(enterIdx);
855  	
856  	   return SPxId();
857  	}
858  	
859  	template <class R>
860  	SPxId SPxDevexPR<R>::selectEnterDenseCoDim(R& best, R feastol, int start, int incr)
861  	{
862  	   const R* test = this->thesolver->test().get_const_ptr();
863  	   const R* pen = this->thesolver->weights.get_const_ptr();
864  	   int end = this->thesolver->weights.dim();
865  	   int enterIdx = -1;
866  	   R x;
867  	
868  	   assert(end == this->thesolver->test().dim());
869  	
870  	   for(; start < end; start += incr)
871  	   {
872  	      x = test[start];
873  	
874  	      if(test[start] < -feastol)
875  	      {
876  	         x = devexpr::computePrice(x, pen[start], feastol);
877  	
878  	         if(x > best)
879  	         {
880  	            best = x;
881  	            enterIdx = start;
882  	            last = pen[start];
883  	         }
884  	      }
885  	   }
886  	
887  	   if(enterIdx >= 0)
888  	      return this->thesolver->id(enterIdx);
889  	
890  	   return SPxId();
891  	}
892  	
893  	
894  	/**@todo suspicious: the pricer should be informed, that variable id
895  	   has entered the basis at position n, but the id is not used here
896  	   (this is true for all pricers)
897  	*/
898  	template <class R>
899  	void SPxDevexPR<R>::entered4(SPxId /*id*/, int n)
900  	{
901  	   VectorBase<R>& weights = this->thesolver->weights;
902  	   VectorBase<R>& coWeights = this->thesolver->coWeights;
903  	
904  	   if(n >= 0 && n < this->thesolver->dim())
905  	   {
906  	      const R* pVec = this->thesolver->pVec().delta().values();
907  	      const IdxSet& pIdx = this->thesolver->pVec().idx();
908  	      const R* coPvec = this->thesolver->coPvec().delta().values();
909  	      const IdxSet& coPidx = this->thesolver->coPvec().idx();
910  	      R xi_p = 1 / this->thesolver->fVec().delta()[n];
911  	      int i, j;
912  	
913  	      assert(this->thesolver->fVec().delta()[n] > this->thesolver->epsilon()
914  	             || this->thesolver->fVec().delta()[n] < -this->thesolver->epsilon());
915  	
916  	      xi_p = xi_p * xi_p * last;
917  	
918  	      for(j = coPidx.size() - 1; j >= 0; --j)
919  	      {
920  	         i = coPidx.index(j);
921  	         coWeights[i] += xi_p * coPvec[i] * coPvec[i];
922  	
923  	         if(coWeights[i] <= 1 || coWeights[i] > 1e+6)
924  	         {
925  	            setupWeights(SPxSolverBase<R>::ENTER);
926  	            return;
927  	         }
928  	      }
929  	
930  	      for(j = pIdx.size() - 1; j >= 0; --j)
931  	      {
932  	         i = pIdx.index(j);
933  	         weights[i] += xi_p * pVec[i] * pVec[i];
934  	
935  	         if(weights[i] <= 1 || weights[i] > 1e+6)
936  	         {
937  	            setupWeights(SPxSolverBase<R>::ENTER);
938  	            return;
939  	         }
940  	      }
941  	   }
942  	}
943  	
944  	template <class R>
945  	void SPxDevexPR<R>::addedVecs(int n)
946  	{
947  	   int initval = (this->thesolver->type() == SPxSolverBase<R>::ENTER) ? 2 : 1;
948  	   VectorBase<R>& weights = this->thesolver->weights;
949  	   n = weights.dim();
950  	   weights.reDim(this->thesolver->coDim());
951  	
952  	   for(int i = weights.dim() - 1; i >= n; --i)
953  	      weights[i] = initval;
954  	}
955  	
956  	template <class R>
957  	void SPxDevexPR<R>::addedCoVecs(int n)
958  	{
959  	   int initval = (this->thesolver->type() == SPxSolverBase<R>::ENTER) ? 2 : 1;
960  	   VectorBase<R>& coWeights = this->thesolver->coWeights;
961  	   n = coWeights.dim();
962  	   coWeights.reDim(this->thesolver->dim());
963  	
964  	   for(int i = coWeights.dim() - 1; i >= n; --i)
965  	      coWeights[i] = initval;
966  	}
967  	
968  	} // namespace soplex
969