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-2020 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 #include <cmath>
33 
34 #ifdef _MSC_VER
35 #include <float.h>
36 #endif
37 
38 #include <assert.h>
39 #include <stdarg.h>
40 #include <stdio.h>
41 #include <iostream>
42 
43 #include <cstdlib>
44 
45 #ifdef SOPLEX_WITH_BOOST
46 #include "boost/multiprecision/number.hpp"
47 #endif
48 
49 namespace soplex
50 {
51 // Overloaded EQ function
52 bool EQ(int a, int b);
53 
54 #define SOPLEX_VERSION 500
55 #define SOPLEX_SUBVERSION 0
56 #define SOPLEX_APIVERSION 11
57 #define SOPLEX_COPYRIGHT "Copyright (c) 1996-2020 Konrad-Zuse-Zentrum fuer Informationstechnik Berlin (ZIB)"
58 
59 /*-----------------------------------------------------------------------------
60  * Assertion Macros etc.
61  *-----------------------------------------------------------------------------
62  */
63 
64 /**
65  \brief Macro to turn some assertions into warnings.
66 
67  If both \c NDEBUG and \c WITH_WARNINGS are defined then the failed
68  assertion is converted to a warning. In all other cases this macro is
69  equivalent to assert().
70 
71  @param prefix Short string for grepping in source code.
72  @param expr Expression that must be satisfied.
73 */
74 #if defined (NDEBUG) && defined (WITH_WARNINGS)
75 #define ASSERT_WARN( prefix, expr ) \
76  if ( !( expr ) ) \
77  { \
78  std::cerr \
79  << prefix \
80  << " failed assertion on line " << __LINE__ \
81  << " in file " << __FILE__ << ": " \
82  << #expr \
83  << std::endl; \
84  }
85 #else // just a normal assert
86 #define ASSERT_WARN( prefix, expr ) ( assert( expr ) )
87 #endif
88 
89 
90 
91 /*-----------------------------------------------------------------------------
92  * Debugging Macros etc.
93  *-----------------------------------------------------------------------------
94  */
95 
96 /**
97  Prints/Executes \p stream with verbosity level \p verbosity, resetting
98  the old verbosity level afterwards.
99  Usually the parameter \p stream prints something out.
100  This is an internal define used by MSG_ERROR, MSG_WARNING, etc.
101 */
102 #ifdef DISABLE_VERBOSITY
103 #define DO_WITH_TMP_VERBOSITY( verbosity, spxout, do_something ) {}
104 #define DO_WITH_ERR_VERBOSITY( do_something ) {}
105 #else
106 #define DO_WITH_TMP_VERBOSITY( verbosity, spxout, do_something ) \
107  { \
108  if( &spxout != NULL ) \
109  { \
110  if( verbosity <= spxout.getVerbosity() ) \
111  { \
112  const SPxOut::Verbosity old_verbosity = spxout.getVerbosity(); \
113  spxout.setVerbosity( verbosity ); \
114  do_something; \
115  spxout.setVerbosity( old_verbosity ); \
116  } \
117  } \
118  }
119 #define DO_WITH_ERR_VERBOSITY( do_something ) { do_something; }
120 #endif
121 
122 /// Prints out message \p x if the verbosity level is at least SPxOut::ERROR.
123 #define MSG_ERROR(x) { DO_WITH_ERR_VERBOSITY( x ) }
124 /// Prints out message \p x if the verbosity level is at least SPxOut::WARNING.
125 #define MSG_WARNING(spxout, x) { DO_WITH_TMP_VERBOSITY( SPxOut::WARNING, spxout, x ) }
126 /// Prints out message \p x if the verbosity level is at least SPxOut::INFO1.
127 #define MSG_INFO1(spxout, x) { DO_WITH_TMP_VERBOSITY( SPxOut::INFO1, spxout, x ) }
128 /// Prints out message \p x if the verbosity level is at least SPxOut::INFO2.
129 #define MSG_INFO2(spxout, x) { DO_WITH_TMP_VERBOSITY( SPxOut::INFO2, spxout, x ) }
130 /// Prints out message \p x if the verbosity level is at least SPxOut::INFO3.
131 #define MSG_INFO3(spxout, x) { DO_WITH_TMP_VERBOSITY( SPxOut::INFO3, spxout, x ) }
132 
133 extern bool msginconsistent(const char* name, const char* file, int line);
134 
135 #define MSGinconsistent(name) msginconsistent(name, __FILE__, __LINE__)
136 
137 #if defined(SOPLEX_DEBUG)
138 // print output in any case, regardless of Param::verbose():
139 #define MSG_DEBUG(x) { x; }
140 #else
141 #define MSG_DEBUG(x) /**/
142 #endif //!SOPLEX_DEBUG
143 
144 
145 /*-----------------------------------------------------------------------------
146  * multi-thread support
147  *-----------------------------------------------------------------------------
148  */
149 // enable the user to compile without thread_local by setting USRCXXFLAGS=-DTHREADLOCAL=""
150 #if !defined(THREADLOCAL)
151 #if defined(_MSC_VER) && _MSC_VER < 1900
152 #define THREADLOCAL
153 #else
154 #define THREADLOCAL thread_local
155 #endif
156 #endif
157 
158 /*-----------------------------------------------------------------------------
159  * Long double support, Parameters and Epsilons
160  *-----------------------------------------------------------------------------
161  */
162 
163 
164 #ifdef WITH_LONG_DOUBLE
165 
166 
167 typedef long double Real;
168 
169 #ifndef REAL
170 #define REAL(x) x##L
171 #define REAL_FORMAT "Lf"
172 #endif
173 /// default allowed bound violation
174 #ifndef DEFAULT_BND_VIOL
175 #define DEFAULT_BND_VIOL 1e-12L
176 #endif
177 /// default allowed additive zero: 1.0 + EPS_ZERO == 1.0
178 #ifndef DEFAULT_EPS_ZERO
179 #define DEFAULT_EPS_ZERO 1e-28L
180 #endif
181 /// epsilon for factorization
182 #ifndef DEFAULT_EPS_FACTOR
183 #define DEFAULT_EPS_FACTOR 1e-30L
184 #endif
185 /// epsilon for factorization update
186 #ifndef DEFAULT_EPS_UPDATE
187 #define DEFAULT_EPS_UPDATE 1e-26L
188 #endif
189 #ifndef DEFAULT_EPS_PIVOT
190 #define DEFAULT_EPS_PIVOT 1e-20L
191 #endif
192 ///
193 #define DEFAULT_INFINITY 1e100L
194 
195 
196 #else
197 
198 #ifdef WITH_FLOAT
199 
200 typedef float Real;
201 
202 #ifndef REAL
203 #define REAL(x) x
204 #define REAL_FORMAT "f"
205 #endif
206 /// default allowed bound violation
207 #ifndef DEFAULT_BND_VIOL
208 #define DEFAULT_BND_VIOL 1e-1f
209 #endif
210 /// default allowed additive zero: 1.0 + EPS_ZERO == 1.0
211 #ifndef DEFAULT_EPS_ZERO
212 #define DEFAULT_EPS_ZERO 1e-7f
213 #endif
214 #ifndef DEFAULT_EPS_FACTOR
215 #define DEFAULT_EPS_FACTOR 1e-7f
216 #endif
217 #ifndef DEFAULT_EPS_UPDATE
218 #define DEFAULT_EPS_UPDATE 1e-6f
219 #endif
220 #ifndef DEFAULT_EPS_PIVOT
221 #define DEFAULT_EPS_PIVOT 1e-6f
222 #endif
223 #define DEFAULT_INFINITY 1e35f
224 
225 #else
226 
227 typedef double Real;
228 
229 #ifndef REAL
230 #define REAL(x) x
231 #define REAL_FORMAT "lf"
232 #endif
233 /// default allowed bound violation
234 #ifndef DEFAULT_BND_VIOL
235 #define DEFAULT_BND_VIOL 1e-6
236 #endif
237 /// default allowed additive zero: 1.0 + EPS_ZERO == 1.0
238 #ifndef DEFAULT_EPS_ZERO
239 #define DEFAULT_EPS_ZERO 1e-16
240 #endif
241 #ifndef DEFAULT_EPS_FACTOR
242 #define DEFAULT_EPS_FACTOR 1e-20
243 #endif
244 #ifndef DEFAULT_EPS_UPDATE
245 #define DEFAULT_EPS_UPDATE 1e-16
246 #endif
247 #ifndef DEFAULT_EPS_PIVOT
248 #define DEFAULT_EPS_PIVOT 1e-10
249 #endif
250 #define DEFAULT_INFINITY 1e100
251 
252 #endif // !WITH_FLOAT
253 #endif // !WITH_LONG_DOUBLE
254 
255 #define MAXIMUM(x,y) ((x)>(y) ? (x) : (y))
256 #define MINIMUM(x,y) ((x)<(y) ? (x) : (y))
257 
258 #define SPX_MAXSTRLEN 1024 /**< maximum string length in SoPlex */
259 
260 THREADLOCAL extern const Real infinity;
261 
262 class Param
263 {
264 private:
265 
266  //------------------------------------
267  /**@name Data */
268  ///@{
269  /// default allowed additive zero: 1.0 + EPS_ZERO == 1.0
270  THREADLOCAL static Real s_epsilon;
271  /// epsilon for factorization
273  /// epsilon for factorization update
275  /// epsilon for pivot zero tolerance in factorization
277  ///@}
278 
279 public:
280 
281  //------------------------------------
282  /**@name Access / modification */
283  ///@{
284  ///
285  static Real epsilon();
286  ///
287  static void setEpsilon(Real eps);
288  ///
289  static Real epsilonFactorization();
290  ///
291  static void setEpsilonFactorization(Real eps);
292  ///
293  static Real epsilonUpdate();
294  ///
295  static void setEpsilonUpdate(Real eps);
296  ///
297  static Real epsilonPivot();
298  ///
299  static void setEpsilonPivot(Real eps);
300  ///@}
301 };
302 
303 // A generic version of spxAbs. It would be nice if we could replace spxAbs
304 // with std::abs. Currently there are different versions of spxAbs under
305 // compile time #if. It's better to make this an overloaded function. Even
306 // better, replace it by std::abs since types from boost/multiprecision would
307 // need no extra modification.
308 template <class R>
309 R spxAbs(R a)
310 {
311  return abs(a);
312 }
313 
314 // cmath means proper long double function gets called, e.g. for fabs -> fabsl.
315 // Documentation unclear for nextafterl, so the ifdef remains for that case.
316 #ifdef WITH_LONG_DOUBLE
317 // returns the next representable value after x in the direction of y
318 inline Real spxNextafter(Real x, Real y)
319 {
320  return nextafterl(x, y);
321 }
322 #else
323 // returns the next representable value after x in the direction of y
324 inline Real spxNextafter(Real x, Real y)
325 {
326 #ifndef _MSC_VER
327  return nextafter(x, y);
328 #else
329  return _nextafter(x, y);
330 #endif
331 }
332 #endif
333 
334 /// returns |a|
335 template <>
336 inline Real spxAbs(Real a)
337 {
338  return fabs(a);
339 }
340 
341 /// returns square root
342 inline Real spxSqrt(Real a)
343 {
344  return std::sqrt(a);
345 }
346 
347 /// returns max(|a|,|b|)
348 inline Real maxAbs(Real a, Real b)
349 {
350  const Real absa = spxAbs(a);
351  const Real absb = spxAbs(b);
352 
353  return absa > absb ? absa : absb;
354 }
355 
356 /// returns (a-b) / max(|a|,|b|,1.0)
357 inline Real relDiff(Real a, Real b)
358 {
359  return (a - b) / (maxAbs(a, b) > 1.0 ? maxAbs(a, b) : 1.0);
360 }
361 
362 /// safe version of snprintf
363 inline int spxSnprintf(
364  char* t, /**< target string */
365  size_t len, /**< length of the string to copy */
366  const char* s, /**< source string */
367  ... /**< further parameters */
368 )
369 {
370  va_list ap;
371  int n;
372 
373  assert(t != NULL);
374  assert(len > 0);
375 
376  va_start(ap, s); /*lint !e826*/
377 
378 #if defined(_WIN32) || defined(_WIN64)
379  n = _vsnprintf(t, len, s, ap);
380 #else
381  n = vsnprintf(t, len, s, ap); /*lint !e571*/
382 #endif
383  va_end(ap);
384 
385  if(n < 0 || (size_t) n >= len)
386  {
387 #ifndef NDEBUG
388 
389  if(n < 0)
390  {
391  MSG_ERROR(std::cerr << "vsnprintf returned " << n << " while reading: " << s << std::endl;)
392  }
393 
394 #endif
395  t[len - 1] = '\0';
396  n = (int) len - 1;
397  }
398 
399  return n;
400 }
401 
402 #ifdef SOPLEX_WITH_BOOST
403 // wrapped frexp function
404 template <typename T, boost::multiprecision::expression_template_option eto>
405 boost::multiprecision::number<T, eto> spxFrexp(boost::multiprecision::number<T, eto> y, int* exp)
406 {
407  using namespace std;
408  using namespace boost::math::tools;
409 
410  return frexp(y, exp);
411 }
412 
413 // Overloaded spxLdexp
414 template <typename T, boost::multiprecision::expression_template_option eto>
415 boost::multiprecision::number<T> spxLdexp(boost::multiprecision::number<T, eto> x, int exp)
416 {
417  return boost::multiprecision::ldexp(x, exp);
418 }
419 
420 // Overloaded function to return the square-root
421 template <typename T, boost::multiprecision::expression_template_option ep>
422 boost::multiprecision::number<T, ep> spxSqrt(boost::multiprecision::number<T, ep> a)
423 {
424  return boost::multiprecision::sqrt(a);
425 }
426 
427 // the nextafter function
428 template <typename T, boost::multiprecision::expression_template_option eto>
429 boost::multiprecision::number<T, eto> spxNextafter(boost::multiprecision::number<T, eto> x,
430  boost::multiprecision::number<T, eto> y)
431 {
432  using namespace std;
433  using namespace boost::math;
434 
435  // Turns out that nextafter is not supported in the mpfr library? The mpfr
436  // library does a different function named nextabove. Probably a
437  // replacement? I've made an issue about this.
438  // return nextafter(x,y);
439 
440  // @todo Temporarily, I'm returning 0
441  assert(false);
442  return 0;
443 }
444 
445 // Returns the square root
446 template <typename T>
447 boost::multiprecision::number<T> spxSqrt(boost::multiprecision::number<T> a)
448 {
449  return boost::multiprecision::sqrt(a);
450 }
451 
452 /// returns max(|a|,|b|)
453 template <typename T, boost::multiprecision::expression_template_option et>
454 inline boost::multiprecision::number<T, et> maxAbs(
455  boost::multiprecision::number<T, et> a, boost::multiprecision::number<T, et> b)
456 {
457  const auto absa = spxAbs(a);
458  const auto absb = spxAbs(b);
459 
460  return absa > absb ? absa : absb;
461 }
462 
463 template <typename T, boost::multiprecision::expression_template_option et>
464 inline boost::multiprecision::number<T, et> relDiff(boost::multiprecision::number<T, et> a,
465  boost::multiprecision::number<T, et> b)
466 {
467  return (a - b) / (maxAbs(a, b) > 1.0 ? maxAbs(a, b) : 1.0);
468 }
469 #endif
470 
471 } // namespace soplex
472 
473 // For the templated functions
474 #include "spxdefines.hpp"
475 
476 #endif // _SPXDEFINES_H_
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:2934
static void setEpsilon(Real eps)
Definition: spxdefines.cpp:60
bool EQ(int a, int b)
Definition: spxdefines.cpp:27
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:32
Real maxAbs(Real a, Real b)
returns max(|a|,|b|)
Definition: spxdefines.h:348
bool msginconsistent(const char *name, const char *file, int line)
Definition: spxdefines.cpp:42
Rational spxLdexp(Rational x, int exp)
Definition: rational.h:1125
double Real
Definition: spxdefines.h:227
static void setEpsilonPivot(Real eps)
Definition: spxdefines.cpp:92
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:123
int spxSnprintf(char *t, size_t len, const char *s,...)
safe version of snprintf
Definition: spxdefines.h:363
static THREADLOCAL Real s_epsilon_pivot
epsilon for pivot zero tolerance in factorization
Definition: spxdefines.h:276
static Real epsilonUpdate()
Definition: spxdefines.cpp:77
Real spxSqrt(Real a)
returns square root
Definition: spxdefines.h:342
static Real epsilon()
Definition: spxdefines.cpp:55
static THREADLOCAL Real s_epsilon
default allowed additive zero: 1.0 + EPS_ZERO == 1.0
Definition: spxdefines.h:270
Rational spxFrexp(Rational r, int *d)
Definition: rational.h:1118
Everything should be within this namespace.
Real relDiff(Real a, Real b)
returns (a-b) / max(|a|,|b|,1.0)
Definition: spxdefines.h:357
Real spxNextafter(Real x, Real y)
Definition: spxdefines.h:324
static void setEpsilonUpdate(Real eps)
Definition: spxdefines.cpp:82
static THREADLOCAL Real s_epsilon_update
epsilon for factorization update
Definition: spxdefines.h:274
static Real epsilonPivot()
Definition: spxdefines.cpp:87
static void setEpsilonFactorization(Real eps)
Definition: spxdefines.cpp:71
static Real epsilonFactorization()
Definition: spxdefines.cpp:66
static THREADLOCAL Real s_epsilon_factorization
epsilon for factorization
Definition: spxdefines.h:272
#define THREADLOCAL
SOPLEX_DEBUG.
Definition: spxdefines.h:154