Scippy

SoPlex

Sequential object-oriented simPlex

spxdefines.h
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-2015 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 spxdefines.h
17  * @brief Debugging, floating point type and parameter definitions.
18  *
19  * In optimized code with \c NDEBUG defined, only
20  * \ref soplex::SPxOut::INFO1 "INFO1",
21  * \ref soplex::SPxOut::INFO2 "INFO2", and
22  * \ref soplex::SPxOut::INFO3 "INFO3" are set.
23  * If \c NDEBUG is not defined, the code within \#TRACE is used.
24  * If \c SOPLEX_DEBUG is defined, the code within
25  * \ref soplex::SPxOut::DEBUG "DEBUG" is also used.
26  *
27  * If \c WITH_LONG_DOUBLE is defined, all Real numbers are of type
28  * long double instead of just double.
29  */
30 #ifndef _SPXDEFINES_H_
31 #define _SPXDEFINES_H_
32 
33 #include <math.h>
34 
35 
36 
37 namespace soplex
38 {
39 #define SOPLEX_VERSION 220
40 #define SOPLEX_SUBVERSION 0
41 
42 /*-----------------------------------------------------------------------------
43  * Assertion Macros etc.
44  *-----------------------------------------------------------------------------
45  */
46 
47 /**
48  \brief Macro to turn some assertions into warnings.
49 
50  If both \c NDEBUG and \c WITH_WARNINGS are defined then the failed
51  assertion is converted to a warning. In all other cases this macro is
52  equivalent to assert().
53 
54  @param prefix Short string for grepping in source code.
55  @param expr Expression that must be satisfied.
56 */
57 #if defined (NDEBUG) && defined (WITH_WARNINGS)
58 #define ASSERT_WARN( prefix, expr ) \
59  if ( !( expr ) ) \
60  { \
61  std::cerr \
62  << prefix \
63  << " failed assertion on line " << __LINE__ \
64  << " in file " << __FILE__ << ": " \
65  << #expr \
66  << std::endl; \
67  }
68 #else // just a normal assert
69 #define ASSERT_WARN( prefix, expr ) ( assert( expr ) )
70 #endif
71 
72 
73 
74 /*-----------------------------------------------------------------------------
75  * Debugging Macros etc.
76  *-----------------------------------------------------------------------------
77  */
78 
79 /**
80  Prints/Executes \p stream with verbosity level \p verbosity, resetting
81  the old verbosity level afterwards.
82  Usually the parameter \p stream prints something out.
83  This is an internal define used by MSG_ERROR, MSG_WARNING, etc.
84 */
85 #ifdef DISABLE_VERBOSITY
86 #define DO_WITH_TMP_VERBOSITY( verbosity, spxout, do_something ) {}
87 #define DO_WITH_ERR_VERBOSITY( do_something ) {}
88 #else
89 #define DO_WITH_TMP_VERBOSITY( verbosity, spxout, do_something ) \
90  { \
91  if( &spxout != NULL ) \
92  { \
93  if( verbosity <= spxout.getVerbosity() ) \
94  { \
95  const SPxOut::Verbosity old_verbosity = spxout.getVerbosity(); \
96  spxout.setVerbosity( verbosity ); \
97  do_something; \
98  spxout.setVerbosity( old_verbosity ); \
99  } \
100  } \
101  }
102 #define DO_WITH_ERR_VERBOSITY( do_something ) { do_something; }
103 #endif
104 
105 /// Prints out message \p x if the verbosity level is at least SPxOut::ERROR.
106 #define MSG_ERROR(x) { DO_WITH_ERR_VERBOSITY( x ) }
107 /// Prints out message \p x if the verbosity level is at least SPxOut::WARNING.
108 #define MSG_WARNING(spxout, x) { DO_WITH_TMP_VERBOSITY( SPxOut::WARNING, spxout, x ) }
109 /// Prints out message \p x if the verbosity level is at least SPxOut::INFO1.
110 #define MSG_INFO1(spxout, x) { DO_WITH_TMP_VERBOSITY( SPxOut::INFO1, spxout, x ) }
111 /// Prints out message \p x if the verbosity level is at least SPxOut::INFO2.
112 #define MSG_INFO2(spxout, x) { DO_WITH_TMP_VERBOSITY( SPxOut::INFO2, spxout, x ) }
113 /// Prints out message \p x if the verbosity level is at least SPxOut::INFO3.
114 #define MSG_INFO3(spxout, x) { DO_WITH_TMP_VERBOSITY( SPxOut::INFO3, spxout, x ) }
115 
116 extern bool msginconsistent(const char* name, const char* file, int line);
117 
118 #define MSGinconsistent(name) msginconsistent(name, __FILE__, __LINE__)
119 
120 #if defined(SOPLEX_DEBUG)
121 // print output in any case, regardless of Param::verbose():
122 #define MSG_DEBUG(x) { x; }
123 #else
124 #define MSG_DEBUG(x) /**/
125 #endif //!SOPLEX_DEBUG
126 
127 
128 /*-----------------------------------------------------------------------------
129  * Long double support, Parameters and Epsilons
130  *-----------------------------------------------------------------------------
131  */
132 
133 #ifdef WITH_LONG_DOUBLE
134 
135 
136 typedef long double Real;
137 
138 #ifndef REAL
139 #define REAL(x) x##L
140 #define REAL_FORMAT "Lf"
141 #endif
142 /// default allowed bound violation
143 #ifndef DEFAULT_BND_VIOL
144 #define DEFAULT_BND_VIOL 1e-12
145 #endif
146 /// default allowed additive zero: 1.0 + EPS_ZERO == 1.0
147 #ifndef DEFAULT_EPS_ZERO
148 #define DEFAULT_EPS_ZERO 1e-28
149 #endif
150 /// epsilon for factorization
151 #ifndef DEFAULT_EPS_FACTOR
152 #define DEFAULT_EPS_FACTOR 1e-30
153 #endif
154 /// epsilon for factorization update
155 #ifndef DEFAULT_EPS_UPDATE
156 #define DEFAULT_EPS_UPDATE 1e-26
157 #endif
158 #ifndef DEFAULT_EPS_PIVOT
159 #define DEFAULT_EPS_PIVOT 1e-20
160 #endif
161 ///
162 #define DEFAULT_INFINITY 1e100
163 
164 
165 #else
166 
167 #ifdef WITH_FLOAT
168 
169 typedef float Real;
170 
171 #ifndef REAL
172 #define REAL(x) x
173 #define REAL_FORMAT "f"
174 #endif
175 /// default allowed bound violation
176 #ifndef DEFAULT_BND_VIOL
177 #define DEFAULT_BND_VIOL 1e-1
178 #endif
179 /// default allowed additive zero: 1.0 + EPS_ZERO == 1.0
180 #ifndef DEFAULT_EPS_ZERO
181 #define DEFAULT_EPS_ZERO 1e-7
182 #endif
183 #ifndef DEFAULT_EPS_FACTOR
184 #define DEFAULT_EPS_FACTOR 1e-7
185 #endif
186 #ifndef DEFAULT_EPS_UPDATE
187 #define DEFAULT_EPS_UPDATE 1e-6
188 #endif
189 #ifndef DEFAULT_EPS_PIVOT
190 #define DEFAULT_EPS_PIVOT 1e-6
191 #endif
192 #define DEFAULT_INFINITY 1e100
193 
194 
195 #else
196 
197 typedef double Real;
198 
199 #ifndef REAL
200 #define REAL(x) x
201 #define REAL_FORMAT "lf"
202 #endif
203 /// default allowed bound violation
204 #ifndef DEFAULT_BND_VIOL
205 #define DEFAULT_BND_VIOL 1e-6
206 #endif
207 /// default allowed additive zero: 1.0 + EPS_ZERO == 1.0
208 #ifndef DEFAULT_EPS_ZERO
209 #define DEFAULT_EPS_ZERO 1e-16
210 #endif
211 #ifndef DEFAULT_EPS_FACTOR
212 #define DEFAULT_EPS_FACTOR 1e-20
213 #endif
214 #ifndef DEFAULT_EPS_UPDATE
215 #define DEFAULT_EPS_UPDATE 1e-16
216 #endif
217 #ifndef DEFAULT_EPS_PIVOT
218 #define DEFAULT_EPS_PIVOT 1e-10
219 #endif
220 #define DEFAULT_INFINITY 1e100
221 
222 
223 
224 
225 
226 #endif // !WITH_FLOAT
227 #endif // !WITH_LONG_DOUBLE
228 
229 extern const Real infinity;
230 
231 class Param
232 {
233 private:
234 
235  //------------------------------------
236  /**@name Data */
237  //@{
238  /// default allowed additive zero: 1.0 + EPS_ZERO == 1.0
239  static Real s_epsilon;
240  /// epsilon for factorization
242  /// epsilon for factorization update
244  /// epsilon for pivot zero tolerance in factorization
246  //@}
247 
248 public:
249 
250  //------------------------------------
251  /**@name Access / modification */
252  //@{
253  ///
254  inline static Real epsilon()
255  {
256  return s_epsilon;
257  }
258  ///
259  static void setEpsilon(Real eps);
260  ///
261  inline static Real epsilonFactorization()
262  {
264  }
265  ///
266  static void setEpsilonFactorization(Real eps);
267  ///
268  inline static Real epsilonUpdate()
269  {
270  return s_epsilon_update;
271  }
272  ///
273  static void setEpsilonUpdate(Real eps);
274  ///
275  inline static Real epsilonPivot()
276  {
277  return s_epsilon_pivot;
278  }
279  ///
280  static void setEpsilonPivot(Real eps);
281  //@}
282 };
283 
284 #ifdef WITH_LONG_DOUBLE
285 /// returns |a|
286 inline Real spxAbs(Real a)
287 {
288  return fabsl(a);
289 }
290 
291 /// returns square root
292 inline Real spxSqrt(Real a)
293 {
294  return sqrtl(a);
295 }
296 
297 // returns the next representable value after x in the direction of y
298 #ifndef SOPLEX_LEGACY
299 inline Real spxNextafter(Real x, Real y)
300 {
301  return nextafterl(x,y);
302 }
303 #endif
304 
305 /// returns x * 2^exp
306 inline Real spxLdexp(Real x, int exp)
307 {
308  return ldexpl(x,exp);
309 }
310 
311 // returns x and exp such that y = x * 2^exp
312 inline Real spxFrexp(Real y, int* exp)
313 {
314  return frexpl(y, exp);
315 }
316 #else
317 /// returns |a|
318 inline Real spxAbs(Real a)
319 {
320  return fabs(a);
321 }
322 
323 /// returns square root
324 inline Real spxSqrt(Real a)
325 {
326  return sqrt(a);
327 }
328 
329 // returns the next representable value after x in the direction of y
330 #ifndef SOPLEX_LEGACY
332 {
333  return nextafter(x,y);
334 }
335 #endif
336 
337 /// returns x * 2^exp
338 inline Real spxLdexp(Real x, int exp)
339 {
340  return ldexp(x,exp);
341 }
342 
343 // returns x and exp such that y = x * 2^exp
344 inline Real spxFrexp(Real y, int* exp)
345 {
346  return frexp(y, exp);
347 }
348 #endif
349 
350 /// returns max(|a|,|b|)
351 inline Real maxAbs(Real a, Real b)
352 {
353  const Real absa = spxAbs(a);
354  const Real absb = spxAbs(b);
355 
356  return absa > absb ? absa : absb;
357 }
358 
359 /// returns (a-b) / max(|a|,|b|,1.0)
360 inline Real relDiff(Real a, Real b)
361 {
362  return (a - b) / (maxAbs(a, b) > 1.0 ? maxAbs(a, b) : 1.0);
363 }
364 
365 /// returns \c true iff |a-b| <= eps
366 inline bool EQ(Real a, Real b, Real eps = Param::epsilon())
367 {
368  return spxAbs(a - b) <= eps;
369 }
370 
371 /// returns \c true iff |a-b| > eps
372 inline bool NE(Real a, Real b, Real eps = Param::epsilon())
373 {
374  return spxAbs(a - b) > eps;
375 }
376 
377 /// returns \c true iff a < b + eps
378 inline bool LT(Real a, Real b, Real eps = Param::epsilon())
379 {
380  return (a - b) < -eps;
381 }
382 
383 /// returns \c true iff a <= b + eps
384 inline bool LE(Real a, Real b, Real eps = Param::epsilon())
385 {
386  return (a - b) < eps;
387 }
388 
389 /// returns \c true iff a > b + eps
390 inline bool GT(Real a, Real b, Real eps = Param::epsilon())
391 {
392  return (a - b) > eps;
393 }
394 
395 /// returns \c true iff a >= b + eps
396 inline bool GE(Real a, Real b, Real eps = Param::epsilon())
397 {
398  return (a - b) > -eps;
399 }
400 
401 /// returns \c true iff |a| <= eps
402 inline bool isZero(Real a, Real eps = Param::epsilon())
403 {
404  return spxAbs(a) <= eps;
405 }
406 
407 /// returns \c true iff |a| > eps
408 inline bool isNotZero(Real a, Real eps = Param::epsilon())
409 {
410  return spxAbs(a) > eps;
411 }
412 
413 /// returns \c true iff |relDiff(a,b)| <= eps
414 inline bool EQrel(Real a, Real b, Real eps = Param::epsilon())
415 {
416  return spxAbs(relDiff(a, b)) <= eps;
417 }
418 
419 /// returns \c true iff |relDiff(a,b)| > eps
420 inline bool NErel(Real a, Real b, Real eps = Param::epsilon())
421 {
422  return spxAbs(relDiff(a, b)) > eps;
423 }
424 
425 /// returns \c true iff relDiff(a,b) <= -eps
426 inline bool LTrel(Real a, Real b, Real eps = Param::epsilon())
427 {
428  return relDiff(a, b) <= -eps;
429 }
430 
431 /// returns \c true iff relDiff(a,b) <= eps
432 inline bool LErel(Real a, Real b, Real eps = Param::epsilon())
433 {
434  return relDiff(a, b) <= eps;
435 }
436 
437 /// returns \c true iff relDiff(a,b) > eps
438 inline bool GTrel(Real a, Real b, Real eps = Param::epsilon())
439 {
440  return relDiff(a, b) > eps;
441 }
442 
443 /// returns \c true iff relDiff(a,b) > -eps
444 inline bool GErel(Real a, Real b, Real eps = Param::epsilon())
445 {
446  return relDiff(a, b) > -eps;
447 }
448 
449 } // namespace soplex
450 #endif // _SPXDEFINES_H_