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