SoPlex Doxygen Documentation
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-2012 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 #include <iostream>
20 #include <assert.h>
21 
22 #include "spxscaler.h"
23 #include "spxlp.h"
24 
25 namespace soplex
26 {
27 
28 std::ostream& operator<<(std::ostream& s, const SPxScaler& sc)
29 {
30  s << sc.getName() << " scaler:" << std::endl;
31  s << "colscale = [ ";
32  for(int ci = 0; ci < sc.m_colscale.size(); ++ci )
33  s << sc.m_colscale[ci] << " ";
34  s << "]" << std::endl;
35 
36  s << "rowscale = [ ";
37  for(int ri = 0; ri < sc.m_rowscale.size(); ++ri )
38  s << sc.m_rowscale[ri] << " ";
39  s << "]" << std::endl;
40 
41  return s;
42 }
43 
45  const char* name,
46  bool colFirst,
47  bool doBoth)
48  : m_name(name)
49  , m_colFirst(colFirst)
50  , m_doBoth(doBoth)
51 {
52  assert(SPxScaler::isConsistent());
53 }
54 
56  : m_name(old.m_name)
57  , m_colscale(old.m_colscale)
58  , m_rowscale(old.m_rowscale)
59  , m_colFirst(old.m_colFirst)
60  , m_doBoth(old.m_doBoth)
61 {
62  assert(SPxScaler::isConsistent());
63 }
64 
66 {
67  m_name = 0;
68 }
69 
71 {
72  if (this != &rhs)
73  {
74  m_name = rhs.m_name;
75  m_colscale = rhs.m_colscale;
76  m_rowscale = rhs.m_rowscale;
77  m_colFirst = rhs.m_colFirst;
78  m_doBoth = rhs.m_doBoth;
79 
80  assert(SPxScaler::isConsistent());
81  }
82  return *this;
83 }
84 
85 
86 const char* SPxScaler::getName() const
87 {
88  METHOD( "SPxScaler::getName()" );
89 
90  return m_name;
91 }
92 
93 void SPxScaler::setOrder(bool colFirst)
94 {
95  METHOD( "SPxScaler::setOrder()" );
96 
97  m_colFirst = colFirst;
98 }
99 
100 void SPxScaler::setBoth(bool both)
101 {
102  METHOD( "SPxScaler::setBoth()" );
103 
104  m_doBoth = both;
105 }
106 
108 {
109  METHOD( "SPxScaler::setup()" );
110 
111  assert(lp.isConsistent());
112 
113  m_colscale.reSize(lp.nCols());
114  m_rowscale.reSize(lp.nRows());
115 
116  int i;
117 
118  for(i = 0; i < lp.nCols(); ++i )
119  m_colscale[i] = 1.0;
120 
121  for(i = 0; i < lp.nRows(); ++i )
122  m_rowscale[i] = 1.0;
123 }
124 
125 /** This function is used by computeScaleVecs and has to be overridden.
126  */
127 Real SPxScaler::computeScale(Real /*mini*/, Real /*maxi*/) const
128 {
129  METHOD( "SPxScaler::computeScale" );
130 
131  return 1.0;
132 }
133 
135  const SVSet* vecset,
136  const DataArray<Real>& coScaleval,
137  DataArray<Real>& scaleval)
138 {
139  METHOD( "SPxScaler::computeScalingVecs()" );
140 
141  Real pmax = 0.0;
142 
143  for(int i = 0; i < vecset->num(); ++i )
144  {
145  const SVector& vec = (*vecset)[i];
146 
147  Real maxi = 0.0;
148  Real mini = infinity;
149 
150  for( int j = 0; j < vec.size(); ++j)
151  {
152  Real x = fabs(vec.value(j) * coScaleval[vec.index(j)]);
153 
154  if (!isZero(x))
155  {
156  if (x > maxi)
157  maxi = x;
158  if (x < mini)
159  mini = x;
160  }
161  }
162  // empty rows/cols are possible
163  if (mini == infinity || maxi == 0.0)
164  {
165  mini = 1.0;
166  maxi = 1.0;
167  }
168  assert(mini < infinity);
169  assert(maxi > 0.0);
170 
171  scaleval[i] = 1.0 / computeScale(mini, maxi);
172 
173  Real p = maxi / mini;
174 
175  if (p > pmax)
176  pmax = p;
177  }
178  return pmax;
179 }
180 
182 {
183  METHOD( "SPxScaler::applyScaling()" );
184 
185  int i;
186 
187  for(i = 0; i < lp.nRows(); ++i )
188  {
189  SVector& vec = lp.rowVector_w(i);
190 
191  for( int j = 0; j < vec.size(); ++j)
192  vec.value(j) *= m_colscale[vec.index(j)] * m_rowscale[i];
193 
194  if (lp.rhs(i) < infinity)
195  lp.rhs_w(i) *= m_rowscale[i];
196  if (lp.lhs(i) > -infinity)
197  lp.lhs_w(i) *= m_rowscale[i];
198  }
199  for(i = 0; i < lp.nCols(); ++i )
200  {
201  SVector& vec = lp.colVector_w(i);
202 
203  for( int j = 0; j < vec.size(); ++j)
204  vec.value(j) *= m_rowscale[vec.index(j)] * m_colscale[i];
205 
206  lp.maxObj_w(i) *= m_colscale[i];
207 
208  if (lp.upper(i) < infinity)
209  lp.upper_w(i) /= m_colscale[i];
210  if (lp.lower(i) > -infinity)
211  lp.lower_w(i) /= m_colscale[i];
212  }
213  assert(lp.isConsistent());
214 }
215 
217 {
218  METHOD( "SPxScaler::unscalePrimal()" );
219 
220  assert(x.dim() == m_colscale.size());
221 
222  for(int j = 0; j < x.dim(); ++j)
223  x[j] *= m_colscale[j];
224 }
225 
227 {
228  METHOD( "SPxScaler::unscaleSlacks()" );
229 
230  assert(s.dim() == m_rowscale.size());
231 
232  for(int i = 0; i < s.dim(); ++i)
233  s[i] /= m_rowscale[i];
234 }
235 
237 {
238  METHOD( "SPxScaler::unscaleDual()" );
239 
240  assert(pi.dim() == m_rowscale.size());
241 
242  for(int i = 0; i < pi.dim(); ++i)
243  pi[i] *= m_rowscale[i];
244 }
245 
247 {
248  METHOD( "SPxScaler::unscaleRedCost()" );
249 
250  assert(r.dim() == m_colscale.size());
251 
252  for(int j = 0; j < r.dim(); ++j)
253  r[j] /= m_colscale[j];
254 }
255 
257 {
258  METHOD( "SPxScaler::minAbsColscale()" );
259 
260  Real mini = infinity;
261 
262  for(int i = 0; i < m_colscale.size(); ++i)
263  if (fabs(m_colscale[i]) < mini)
264  mini = fabs(m_colscale[i]);
265 
266  return mini;
267 }
268 
270 {
271  METHOD( "SPxScaler::maxAbsColscale()" );
272 
273  Real maxi = 0.0;
274 
275  for(int i = 0; i < m_colscale.size(); ++i)
276  if (fabs(m_colscale[i]) > maxi)
277  maxi = fabs(m_colscale[i]);
278 
279  return maxi;
280 }
281 
283 {
284  METHOD( "SPxScaler::minAbsRowscale()" );
285 
286  Real mini = infinity;
287 
288  for(int i = 0; i < m_rowscale.size(); ++i)
289  if (fabs(m_rowscale[i]) < mini)
290  mini = fabs(m_rowscale[i]);
291 
292  return mini;
293 }
294 
296 {
297  METHOD( "SPxScaler::maxAbsRowscale()" );
298 
299  Real maxi = 0.0;
300 
301  for(int i = 0; i < m_rowscale.size(); ++i)
302  if (fabs(m_rowscale[i]) > maxi)
303  maxi = fabs(m_rowscale[i]);
304 
305  return maxi;
306 }
307 
308 /** \f$\max_{j\in\mbox{ cols}}
309  * \left(\frac{\max_{i\in\mbox{ rows}}|a_ij|}
310  * {\min_{i\in\mbox{ rows}}|a_ij|}\right)\f$
311  */
313 {
314  METHOD( "SPxScaler::maxColRatio()" );
315 
316  Real pmax = 0.0;
317 
318  for(int i = 0; i < lp.nCols(); ++i )
319  {
320  const SVector& vec = lp.colVector(i);
321  Real mini = infinity;
322  Real maxi = 0.0;
323 
324  for(int j = 0; j < vec.size(); ++j)
325  {
326  Real x = fabs(vec.value(j));
327 
328  if (x < mini)
329  mini = x;
330  if (x > maxi)
331  maxi = x;
332  }
333  Real p = maxi / mini;
334 
335  if (p > pmax)
336  pmax = p;
337  }
338  return pmax;
339 }
340 
341 /** \f$\max_{i\in\mbox{ rows}}
342  * \left(\frac{\max_{j\in\mbox{ cols}}|a_ij|}
343  * {\min_{j\in\mbox{ cols}}|a_ij|}\right)\f$
344  */
346 {
347  METHOD( "SPxScaler::maxRowRatio()" );
348 
349  Real pmax = 0.0;
350 
351  for(int i = 0; i < lp.nRows(); ++i )
352  {
353  const SVector& vec = lp.rowVector(i);
354  Real mini = infinity;
355  Real maxi = 0.0;
356 
357  for(int j = 0; j < vec.size(); ++j)
358  {
359  Real x = fabs(vec.value(j));
360 
361  if (x < mini)
362  mini = x;
363  if (x > maxi)
364  maxi = x;
365  }
366  Real p = maxi / mini;
367 
368  if (p > pmax)
369  pmax = p;
370  }
371  return pmax;
372 }
373 
375 {
376 #ifdef ENABLE_CONSISTENCY_CHECKS
377  METHOD( "SPxScaler::isConsistent()" );
378 
380 #else
381  return true;
382 #endif
383 }
384 
385 } // namespace soplex
386 
387 //-----------------------------------------------------------------------------
388 //Emacs Local Variables:
389 //Emacs mode:c++
390 //Emacs c-basic-offset:3
391 //Emacs tab-width:8
392 //Emacs indent-tabs-mode:nil
393 //Emacs End:
394 //-----------------------------------------------------------------------------
395 
396