Scippy

SoPlex

Sequential object-oriented simPlex

spxscaler.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2017 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file spxscaler.cpp
17  * @brief LP scaling base class.
18  */
19 
20 #include <cmath>
21 
22 #include <iostream>
23 #include <assert.h>
24 #include "spxscaler.h"
25 #include "spxlp.h"
26 #include "dsvector.h"
27 #include "dvector.h"
28 #include <limits>
29 
30 namespace soplex
31 {
32 
33 std::ostream& operator<<(std::ostream& s, const SPxScaler& sc)
34 {
35  const DataArray < int >& colscaleExp = *(sc.m_activeColscaleExp);
36  DataArray < int > rowccaleExp = *(sc.m_activeRowscaleExp);
37 
38  s << sc.getName() << " scaler:" << std::endl;
39  s << "colscale = [ ";
40  for(int ci = 0; ci < colscaleExp.size(); ++ci )
41  s << colscaleExp[ci] << " ";
42  s << "]" << std::endl;
43 
44  s << "rowscale = [ ";
45  for(int ri = 0; ri < rowccaleExp.size(); ++ri )
46  s << rowccaleExp[ri] << " ";
47  s << "]" << std::endl;
48 
49  return s;
50 }
51 
52 
54  const char* name,
55  bool colFirst,
56  bool doBoth,
57  SPxOut* outstream)
58  : m_name(name)
59  , m_activeColscaleExp(0)
60  , m_activeRowscaleExp(0)
61  , m_colFirst(colFirst)
62  , m_doBoth(doBoth)
63  , spxout(outstream)
64 {
65  assert(SPxScaler::isConsistent());
66 }
67 
69  : m_name(old.m_name)
72  , m_colFirst(old.m_colFirst)
73  , m_doBoth(old.m_doBoth)
74  , spxout(old.spxout)
75 {
76  assert(SPxScaler::isConsistent());
77 }
78 
80 {
81  m_name = 0;
82 }
83 
85 {
86  if (this != &rhs)
87  {
88  m_name = rhs.m_name;
91  m_colFirst = rhs.m_colFirst;
92  m_doBoth = rhs.m_doBoth;
93  spxout = rhs.spxout;
94 
95  assert(SPxScaler::isConsistent());
96  }
97  return *this;
98 }
99 
100 const char* SPxScaler::getName() const
101 {
102 
103  return m_name;
104 }
105 
106 void SPxScaler::setOrder(bool colFirst)
107 {
108 
109  m_colFirst = colFirst;
110 }
111 
112 void SPxScaler::setBoth(bool both)
113 {
114 
115  m_doBoth = both;
116 }
117 
118 void SPxScaler::setRealParam(Real param, const char* name)
119 {}
120 
121 void SPxScaler::setIntParam(int param, const char* name)
122 {}
123 
125 {
126  assert(lp.isConsistent());
127  m_activeColscaleExp = &lp.LPColSetBase<Real>::scaleExp;
128  m_activeRowscaleExp = &lp.LPRowSetBase<Real>::scaleExp;
129  m_activeColscaleExp->reSize(lp.nCols());
131 
132  for( int i = 0; i < lp.nCols(); ++i)
133  (*m_activeColscaleExp)[i] = 0;
134  for( int i = 0; i < lp.nRows(); ++i)
135  (*m_activeRowscaleExp)[i] = 0;
136 
137  lp.lp_scaler = this;
138 }
139 
140 int SPxScaler::computeScaleExp(const SVector& vec, const DataArray<int>& oldScaleExp) const
141 {
142  Real maxi = 0.0;
143 
144  // find largest absolute value after applying existing scaling factors
145  for( int i = 0; i < vec.size(); ++i )
146  {
147  Real x = spxAbs(spxLdexp(vec.value(i), oldScaleExp[vec.index(i)]));
148 
149  if( GT(x, maxi) )
150  maxi = x;
151  }
152  // empty rows/cols are possible
153  if( maxi == 0.0 )
154  return 0;
155  // get exponent corresponding to new scaling factor
156  else
157  {
158  int scaleExp;
159  spxFrexp(1.0 / maxi, &(scaleExp));
160  return scaleExp - 1;
161  }
162 }
163 
164 #ifndef SOPLEX_LEGACY
165 int SPxScaler::computeScaleExp(const SVectorBase<Rational>& vec, const DataArray<int>& oldScaleExp) const
166 {
167  return 0;
168 }
169 #endif
170 
172 {
173  assert(lp.nCols() == m_activeColscaleExp->size());
174  assert(lp.nRows() == m_activeRowscaleExp->size());
175 
176  DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
177  DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
178 
179  for( int i = 0; i < lp.nRows(); ++i )
180  {
181  SVector& vec = lp.rowVector_w(i);
182  int exp1;
183  int exp2 = rowscaleExp[i];
184 
185  for( int j = 0; j < vec.size(); ++j)
186  {
187  exp1 = colscaleExp[vec.index(j)];
188  vec.value(j) = spxLdexp(vec.value(j), exp1 + exp2);
189  }
190 
191  lp.maxRowObj_w(i) = spxLdexp(lp.maxRowObj(i), exp2);
192 
193  if( lp.rhs(i) < infinity )
194  lp.rhs_w(i) = spxLdexp(lp.rhs_w(i), exp2);
195 
196  if( lp.lhs(i) > -infinity )
197  lp.lhs_w(i) = spxLdexp(lp.lhs_w(i), exp2);
198 
199  MSG_DEBUG( std::cout << "DEBUG: rowscaleExp(" << i << "): " << exp2 << std::endl; )
200  }
201 
202  for( int i = 0; i < lp.nCols(); ++i )
203  {
204  SVector& vec = lp.colVector_w(i);
205  int exp1;
206  int exp2 = colscaleExp[i];
207 
208  for( int j = 0; j < vec.size(); ++j)
209  {
210  exp1 = rowscaleExp[vec.index(j)];
211  vec.value(j) = spxLdexp(vec.value(j), exp1 + exp2);
212  }
213 
214  lp.maxObj_w(i) = spxLdexp(lp.maxObj_w(i), exp2);
215 
216  if( lp.upper(i) < infinity )
217  lp.upper_w(i) = spxLdexp(lp.upper_w(i), -exp2);
218 
219  if( lp.lower(i) > -infinity )
220  lp.lower_w(i) = spxLdexp(lp.lower_w(i), -exp2);
221 
222  MSG_DEBUG( std::cout << "DEBUG: colscaleExp(" << i << "): " << exp2 << std::endl; )
223  }
224 
225  lp.setScalingInfo(true);
226  assert(lp.isConsistent());
227 }
228 
229 /// unscale SPxLP
231 {
232  assert(lp.isScaled());
233 
234  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
235  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
236 
237  for( int i = 0; i < lp.nRows(); ++i )
238  {
239  SVector& vec = lp.rowVector_w(i);
240 
241  int exp1;
242  int exp2 = rowscaleExp[i];
243 
244  for( int j = 0; j < vec.size(); ++j)
245  {
246  exp1 = colscaleExp[vec.index(j)];
247  vec.value(j) = spxLdexp(vec.value(j), -exp1 - exp2);
248  }
249 
250  lp.maxRowObj_w(i) = spxLdexp(lp.maxRowObj(i), -exp2);
251 
252  if( lp.rhs(i) < infinity )
253  lp.rhs_w(i) = spxLdexp(lp.rhs_w(i), -exp2);
254 
255  if( lp.lhs(i) > -infinity )
256  lp.lhs_w(i) = spxLdexp(lp.lhs_w(i), -exp2);
257  }
258 
259  for( int i = 0; i < lp.nCols(); ++i )
260  {
261  SVector& vec = lp.colVector_w(i);
262 
263  int exp1;
264  int exp2 = colscaleExp[i];
265 
266  for( int j = 0; j < vec.size(); ++j)
267  {
268  exp1 = rowscaleExp[vec.index(j)];
269  vec.value(j) = spxLdexp(vec.value(j), -exp1 - exp2);
270  }
271 
272  lp.maxObj_w(i) = spxLdexp(lp.maxObj_w(i), -exp2);
273 
274  if( lp.upper(i) < infinity )
275  lp.upper_w(i) = spxLdexp(lp.upper_w(i), exp2);
276 
277  if( lp.lower(i) > -infinity )
278  lp.lower_w(i) = spxLdexp(lp.lower_w(i), exp2);
279  }
280 
281  lp._isScaled = false;
282  assert(lp.isConsistent());
283 }
284 
285 /// returns scaling factor for column \p i
286 /// todo pass the LP?!
288 {
289  return (*m_activeColscaleExp)[i];
290 }
291 
292 /// returns scaling factor for row \p i
293 /// todo pass the LP?!
295 {
296  return (*m_activeRowscaleExp)[i];
297 }
298 
299 /// gets unscaled column \p i
300 void SPxScaler::getColUnscaled(const SPxLP& lp, int i, DSVector& vec) const
301 {
302  assert(lp.isScaled());
303  assert(i < lp.nCols());
304  assert(i >= 0);
305  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
306  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
307 
308  vec = lp.LPColSet::colVector(i);
309 
310  int exp1;
311  int exp2 = colscaleExp[i];
312 
313  const SVectorReal& col = lp.colVector(i);
314  vec.setMax(col.size());
315  vec.clear();
316 
317  for( int j = 0; j < col.size(); j++ )
318  {
319  exp1 = rowscaleExp[col.index(j)];
320  vec.add(col.index(j), spxLdexp(col.value(j), -exp1 - exp2));
321  }
322 }
323 
324 /// returns maximum absolute value of unscaled column \p i
326 {
327  assert(i < lp.nCols());
328  assert(i >= 0);
329 
330  DataArray < int >& colscaleExp = *m_activeColscaleExp;
331  DataArray < int >& rowscaleExp = *m_activeRowscaleExp;
332  const SVector& colVec = lp.LPColSet::colVector(i);
333 
334  Real max = 0.0;
335  int exp1;
336  int exp2 = colscaleExp[i];
337 
338  for( int j = 0; j < colVec.size(); j++ )
339  {
340  exp1 = rowscaleExp[colVec.index(j)];
341  Real abs = spxAbs(spxLdexp(colVec.value(j), -exp1 - exp2));
342  if( abs > max )
343  max = abs;
344  }
345 
346  return max;
347 }
348 
349 /// returns minimum absolute value of unscaled column \p i
351 {
352  assert(i < lp.nCols());
353  assert(i >= 0);
354 
355  DataArray < int >& colscaleExp = *m_activeColscaleExp;
356  DataArray < int >& rowscaleExp = *m_activeRowscaleExp;
357  const SVector& colVec = lp.LPColSet::colVector(i);
358 
359  Real min = infinity;
360  int exp1;
361  int exp2 = colscaleExp[i];
362 
363  for( int j = 0; j < colVec.size(); j++ )
364  {
365  exp1 = rowscaleExp[colVec.index(j)];
366  Real abs = spxAbs(spxLdexp(colVec.value(j), -exp1 - exp2));
367  if( abs < min )
368  min = abs;
369  }
370 
371  return min;
372 }
373 
374 
375 /// returns unscaled upper bound \p i
377 {
378  assert(lp.isScaled());
379  assert(i < lp.nCols());
380  assert(i >= 0);
381 
382  if( lp.LPColSet::upper(i) < infinity )
383  {
384  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
385  return spxLdexp(lp.LPColSet::upper(i) , colscaleExp[i]);
386  }
387  else
388  return lp.LPColSet::upper(i);
389 }
390 
391 
392 /// gets unscaled upper bound vector
394 {
395  assert(lp.isScaled());
396  assert(lp.LPColSet::upper().dim() == vec.dim());
397 
398  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
399 
400  for( int i = 0; i < lp.LPColSet::upper().dim(); i++)
401  vec[i] = spxLdexp(lp.LPColSet::upper()[i], colscaleExp[i]);
402 }
403 
404 
405 /// returns unscaled upper bound vector of \p lp
407 {
408  assert(lp.isScaled());
409  assert(i < lp.nCols());
410  assert(i >= 0);
411 
412  if( lp.LPColSet::lower(i) > -infinity )
413  {
414  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
415  return spxLdexp(lp.LPColSet::lower(i), colscaleExp[i]);
416  }
417  else
418  return lp.LPColSet::lower(i);
419 }
420 
421 
422 /// returns unscaled lower bound vector of \p lp
424 {
425  assert(lp.isScaled());
426  assert(lp.LPColSet::lower().dim() == vec.dim());
427 
428  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
429 
430  for( int i = 0; i < lp.LPColSet::lower().dim(); i++)
431  vec[i] = spxLdexp(lp.LPColSet::lower()[i], colscaleExp[i]);
432 }
433 
434 /// returns unscaled objective function coefficient of \p i
436 {
437  assert(lp.isScaled());
438  assert(i < lp.nCols());
439  assert(i >= 0);
440 
441  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
442 
443  return spxLdexp(lp.LPColSet::maxObj(i) , -colscaleExp[i]);
444 }
445 
446 
447 /// gets unscaled objective function coefficient of \p i
449 {
450  assert(lp.isScaled());
451  assert(lp.LPColSet::maxObj().dim() == vec.dim());
452 
453  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
454 
455  for( int i = 0; i < lp.LPColSet::maxObj().dim(); i++)
456  vec[i] = spxLdexp(lp.LPColSet::maxObj()[i], -colscaleExp[i]);
457 }
458 
459 /// gets unscaled row \p i
460 void SPxScaler::getRowUnscaled(const SPxLP& lp, int i, DSVector& vec) const
461 {
462  assert(lp.isScaled());
463  assert(i < lp.nRows());
464  assert(i >= 0);
465 
466  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
467  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
468  int exp1;
469  int exp2 = rowscaleExp[i];
470 
471  const SVectorReal& row = lp.rowVector(i);
472  vec.setMax(row.size());
473  vec.clear();
474 
475  for( int j = 0; j < row.size(); j++ )
476  {
477  exp1 = colscaleExp[row.index(j)];
478  vec.add(row.index(j), spxLdexp(row.value(j), -exp1 - exp2));
479  }
480 }
481 
482 /// returns maximum absolute value of unscaled row \p i
484 {
485  assert(i < lp.nRows());
486  assert(i >= 0);
487  DataArray < int >& colscaleExp = *m_activeColscaleExp;
488  DataArray < int >& rowscaleExp = *m_activeRowscaleExp;
489  const SVector& rowVec = lp.LPRowSet::rowVector(i);
490 
491  Real max = 0.0;
492 
493  int exp1;
494  int exp2 = rowscaleExp[i];
495 
496  for( int j = 0; j < rowVec.size(); j++ )
497  {
498  exp1 = colscaleExp[rowVec.index(j)];
499  Real abs = spxAbs(spxLdexp(rowVec.value(j), -exp1 - exp2));
500 
501  if( GT(abs, max) )
502  max = abs;
503  }
504 
505  return max;
506 }
507 
508 /// returns minimum absolute value of unscaled row \p i
510 {
511  assert(i < lp.nRows());
512  assert(i >= 0);
513  DataArray < int >& colscaleExp = *m_activeColscaleExp;
514  DataArray < int >& rowscaleExp = *m_activeRowscaleExp;
515  const SVector& rowVec = lp.LPRowSet::rowVector(i);
516 
517  Real min = infinity;
518 
519  int exp1;
520  int exp2 = rowscaleExp[i];
521 
522  for( int j = 0; j < rowVec.size(); j++ )
523  {
524  exp1 = colscaleExp[rowVec.index(j)];
525  Real abs = spxAbs(spxLdexp(rowVec.value(j), -exp1 - exp2));
526 
527  if( LT(abs, min) )
528  min = abs;
529  }
530 
531  return min;
532 }
533 
534 /// returns unscaled right hand side \p i
536 {
537  assert(lp.isScaled());
538  assert(i < lp.nRows());
539  assert(i >= 0);
540 
541  if( lp.LPRowSet::rhs(i) < infinity )
542  {
543  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
544  return spxLdexp(lp.LPRowSet::rhs(i) , -rowscaleExp[i]);
545  }
546  else
547  return lp.LPRowSet::rhs(i);
548 }
549 
550 
551 /// gets unscaled right hand side vector
553 {
554  assert(lp.isScaled());
555  assert(lp.LPRowSet::rhs().dim() == vec.dim());
556 
557  for( int i = 0; i < lp.LPRowSet::rhs().dim(); i++)
558  {
559  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
560  vec[i] = spxLdexp(lp.LPRowSet::rhs()[i], -rowscaleExp[i]);
561  }
562 }
563 
564 
565 /// returns unscaled left hand side \p i of \p lp
567 {
568  assert(lp.isScaled());
569  assert(i < lp.nRows());
570  assert(i >= 0);
571 
572  if( lp.LPRowSet::lhs(i) > -infinity )
573  {
574  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
575  return spxLdexp(lp.LPRowSet::lhs(i) , -rowscaleExp[i]);
576  }
577  else
578  return lp.LPRowSet::lhs(i);
579 }
580 
581 /// returns unscaled left hand side vector of \p lp
583 {
584  assert(lp.isScaled());
585  assert(lp.LPRowSet::lhs().dim() == vec.dim());
586 
587  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
588 
589  for( int i = 0; i < lp.LPRowSet::lhs().dim(); i++)
590  vec[i] = spxLdexp(lp.LPRowSet::lhs()[i], -rowscaleExp[i]);
591 }
592 
593 /// returns unscaled coefficient of \p lp
594 Real SPxScaler::getCoefUnscaled(const SPxLPBase<Real>& lp, int row, int col) const
595 {
596  assert(lp.isScaled());
597  assert(row < lp.nRows());
598  assert(col < lp.nCols());
599 
600  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
601  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
602 
603  return spxLdexp(lp.colVector(col)[row], - rowscaleExp[row] - colscaleExp[col]);
604 }
605 
607 {
608  assert(lp.isScaled());
609 
610  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
611 
612  assert(x.dim() == colscaleExp.size());
613 
614  for( int j = 0; j < x.dim(); ++j )
615  x[j] = spxLdexp(x[j], colscaleExp[j]);
616 }
617 
619 {
620  assert(lp.isScaled());
621 
622  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
623 
624  assert(s.dim() == rowscaleExp.size());
625 
626  for( int i = 0; i < s.dim(); ++i )
627  s[i] = spxLdexp(s[i], -rowscaleExp[i]);
628 }
629 
631 {
632  assert(lp.isScaled());
633 
634  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
635 
636  assert(pi.dim() == rowscaleExp.size());
637 
638  for( int i = 0; i < pi.dim(); ++i )
639  pi[i] = spxLdexp(pi[i], rowscaleExp[i]);
640 }
641 
643 {
644  assert(lp.isScaled());
645 
646  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
647 
648  assert(r.dim() == colscaleExp.size());
649 
650  for( int j = 0; j < r.dim(); ++j )
651  r[j] = spxLdexp(r[j], -colscaleExp[j]);
652 }
653 
655 {
656  assert(lp.isScaled());
657 
658  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
659 
660  assert(ray.dim() == colscaleExp.size());
661 
662  for( int j = 0; j < ray.dim(); ++j )
663  ray[j] = spxLdexp(ray[j], colscaleExp[j]);
664 }
665 
667 {
668  assert(lp.isScaled());
669 
670  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
671 
672  assert(ray.dim() == rowscaleExp.size());
673 
674  for( int i = 0; i < ray.dim(); ++i )
675  ray[i] = spxLdexp(ray[i], rowscaleExp[i]);
676 }
677 
678 void SPxScaler::scaleObj(const SPxLPBase<Real>& lp, VectorReal& origObj) const
679 {
680  assert(lp.isScaled());
681 
682  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
683 
684  for( int i = 0; i < origObj.dim(); ++i )
685  {
686  origObj[i] = spxLdexp(origObj[i], colscaleExp[i]);
687  }
688 }
689 
690 Real SPxScaler::scaleObj(const SPxLPBase<Real>& lp, int i, Real origObj) const
691 {
692  assert(lp.isScaled());
693  assert(i < lp.nCols());
694  assert(i >= 0);
695 
696  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
697  int exp = colscaleExp[i];
698 
699  return spxLdexp(origObj, exp);
700 }
701 
702 Real SPxScaler::scaleElement(const SPxLPBase<Real>& lp, int row, int col, Real val) const
703 {
704  assert(lp.isScaled());
705  assert(col < lp.nCols());
706  assert(col >= 0);
707  assert(row < lp.nRows());
708  assert(row >= 0);
709 
710  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
711  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
712 
713  return spxLdexp(val, colscaleExp[col] + rowscaleExp[row]);
714 }
715 
716 Real SPxScaler::scaleLower(const SPxLPBase<Real>& lp, int col, Real lower) const
717 {
718  assert(lp.isScaled());
719  assert(col < lp.nCols());
720  assert(col >= 0);
721 
722  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
723 
724  return spxLdexp(lower, -colscaleExp[col]);
725 }
726 
727 Real SPxScaler::scaleUpper(const SPxLPBase<Real>& lp, int col, Real upper) const
728 {
729  assert(lp.isScaled());
730  assert(col < lp.nCols());
731  assert(col >= 0);
732 
733  const DataArray < int >& colscaleExp = lp.LPColSetBase<Real>::scaleExp;
734 
735  return spxLdexp(upper, -colscaleExp[col]);
736 }
737 
738 Real SPxScaler::scaleLhs(const SPxLPBase<Real>& lp, int row, Real lhs) const
739 {
740  assert(lp.isScaled());
741  assert(row < lp.nRows());
742  assert(row >= 0);
743 
744  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
745 
746  return spxLdexp(lhs, rowscaleExp[row]);
747 }
748 
749 Real SPxScaler::scaleRhs(const SPxLPBase<Real>& lp, int row, Real rhs) const
750 {
751  assert(lp.isScaled());
752  assert(row < lp.nRows());
753  assert(row >= 0);
754 
755  const DataArray < int >& rowscaleExp = lp.LPRowSetBase<Real>::scaleExp;
756 
757  return spxLdexp(rhs, rowscaleExp[row]);
758 }
759 
761 {
762  const DataArray < int >& colscaleExp = *m_activeColscaleExp;
763 
764  Real mini = infinity;
765 
766  for( int i = 0; i < colscaleExp.size(); ++i )
767  if( spxAbs(spxLdexp(1.0, colscaleExp[i])) < mini )
768  mini = spxAbs(spxLdexp(1.0, colscaleExp[i]));
769 
770  return mini;
771 }
772 
774 {
775  const DataArray < int >& colscaleExp = *m_activeColscaleExp;
776 
777  Real maxi = 0.0;
778 
779  for( int i = 0; i < colscaleExp.size(); ++i )
780  if( spxAbs(spxLdexp(1.0, colscaleExp[i])) > maxi )
781  maxi = spxAbs(spxLdexp(1.0, colscaleExp[i]));
782 
783 
784  return maxi;
785 }
786 
788 {
789  const DataArray < int >& rowscaleExp = *m_activeRowscaleExp;
790 
791  int mini = std::numeric_limits<int>::max();
792 
793  for( int i = 0; i < rowscaleExp.size(); ++i )
794  if( rowscaleExp[i] < mini )
795  mini = rowscaleExp[i];
796 
797  return spxLdexp(1.0, mini);
798 }
799 
801 {
802  const DataArray < int >& rowscaleExp = *m_activeRowscaleExp;
803 
804  int maxi = std::numeric_limits<int>::min();
805 
806  for( int i = 0; i < rowscaleExp.size(); ++i )
807  if( rowscaleExp[i] > maxi )
808  maxi = rowscaleExp[i];
809 
810  return spxLdexp(1.0, maxi);
811 }
812 
813 /** \f$\max_{j\in\mbox{ cols}}
814  * \left(\frac{\max_{i\in\mbox{ rows}}|a_ij|}
815  * {\min_{i\in\mbox{ rows}}|a_ij|}\right)\f$
816  */
818 {
819 
820  Real pmax = 0.0;
821 
822  for(int i = 0; i < lp.nCols(); ++i )
823  {
824  const SVector& vec = lp.colVector(i);
825  Real mini = infinity;
826  Real maxi = 0.0;
827 
828  for(int j = 0; j < vec.size(); ++j)
829  {
830  Real x = spxAbs(vec.value(j));
831 
832  if( isZero(x) )
833  continue;
834  if( x < mini )
835  mini = x;
836  if( x > maxi )
837  maxi = x;
838  }
839 
840  if( mini == infinity )
841  continue;
842 
843  Real p = maxi / mini;
844 
845  if (p > pmax)
846  pmax = p;
847  }
848  return pmax;
849 }
850 
851 /** \f$\max_{i\in\mbox{ rows}}
852  * \left(\frac{\max_{j\in\mbox{ cols}}|a_ij|}
853  * {\min_{j\in\mbox{ cols}}|a_ij|}\right)\f$
854  */
856 {
857 
858  Real pmax = 0.0;
859 
860  for(int i = 0; i < lp.nRows(); ++i )
861  {
862  const SVector& vec = lp.rowVector(i);
863  Real mini = infinity;
864  Real maxi = 0.0;
865 
866  for(int j = 0; j < vec.size(); ++j)
867  {
868  Real x = spxAbs(vec.value(j));
869 
870  if( isZero(x) )
871  continue;
872  if( x < mini )
873  mini = x;
874  if( x > maxi )
875  maxi = x;
876  }
877 
878  if( mini == infinity )
879  continue;
880 
881  Real p = maxi / mini;
882 
883  if (p > pmax)
884  pmax = p;
885  }
886  return pmax;
887 }
888 
889 void SPxScaler::computeExpVec(const std::vector<Real>& vec, DataArray<int>& vecExp)
890 {
891  assert(vec.size() == unsigned(vecExp.size()));
892 
893  for( unsigned i = 0; i < vec.size(); ++i )
894  {
895  frexp(vec[i], &(vecExp[int(i)]));
896  vecExp[int(i)] -= 1;
897  }
898 }
899 
901 {
902 #ifdef ENABLE_CONSISTENCY_CHECKS
904 #else
905  return true;
906 #endif
907 }
908 
909 
910 } // namespace soplex
const VectorBase< R > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:219
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:3909
virtual void unscaleDualray(const SPxLPBase< Real > &lp, Vector &ray) const
unscale dual ray given in ray.
Definition: spxscaler.cpp:666
virtual void setup(SPxLPBase< Real > &lp)
clear and setup scaling arrays in the LP
Definition: spxscaler.cpp:124
virtual void setBoth(bool both)
set wether column and row scaling should be performed
Definition: spxscaler.cpp:112
virtual void setOrder(bool colFirst)
set scaling order
Definition: spxscaler.cpp:106
bool isConsistent() const
consistency check
Definition: dataarray.h:288
virtual void unscalePrimal(const SPxLPBase< Real > &lp, Vector &x) const
unscale dense primal solution vector given in x.
Definition: spxscaler.cpp:606
const VectorBase< R > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:456
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
bool _isScaled
true, if scaling has been performed
Definition: spxlpbase.h:113
virtual Real lhsUnscaled(const SPxLPBase< Real > &lp, int i) const
returns unscaled left hand side i of lp
Definition: spxscaler.cpp:566
virtual void getRowUnscaled(const SPxLPBase< Real > &lp, int i, DSVector &vec) const
returns unscaled row i
Definition: spxscaler.cpp:460
virtual Real scaleElement(const SPxLPBase< Real > &lp, int row, int col, Real val) const
returns scaled LP element in row and col.
Definition: spxscaler.cpp:702
R & maxObj_w(int i)
Returns objective value of column i for maximization problem.
Definition: spxlpbase.h:1912
int size() const
Number of used indices.
Definition: svectorbase.h:152
bool isScaled() const
Returns true if and only if the LP is scaled.
Definition: spxlpbase.h:139
bool LT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a < b + eps
Definition: spxdefines.h:392
virtual void getLhsUnscaled(const SPxLPBase< Real > &lp, Vector &vec) const
returns unscaled left hand side vector of lp
Definition: spxscaler.cpp:582
virtual void unscaleRedCost(const SPxLPBase< Real > &lp, Vector &r) const
unscale dense reduced cost vector given in r.
Definition: spxscaler.cpp:642
virtual Real maxRowRatio(const SPxLPBase< Real > &lp) const
maximum ratio between absolute biggest and smallest element in any row.
Definition: spxscaler.cpp:855
virtual void unscaleDual(const SPxLPBase< Real > &lp, Vector &pi) const
unscale dense dual solution vector given in pi.
Definition: spxscaler.cpp:630
virtual Real scaleUpper(const SPxLPBase< Real > &lp, int col, Real upper) const
returns scaled upper bound of column col.
Definition: spxscaler.cpp:727
R & value(int n)
Reference to value of n &#39;th nonzero.
Definition: svectorbase.h:252
virtual ~SPxScaler()
destructor.
Definition: spxscaler.cpp:79
virtual bool isConsistent() const
consistency check
Definition: spxscaler.cpp:900
R & rhs_w(int i)
Returns right hand side of row i.
Definition: spxlpbase.h:1894
virtual Real getRowMaxAbsUnscaled(const SPxLPBase< Real > &lp, int i) const
returns maximum absolute value of unscaled row i
Definition: spxscaler.cpp:483
virtual void getUpperUnscaled(const SPxLPBase< Real > &lp, Vector &vec) const
returns unscaled upper bound vector of lp
Definition: spxscaler.cpp:393
virtual Real scaleLhs(const SPxLPBase< Real > &lp, int row, Real lhs) const
returns scaled left hand side of row row.
Definition: spxscaler.cpp:738
SVectorBase< R > & rowVector_w(int i)
Definition: spxlpbase.h:2139
Real spxFrexp(Real y, int *exp)
Definition: spxdefines.h:358
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:151
void add(const SVectorBase< S > &vec)
Append nonzeros of sv.
Definition: dsvectorbase.h:216
DataArray< int > * m_activeColscaleExp
pointer to currently active column scaling factors
Definition: spxscaler.h:84
virtual void applyScaling(SPxLPBase< Real > &lp)
applies m_colscale and m_rowscale to the lp.
Definition: spxscaler.cpp:171
Real spxLdexp(Real x, int exp)
returns x * 2^exp
Definition: spxdefines.h:352
virtual int computeScaleExp(const SVector &vec, const DataArray< int > &oldScaleExp) const
compute a single scaling vector , e.g. of a newly added row
Definition: spxscaler.cpp:140
double Real
Definition: spxdefines.h:218
#define MSG_DEBUG(x)
Definition: spxdefines.h:132
virtual void unscale(SPxLPBase< Real > &lp)
unscale SPxLP
Definition: spxscaler.cpp:230
SPxOut * spxout
message handler
Definition: spxscaler.h:88
bool GT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a > b + eps
Definition: spxdefines.h:404
int & index(int n)
Reference to index of n &#39;th nonzero.
Definition: svectorbase.h:234
std::ostream & operator<<(std::ostream &s, const VectorBase< R > &vec)
Output operator.
Definition: basevectors.h:1159
virtual Real upperUnscaled(const SPxLPBase< Real > &lp, int i) const
returns unscaled upper bound i
Definition: spxscaler.cpp:376
Dynamic vectors.
Wrapper for several output streams. A verbosity level is used to decide which stream to use and wheth...
Definition: spxout.h:63
virtual void getLowerUnscaled(const SPxLPBase< Real > &lp, Vector &vec) const
gets unscaled lower bound vector
Definition: spxscaler.cpp:423
const VectorBase< R > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:253
R & lower_w(int i)
Returns lower bound of column i.
Definition: spxlpbase.h:1924
virtual Real maxAbsColscale() const
absolute biggest column scaling factor
Definition: spxscaler.cpp:773
virtual int getColScaleExp(int i) const
returns scaling factor for column i
Definition: spxscaler.cpp:287
virtual void scaleObj(const SPxLPBase< Real > &lp, VectorReal &origObj) const
apply scaling to objective function vector origObj.
Definition: spxscaler.cpp:678
LPColSetBase(int pmax=-1, int pmemmax=-1)
Default constructor.
Definition: lpcolsetbase.h:585
virtual void getRhsUnscaled(const SPxLPBase< Real > &lp, Vector &vec) const
gets unscaled right hand side vector
Definition: spxscaler.cpp:552
virtual Real minAbsColscale() const
absolute smallest column scaling factor
Definition: spxscaler.cpp:760
virtual void setRealParam(Real param, const char *name="realparam")
set real parameter
Definition: spxscaler.cpp:118
const VectorBase< R > & maxRowObj() const
Definition: spxlpbase.h:297
virtual Real maxObjUnscaled(const SPxLPBase< Real > &lp, int i) const
returns unscaled objective function coefficient of i
Definition: spxscaler.cpp:435
void computeExpVec(const std::vector< Real > &vec, DataArray< int > &vecExp)
round vector entries to power of 2
Definition: spxscaler.cpp:889
DataArray< int > * m_activeRowscaleExp
pointer to currently active row scaling factors
Definition: spxscaler.h:85
void setScalingInfo(bool scaled)
set whether the LP is scaled or not
Definition: spxlpbase.h:145
R & maxRowObj_w(int i)
Returns objective function value of row i.
Definition: spxlpbase.h:1906
virtual const char * getName() const
get name of scaler
Definition: spxscaler.cpp:100
virtual Real minAbsRowscale() const
absolute smallest row scaling factor
Definition: spxscaler.cpp:787
virtual Real scaleLower(const SPxLPBase< Real > &lp, int col, Real lower) const
returns scaled lower bound of column col.
Definition: spxscaler.cpp:716
int dim() const
Dimension of vector.
Definition: vectorbase.h:215
Everything should be within this namespace.
virtual Real lowerUnscaled(const SPxLPBase< Real > &lp, int i) const
returns unscaled lower bound i
Definition: spxscaler.cpp:406
virtual Real rhsUnscaled(const SPxLPBase< Real > &lp, int i) const
returns unscaled right hand side i
Definition: spxscaler.cpp:535
void clear()
Remove all indices.
Definition: svectorbase.h:422
virtual Real getColMinAbsUnscaled(const SPxLPBase< Real > &lp, int i) const
returns minumum absolute value of unscaled column i
Definition: spxscaler.cpp:350
R & upper_w(int i)
Returns upper bound of column i.
Definition: spxlpbase.h:1918
SPxScaler * lp_scaler
points to the scaler if the lp has been scaled, to 0 otherwise
Definition: spxlpbase.h:114
bool m_colFirst
do column scaling first
Definition: spxscaler.h:86
LP scaling base class.
SPxScaler(const char *name, bool colFirst=false, bool doBoth=true, SPxOut *spxout=NULL)
constructor
Definition: spxscaler.cpp:53
Saving LPs in a form suitable for SoPlex.
const SVectorBase< R > & rowVector(int i) const
Gets row vector of row i.
Definition: spxlpbase.h:204
Dynamic sparse vectors.
LP scaler abstract base class.Instances of classes derived from SPxScaler may be loaded to SoPlex in ...
Definition: spxscaler.h:76
LPRowSetBase(int pmax=-1, int pmemmax=-1)
Default constructor.
Definition: lprowsetbase.h:668
virtual Real getRowMinAbsUnscaled(const SPxLPBase< Real > &lp, int i) const
returns minimum absolute value of unscaled row i
Definition: spxscaler.cpp:509
virtual Real maxAbsRowscale() const
absolute biggest row scaling factor
Definition: spxscaler.cpp:800
int size() const
return nr. of elements.
Definition: dataarray.h:211
bool isConsistent() const
Consistency check.
Definition: spxlpbase.h:1841
virtual int getRowScaleExp(int i) const
returns scaling factor for row i
Definition: spxscaler.cpp:294
const SVectorBase< R > & colVector(int i) const
Returns column vector of column i.
Definition: spxlpbase.h:373
virtual void getColUnscaled(const SPxLPBase< Real > &lp, int i, DSVector &vec) const
gets unscaled column i
Definition: spxscaler.cpp:300
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:157
virtual Real getCoefUnscaled(const SPxLPBase< Real > &lp, int row, int col) const
returns unscaled coefficient of lp
Definition: spxscaler.cpp:594
bool isZero(Real a, Real eps=Param::epsilon())
returns true iff |a| <= eps
Definition: spxdefines.h:416
bool m_doBoth
do columns and rows
Definition: spxscaler.h:87
virtual Real maxColRatio(const SPxLPBase< Real > &lp) const
maximum ratio between absolute biggest and smallest element in any column.
Definition: spxscaler.cpp:817
virtual Real scaleRhs(const SPxLPBase< Real > &lp, int row, Real rhs) const
returns scaled right hand side of row row.
Definition: spxscaler.cpp:749
SVectorBase< R > & colVector_w(int i)
Returns the LP as an LPRowSet.
Definition: spxlpbase.h:2133
virtual void unscaleSlacks(const SPxLPBase< Real > &lp, Vector &s) const
unscale dense slack vector given in s.
Definition: spxscaler.cpp:618
virtual void unscalePrimalray(const SPxLPBase< Real > &lp, Vector &ray) const
unscale primal ray given in ray.
Definition: spxscaler.cpp:654
virtual Real getColMaxAbsUnscaled(const SPxLPBase< Real > &lp, int i) const
returns maximum absolute value of unscaled column i
Definition: spxscaler.cpp:325
virtual void getMaxObjUnscaled(const SPxLPBase< Real > &lp, Vector &vec) const
gets unscaled objective function
Definition: spxscaler.cpp:448
void reSize(int newsize)
reset size to newsize.
Definition: dataarray.h:223
const char * m_name
Name of the scaler.
Definition: spxscaler.h:83
const VectorBase< R > & lower() const
Returns (internal and possibly scaled) lower bound vector.
Definition: spxlpbase.h:483
virtual void setIntParam(int param, const char *name="intparam")
set int parameter
Definition: spxscaler.cpp:121
SPxScaler & operator=(const SPxScaler &)
assignment operator
Definition: spxscaler.cpp:84
void setMax(int newmax=1)
Reset nonzero memory to >= newmax.
Definition: dsvectorbase.h:248
R & lhs_w(int i)
Returns left hand side of row i.
Definition: spxlpbase.h:1900