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