Scippy

SoPlex

Sequential object-oriented simPlex

rational.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 rational.h
17  * @brief Wrapper for GMP types.
18  */
19 #ifndef _RATIONAL_H_
20 #define _RATIONAL_H_
21 
22 #include <math.h>
23 #include <assert.h>
24 #include <string.h>
25 #include <iostream>
26 
27 #include "soplex/spxdefines.h"
28 #include "soplex/idlist.h"
29 
30 
31 #include "soplex/spxalloc.h"
32 #ifdef SOPLEX_WITH_BOOST
33 #include "boost/multiprecision/number.hpp"
34 
35 #ifdef SOPLEX_WITH_MPFR
36 #include "boost/multiprecision/mpfr.hpp"
37 #endif
38 
39 #ifdef SOPLEX_WITH_CPPMPF
40 #include "boost/multiprecision/cpp_dec_float.hpp"
41 #include "boost/multiprecision/cpp_int.hpp"
42 #endif
43 #endif
44 
45 #ifdef SOPLEX_WITH_GMP
46 #include "gmp.h"
47 #ifdef SOPLEX_WITH_BOOST
48 #include "boost/multiprecision/gmp.hpp"
49 #endif
50 #endif
51 
52 
53 namespace soplex
54 {
55 /**@brief Wrapper for GMP type mpq_class.
56  * @ingroup Algebra
57  *
58  * We wrap mpq_class so that we can replace it by a double type if GMP is not available.
59  */
60 
61 /// If compiled with GMP support, Rational is defined as mpq_class.
62 class Rational // coverity[missing_move_assignment]
63 {
64 private:
65  class Private;
67 
68 #ifdef SOPLEX_WITH_GMP
70  THREADLOCAL static bool useListMem;
71 
72 
73  /// special constructor only for initializing static rational variables; this is necessary since we need a
74  /// constructor for Rational::{ZERO, POSONE, NEGONE} that does not use these numbers
75  Rational(const int& i, const bool& dummy);
76 
77  ///@name Static variables for special rational values
78  ///@{
79 
80  static const Rational ZERO;
81  static const Rational POSONE;
82  static const Rational NEGONE;
83 
84  ///@}
85 #endif
86 
87 public:
88 
89  ///@name Construction and destruction
90  ///@{
91 
92  /// default constructor
93  Rational();
94 
95  /// copy constructor
96  Rational(const Rational& r);
97 
98  /// constructor from long double
99  Rational(const long double& r);
100 
101  /// constructor from double
102  Rational(const double& r);
103 
104  ///constructor from int
105  Rational(const int& i);
106 
107 #ifdef SOPLEX_WITH_GMP
108  /// constructor from mpq_t (GMP only)
109  Rational(const mpq_t& q);
110 #endif
111 
112 #ifdef SOPLEX_WITH_BOOST
113  // constructor from boost number
114  template <typename T, boost::multiprecision::expression_template_option eto>
115  Rational(const boost::multiprecision::number<T, eto>& q);
116 #endif
117 
118  /// destructor
119  ~Rational();
120 
121  /// enables list memory
122  static void enableListMem();
123 
124  /// frees the unused rational elements in the memory list
125  /** this can be useful when you want to save memory or needed when working with a GMP memory manager like the one
126  * in EGlib that frees GMP memory before the destructor of the static memory list is called; in most cases this
127  * method is optional; note that this does not free the Rational elements that are currently in use
128  */
129  static void freeListMem();
130 
131  /// disables list memory
132  static void disableListMem();
133 
134  /// assignment operator
135  Rational& operator=(const Rational&);
136 
137  /// assignment operator from long double
138  Rational& operator=(const long double& r);
139 
140  /// assignment operator from double
141  Rational& operator=(const double& r);
142 
143  /// assignment operator from int
144  Rational& operator=(const int& i);
145  ///@}
146 
147 #ifdef SOPLEX_WITH_GMP
148  /// @name GMP Only methods
149  ///
150  /// Methods of the Rational class that are only available if SoPlex is compiled with "-DGMP=on"
151  ///
152  ///@{
153 
154  /// assignment operator from mpq_t
155  Rational& operator=(const mpq_t& q);
156 #endif
157 
158 #ifdef SOPLEX_WITH_BOOST
159  // assignment operator from boost multiprecision number The operator should
160  // convert the boost number to mpq_t
161 
162  // Note: the function is only implemented in the #if part
163  template <typename T, boost::multiprecision::expression_template_option eto>
164  Rational& operator=(const boost::multiprecision::number<T, eto>& q);
165  ///@}
166 #endif
167 
168  ///@name Typecasts
169  ///@{
170 
171  operator double() const;
172  operator long double() const;
173  operator float() const;
174 #ifdef SOPLEX_WITH_BOOST
175 #ifndef SOPLEX_WITH_CPPMPF
176  // Operator to typecast Rational to one of the Boost Number types
177  template <typename T, boost::multiprecision::expression_template_option eto>
178  operator boost::multiprecision::number<T, eto>() const;
179 #else
180  // Operator to typecast Rational to one of the Boost Number types
181  template <unsigned bits, boost::multiprecision::expression_template_option eto>
182  operator boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<bits>, eto>()
183  const;
184 #endif
185 #endif
186 
187 #ifdef SOPLEX_WITH_GMP
188  /// provides read-only access to underlying mpq_t
189  const mpq_t* getMpqPtr() const;
190 
191  /// provides read-only access to underlying mpq_t
192  const mpq_t& getMpqRef() const;
193 
194  /// provides write access to underlying mpq_t; use with care
195  mpq_t* getMpqPtr_w() const;
196 
197  /// provides write access to underlying mpq_t; use with care
198  mpq_t& getMpqRef_w() const;
199  ///@} // end of RationalWithGMP
200 #endif
201 
202  ///@name Typecasts
203  ///@{
204 
205  ///@}
206 
207 
208  ///@name Arithmetic operators
209  ///@{
210 
211  /// addition operator
212  Rational operator+(const Rational& r) const;
213 
214  /// addition assignment operator
215  Rational& operator+=(const Rational& r);
216 
217  /// addition operator for doubles
218  Rational operator+(const double& r) const;
219 
220  /// addition assignment operator for doubles
221  Rational& operator+=(const double& r);
222 
223  /// addition operator for ints
224  Rational operator+(const int& r) const;
225 
226  /// addition assignment operator for ints
227  Rational& operator+=(const int& r);
228 
229  /// subtraction operator
230  Rational operator-(const Rational& r) const;
231 
232  /// subtraction assignment operator
233  Rational& operator-=(const Rational& r);
234 
235  /// subtraction operator for doubles
236  Rational operator-(const double& r) const;
237 
238  /// subtraction assignment operator for doubles
239  Rational& operator-=(const double& r);
240 
241  /// subtraction operator for ints
242  Rational operator-(const int& r) const;
243 
244  /// subtraction assignment operator for ints
245  Rational& operator-=(const int& r);
246 
247  /// multiplication operator
248  Rational operator*(const Rational& r) const;
249 
250  /// multiplication assignment operator operator
251  Rational& operator*=(const Rational& r);
252 
253  /// multiplication operator for doubles
254  Rational operator*(const double& r) const;
255 
256  /// multiplication assignment operator for doubles
257  Rational& operator*=(const double& r);
258 
259  /// multiplication operator for ints
260  Rational operator*(const int& r) const;
261 
262  /// multiplication assignment operator for ints
263  Rational& operator*=(const int& r);
264 
265  /// division operator
266  Rational operator/(const Rational& r) const;
267 
268  /// division assignment operator
269  Rational& operator/=(const Rational& r);
270 
271  /// division operator for doubles
272  Rational operator/(const double& r) const;
273 
274  /// division assignment operator for doubles
275  Rational& operator/=(const double& r);
276 
277  /// division operator for ints
278  Rational operator/(const int& r) const;
279 
280  /// division assignment operator for ints
281  Rational& operator/=(const int& r);
282 
283  /// add product of two rationals
284  Rational& addProduct(const Rational& r, const Rational& s);
285 
286  /// subtract product of two rationals
287  Rational& subProduct(const Rational& r, const Rational& s);
288 
289  /// add quotient of two rationals, r divided by s
290  Rational& addQuotient(const Rational& r, const Rational& s);
291 
292  /// subtract quotient of two rationals, r divided by s
293  Rational& subQuotient(const Rational& r, const Rational& s);
294 
295  /// inversion
296  Rational& invert();
297 
298  /// round up to next power of two
299  Rational& powRound();
300 
301  ///@}
302 
303 
304  ///@name Methods for checking exactness of doubles
305  ///@{
306 
307  /// checks if \p d is the closest number that can be represented by double
308  bool isNextTo(const double& d);
309 
310  /// checks if \p d is exactly equal to the Rational and if not, if it is one of the two adjacent doubles
311  bool isAdjacentTo(const double& d) const;
312 
313  ///@}
314 
315 
316  ///@name Methods for querying size
317  ///@{
318 
319  /// Size in specified base (bit size for base 2)
320  int sizeInBase(const int base = 2) const;
321 
322  ///@}
323 
324 
325  ///@name Static methods
326  ///@{
327 
328  /// returns precision of Rational implementation, i.e., number of bits used to store Rational numbers (INT_MAX if exact)
329  static int precision();
330 
331  ///@}
332 
333 
334  ///@name Conversion from and to String
335  ///@{
336 
337  /// read Rational from string
338  bool readString(const char* s);
339 
340  friend std::string rationalToString(const Rational& r, const int precision);
341  friend bool readStringRational(const char* s, Rational& value);
342  friend std::ostream& operator<<(std::ostream& os, const Rational& q);
343 
344  ///@}
345 
346  ///@name Friends
347  ///@{
348 
349  friend int compareRational(const Rational& r, const Rational& s);
350  friend bool operator!=(const Rational& r, const Rational& s);
351  friend bool operator==(const Rational& r, const Rational& s);
352  friend bool operator<(const Rational& r, const Rational& s);
353  friend bool operator<=(const Rational& r, const Rational& s);
354  friend bool operator>(const Rational& r, const Rational& s);
355  friend bool operator>=(const Rational& r, const Rational& s);
356 
357  friend bool operator!=(const Rational& r, const double& s);
358  friend bool operator==(const Rational& r, const double& s);
359  friend bool operator<(const Rational& r, const double& s);
360  friend bool operator<=(const Rational& r, const double& s);
361  friend bool operator>(const Rational& r, const double& s);
362  friend bool operator>=(const Rational& r, const double& s);
363 
364  friend bool operator!=(const double& r, const Rational& s);
365  friend bool operator==(const double& r, const Rational& s);
366  friend bool operator<(const double& r, const Rational& s);
367  friend bool operator<=(const double& r, const Rational& s);
368  friend bool operator>(const double& r, const Rational& s);
369  friend bool operator>=(const double& r, const Rational& s);
370 
371  friend bool operator!=(const Rational& r, const long double& s);
372  friend bool operator==(const Rational& r, const long double& s);
373  friend bool operator<(const Rational& r, const long double& s);
374  friend bool operator<=(const Rational& r, const long double& s);
375  friend bool operator>(const Rational& r, const long double& s);
376  friend bool operator>=(const Rational& r, const long double& s);
377 
378  friend bool operator!=(const long double& r, const Rational& s);
379  friend bool operator==(const long double& r, const Rational& s);
380  friend bool operator<(const long double& r, const Rational& s);
381  friend bool operator<=(const long double& r, const Rational& s);
382  friend bool operator>(const long double& r, const Rational& s);
383  friend bool operator>=(const long double& r, const Rational& s);
384 
385  friend bool operator!=(const Rational& r, const float& s);
386  friend bool operator==(const Rational& r, const float& s);
387  friend bool operator<(const Rational& r, const float& s);
388  friend bool operator<=(const Rational& r, const float& s);
389  friend bool operator>(const Rational& r, const float& s);
390  friend bool operator>=(const Rational& r, const float& s);
391 
392  friend bool operator!=(const float& r, const Rational& s);
393  friend bool operator==(const float& r, const Rational& s);
394  friend bool operator<(const float& r, const Rational& s);
395  friend bool operator<=(const float& r, const Rational& s);
396  friend bool operator>(const float& r, const Rational& s);
397  friend bool operator>=(const float& r, const Rational& s);
398 
399 
400  friend Rational operator+(const double& d, const Rational& r);
401  friend Rational operator-(const double& d, const Rational& r);
402  friend Rational operator*(const double& d, const Rational& r);
403  friend Rational operator/(const double& d, const Rational& r);
404 
405  friend bool operator!=(const Rational& r, const int& s);
406  friend bool operator==(const Rational& r, const int& s);
407  friend bool operator<(const Rational& r, const int& s);
408  friend bool operator<=(const Rational& r, const int& s);
409  friend bool operator>(const Rational& r, const int& s);
410  friend bool operator>=(const Rational& r, const int& s);
411 
412  friend bool operator!=(const int& r, const Rational& s);
413  friend bool operator==(const int& r, const Rational& s);
414  friend bool operator<(const int& r, const Rational& s);
415  friend bool operator<=(const int& r, const Rational& s);
416  friend bool operator>(const int& r, const Rational& s);
417  friend bool operator>=(const int& r, const Rational& s);
418 
419  friend Rational operator+(const int& d, const Rational& r);
420  friend Rational operator-(const int& d, const Rational& r);
421  friend Rational operator*(const int& d, const Rational& r);
422  friend Rational operator/(const int& d, const Rational& r);
423 
424  friend Rational spxAbs(const Rational& r);
425  friend int sign(const Rational& r);
426  friend Rational operator-(const Rational& q);
427 
428  ///@}
429 };
430 
431 /// less than operator
432 bool operator<(const Rational& r, const Rational& s);
433 
434 ///@name Parsing and printing
435 ///@{
436 
437 /// convert rational number to string
438 std::string rationalToString(const Rational& r, const int precision = 32);
439 
440 /// read Rational from string
441 bool readStringRational(const char* s, Rational& value);
442 
443 /// print Rational
444 std::ostream& operator<<(std::ostream& os, const Rational& r);
445 
446 ///@}
447 
448 /// less than operator for Rational and double
449 bool operator<(const Rational& r, const double& s);
450 
451 ///@name Relational operators
452 ///@{
453 
454 /// comparison operator returning a positive value if r > s, zero if r = s, and a negative value if r < s
455 int compareRational(const Rational& r, const Rational& s);
456 
457 /// equality operator
458 bool operator==(const Rational& r, const Rational& s);
459 
460 /// inequality operator
461 bool operator!=(const Rational& r, const Rational& s);
462 
463 /// less than operator
464 bool operator<(const Rational& r, const Rational& s);
465 
466 /// less than or equal to operator
467 bool operator<=(const Rational& r, const Rational& s);
468 
469 /// greater than operator
470 bool operator>(const Rational& r, const Rational& s);
471 
472 /// greater than or equal to operator
473 bool operator>=(const Rational& r, const Rational& s);
474 
475 /// equality operator for Rational and double
476 bool operator==(const Rational& r, const double& s);
477 
478 /// inequality operator for Rational and double
479 bool operator!=(const Rational& r, const double& s);
480 
481 /// less than operator for Rational and double
482 bool operator<(const Rational& r, const double& s);
483 
484 /// less than or equal to operator for Rational and double
485 bool operator<=(const Rational& r, const double& s);
486 
487 /// greater than operator for Rational and double
488 bool operator>(const Rational& r, const double& s);
489 
490 /// greater than or equal to operator for Rational and double
491 bool operator>=(const Rational& r, const double& s);
492 
493 /// equality operator for double and Rational
494 bool operator==(const double& r, const Rational& s);
495 
496 /// inequality operator for double and Rational
497 bool operator!=(const double& r, const Rational& s);
498 
499 /// less than operator for double and Rational
500 bool operator<(const double& r, const Rational& s);
501 
502 /// less than or equal to operator for double and Rational
503 bool operator<=(const double& r, const Rational& s);
504 
505 /// greater than operator for double and Rational
506 bool operator>(const double& r, const Rational& s);
507 
508 /// greater than or equal to operator for double and Rational
509 bool operator>=(const double& r, const Rational& s);
510 
511 /// equality operator for Rational and long double
512 bool operator==(const Rational& r, const long double& s);
513 
514 /// inequality operator for Rational and long double
515 bool operator!=(const Rational& r, const long double& s);
516 
517 /// less than operator for Rational and long double
518 bool operator<(const Rational& r, const long double& s);
519 
520 /// less than or equal to operator for Rational and long double
521 bool operator<=(const Rational& r, const long double& s);
522 
523 /// greater than operator for Rational and long double
524 bool operator>(const Rational& r, const long double& s);
525 
526 /// greater than or equal to operator for Rational and long double
527 bool operator>=(const Rational& r, const long double& s);
528 
529 /// equality operator for long double and Rational
530 bool operator==(const long double& r, const Rational& s);
531 
532 /// inequality operator for long double and Rational
533 bool operator!=(const long double& r, const Rational& s);
534 
535 /// less than operator for long double and Rational
536 bool operator<(const long double& r, const Rational& s);
537 
538 /// less than or equal to operator for long double and Rational
539 bool operator<=(const long double& r, const Rational& s);
540 
541 /// greater than operator for long double and Rational
542 bool operator>(const long double& r, const Rational& s);
543 
544 /// greater than or equal to operator for long double and Rational
545 bool operator>=(const long double& r, const Rational& s);
546 
547 /// equality operator for Rational and int
548 bool operator==(const Rational& r, const int& s);
549 
550 /// inequality operator for Rational and int
551 bool operator!=(const Rational& r, const int& s);
552 
553 /// less than operator for Rational and int
554 bool operator<(const Rational& r, const int& s);
555 
556 /// less than or equal to operator for Rational and int
557 bool operator<=(const Rational& r, const int& s);
558 
559 /// greater than operator for Rational and int
560 bool operator>(const Rational& r, const int& s);
561 
562 /// greater than or equal to operator for Rational and int
563 bool operator>=(const Rational& r, const int& s);
564 
565 /// equality operator for int and Rational
566 bool operator==(const int& r, const Rational& s);
567 
568 /// inequality operator for int and Rational
569 bool operator!=(const int& r, const Rational& s);
570 
571 /// less than operator for int and Rational
572 bool operator<(const int& r, const Rational& s);
573 
574 /// less than or equal to operator for int and Rational
575 bool operator<=(const int& r, const Rational& s);
576 
577 /// greater than operator for int and Rational
578 bool operator>(const int& r, const Rational& s);
579 
580 /// greater than or equal to operator for int and Rational
581 bool operator>=(const int& r, const Rational& s);
582 
583 ///@}
584 
585 /// Sign function; returns 1 if r > 0, 0 if r = 0, and -1 if r < 0.
586 int sign(const Rational& r);
587 
588 ///@name Non-member arithmetic operators and functions
589 ///@{
590 
591 /// addition operator for double and Rational
592 Rational operator+(const double& d, const Rational& r);
593 
594 /// addition operator for double and Rational
595 Rational operator+(const double& d, const Rational& r);
596 
597 /// addition operator for double and Rational
598 Rational operator+(const double& d, const Rational& r);
599 
600 /// addition operator for double and Rational
601 Rational operator+(const double& d, const Rational& r);
602 
603 /// addition operator for int and Rational
604 Rational operator+(const int& d, const Rational& r);
605 
606 /// addition operator for int and Rational
607 Rational operator+(const int& d, const Rational& r);
608 
609 /// addition operator for int and Rational
610 Rational operator+(const int& d, const Rational& r);
611 
612 /// addition operator for int and Rational
613 Rational operator+(const int& d, const Rational& r);
614 
615 /// absolute function
616 Rational spxAbs(const Rational& r);
617 
618 /// Sign function; returns 1 if r > 0, 0 if r = 0, and -1 if r < 0.
619 int sign(const Rational& r);
620 
621 /// Negation.
622 Rational operator-(const Rational& r);
623 
624 /// Total size of rational vector.
625 int totalSizeRational(const Rational* vector, const int length, const int base = 2);
626 
627 /// Size of least common multiple of denominators in rational vector.
628 int dlcmSizeRational(const Rational* vector, const int length, const int base = 2);
629 
630 /// Size of largest denominator in rational vector.
631 int dmaxSizeRational(const Rational* vector, const int length, const int base = 2);
632 
633 #ifdef SOPLEX_WITH_GMP
634 /// Defines the "Pimpl"-class Private
636 {
637 public:
638 
639  mpq_t privatevalue; ///< actual value of the Rational object
640  Private* theprev; ///< pointer to the previous element in the list
641  Private* thenext; ///< pointer to the next element in the list
642 
643  /// default constructor
645  : theprev(0)
646  , thenext(0)
647  {
648  mpq_init(privatevalue);
649  }
650 
651  /// copy constructor
652  Private(const Private& p)
653  : theprev(0)
654  , thenext(0)
655  {
656  // a newly constructed element is not in any list, even if the original element (p) is; hence we initialize
657  // theprev and thenext to zero
658  mpq_init(privatevalue);
659  mpq_set(this->privatevalue, p.privatevalue);
660  }
661 
662  /// constructor from long double
663  Private(const long double& r)
664  : theprev(0)
665  , thenext(0)
666  {
667  mpq_init(privatevalue);
668 
669  if(r == (long double)(1.0))
670  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
671  else if(r == (long double)(-1.0))
672  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
673  else if(r == (long double)(0.0))
674  {
675  assert(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
676  }
677  else
678  mpq_set_d(privatevalue, double(r));
679  }
680 
681  /// constructor from double
682  Private(const double& r)
683  : theprev(0)
684  , thenext(0)
685  {
686  mpq_init(privatevalue);
687 
688  if(r == 1.0)
689  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
690  else if(r == -1.0)
691  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
692  else if(r == 0.0)
693  {
694  assert(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
695  }
696  else
697  mpq_set_d(privatevalue, r);
698  }
699 
700  /// constructor from int
701  Private(const int& i)
702  : theprev(0)
703  , thenext(0)
704  {
705  mpq_init(privatevalue);
706 
707  if(i == 1)
708  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
709  else if(i == -1)
710  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
711  else if(i == 0)
712  {
713  assert(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
714  }
715  else
716  mpq_set_si(privatevalue, i, 1);
717  }
718 
719  /// constructor from mpq_t (GMP only)
720  Private(const mpq_t& q)
721  : theprev(0)
722  , thenext(0)
723  {
724  mpq_init(privatevalue);
725  mpq_set(privatevalue, q);
726  }
727 
728  /// constructor from boost number
729  // Also should satisfy SOPLEX_WITH_GMP
730 #ifdef SOPLEX_WITH_BOOST
731 #ifdef SOPLEX_WITH_GMP
732  template <typename T, boost::multiprecision::expression_template_option eto>
733  Private(const boost::multiprecision::number<T, eto>& q)
734  : theprev(0)
735  , thenext(0)
736  {
737  boost::multiprecision::mpq_rational tmp{q};
738  mpq_init(privatevalue);
739  mpq_set(privatevalue, tmp.backend().data());
740  }
741 #endif
742 #endif
743 
744  /// destructor
746  {
747  mpq_clear(privatevalue);
748  }
749 
750  /// assignment operator
752  {
753 #ifdef SOPLEX_PERFALT_4
754 
755  if(mpq_equal(this->privatevalue, p.privatevalue) != 0)
756  return *this;
757 
758 #endif
759 
760  // we only assign the value; the position in the list, i.e., theprev and thenext, must not be modified
761  mpq_set(this->privatevalue, p.privatevalue);
762  return *this;
763  }
764 
765  /// assignment operator from long double
766  Private& operator=(const long double& r)
767  {
768  // we only assign the value; the position in the list, i.e., theprev and thenext, must not be modified
769  if(r == (long double)(0.0))
770  {
771 #ifdef SOPLEX_PERFALT_5a
772 #ifdef SOPLEX_PERFALT_1
773 
774  if(mpq_sgn(privatevalue) != 0)
775 #else
776  if(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) == 0)
777 #endif
778 #endif
779  mpq_set(privatevalue, Rational::ZERO.dpointer->privatevalue);
780  }
781  else if(r == (long double)(1.0))
782  {
783 #ifdef SOPLEX_PERFALT_5b
784 
785  if(mpq_equal(privatevalue, Rational::POSONE.dpointer->privatevalue) == 0)
786 #endif
787  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
788  }
789  else if(r == (long double)(-1.0))
790  {
791 #ifdef SOPLEX_PERFALT_5b
792 
793  if(mpq_equal(privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0)
794 #endif
795  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
796  }
797  else
798  mpq_set_d(this->privatevalue, double(r));
799 
800  return *this;
801  }
802 
803  /// assignment operator from double
804  Private& operator=(const double& r)
805  {
806  // we only assign the value; the position in the list, i.e., theprev and thenext, must not be modified
807  if(r == 0.0)
808  {
809 #ifdef SOPLEX_PERFALT_5a
810 #ifdef SOPLEX_PERFALT_1
811 
812  if(mpq_sgn(privatevalue) != 0)
813 #else
814  if(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) == 0)
815 #endif
816 #endif
817  mpq_set(privatevalue, Rational::ZERO.dpointer->privatevalue);
818  }
819  else if(r == 1.0)
820  {
821 #ifdef SOPLEX_PERFALT_5b
822 
823  if(mpq_equal(privatevalue, Rational::POSONE.dpointer->privatevalue) == 0)
824 #endif
825  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
826  }
827  else if(r == -1.0)
828  {
829 #ifdef SOPLEX_PERFALT_5b
830 
831  if(mpq_equal(privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0)
832 #endif
833  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
834  }
835  else
836  mpq_set_d(privatevalue, r);
837 
838  return *this;
839  }
840 
841  /// assignment operator from int
842  Private& operator=(const int& i)
843  {
844  // we only assign the value; the position in the list, i.e., theprev and thenext, must not be modified
845  if(i == 0)
846  {
847 #ifdef SOPLEX_PERFALT_5a
848 #ifdef SOPLEX_PERFALT_1
849 
850  if(mpq_sgn(privatevalue) != 0)
851 #else
852  if(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) == 0)
853 #endif
854 #endif
855  mpq_set(privatevalue, Rational::ZERO.dpointer->privatevalue);
856  }
857  else if(i == 1)
858  {
859 #ifdef SOPLEX_PERFALT_5b
860 
861  if(mpq_equal(privatevalue, Rational::POSONE.dpointer->privatevalue) == 0)
862 #endif
863  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
864  }
865  else if(i == -1)
866  {
867 #ifdef SOPLEX_PERFALT_5b
868 
869  if(mpq_equal(privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0)
870 #endif
871  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
872  }
873  else
874  mpq_set_si(privatevalue, i, 1);
875 
876  return *this;
877  }
878 
879  /// assignment operator from mpq_t
880  Private& operator=(const mpq_t& q)
881  {
882 #ifdef SOPLEX_PERFALT_4
883 
884  if(mpq_equal(this->privatevalue, q) != 0)
885  return *this;
886 
887 #endif
888 
889  // we only assign the value; the position in the list, i.e., theprev and thenext, must not be modified
890  mpq_set(this->privatevalue, q);
891  return *this;
892  }
893 
894 #ifdef SOPLEX_WITH_BOOST
895  // The back end for Rational operator=.
896  template <typename T, boost::multiprecision::expression_template_option eto>
897  Private& operator=(const boost::multiprecision::number<T, eto>& q)
898  {
899  // mpq_rational is used as an intermediate to convert the mpf float to
900  // mpq_t.
901  boost::multiprecision::mpq_rational tmp{q};
902  mpq_set(this->privatevalue, tmp.backend().data());
903  return *this;
904  }
905 #endif
906 
907  /// previous Private element
909  {
910  return theprev;
911  }
912 
913  /// previous Private element
914  Private* const& prev() const
915  {
916  return theprev;
917  }
918 
919  /// next Private element
921  {
922  return thenext;
923  }
924 
925  /// next Private element
926  Private* const& next() const
927  {
928  return thenext;
929  }
930 };
931 #else // SOPLEX_WITH_GMP
932 
933 /// Defines the "Pimpl"-class Private
934 class Rational::Private
935 {
936 
937 public:
938 
939  /// value
940  long double privatevalue;
941 
942 #ifdef SOPLEX_WITH_BOOST
943  template <typename T, boost::multiprecision::expression_template_option eto>
944  Private(const boost::multiprecision::number<T, eto>& q)
945  {
946  privatevalue = (long double)q;
947  }
948 
949  template <typename T, boost::multiprecision::expression_template_option eto>
950  Private& operator=(const boost::multiprecision::number<T, eto>& q)
951  {
952  privatevalue = (long double)q;
953  return *this;
954  }
955 #endif
956 
957 
958  /// default constructor
959  Private()
960  {
961  privatevalue = 0;
962  }
963 
964  /// copy constructor
965  Private(const Private& p)
966  {
967  *this = p;
968  }
969 
970  /// constructor from long double
971  Private(const long double& r)
972  {
973  privatevalue = r;
974  }
975 
976  /// constructor from double
977  Private(const double& r)
978  {
979  privatevalue = r;
980  }
981 
982  /// constructor from int
983  Private(const int& i)
984  {
985  privatevalue = i;
986  }
987 
988  /// assignment operator
989  Private& operator=(const Private& p)
990  {
991  this->privatevalue = p.privatevalue;
992  return *this;
993  }
994 
995  /// assignment operator from long double
996  Private& operator=(const long double& r)
997  {
998  this->privatevalue = r;
999  return *this;
1000  }
1001 
1002  /// assignment operator from double
1003  Private& operator=(const double& r)
1004  {
1005  this->privatevalue = (long double)(r);
1006  return *this;
1007  }
1008 
1009  /// assignment operator from int
1010  Private& operator=(const int& i)
1011  {
1012  this->privatevalue = (long double)(i);
1013  return *this;
1014  }
1015 };
1016 #endif // SOPLEX_WITH_GMP
1017 
1018 
1019 
1020 #ifdef SOPLEX_WITH_BOOST
1021 using namespace boost::multiprecision;
1022 // Definitions related to boost number and SoPlex Rational. This is still
1023 // inside the #ifdef SOPLEX_WITH_GMP
1024 
1025 // Assignment operator from boost number. Uses the API for the Private class
1026 // to do this.
1027 template <typename T, expression_template_option eto>
1028 Rational& Rational::operator=(const number<T, eto>& r)
1029 {
1030  *(this->dpointer) = r;
1031  return *this;
1032 }
1033 
1034 #ifndef SOPLEX_WITH_CPPMPF
1035 // Operator to typecast Rational to one of the Boost Number types
1036 template <typename T, expression_template_option eto>
1037 Rational::operator number<T, eto>() const
1038 {
1039  // Constructs a boost::multiprecision::number<T> with value
1040  // this->pointer->privatevalue
1041  return number<T, eto>(this->dpointer->privatevalue);
1042 }
1043 
1044 #else
1045 #ifdef SOPLEX_WITH_GMP
1046 // Specialization for the conversion mpq_t -> cpp_rational
1047 template<unsigned bits, expression_template_option eto>
1048 Rational::operator number<backends::cpp_dec_float<bits>, eto>() const
1049 {
1050  number<gmp_rational, et_on> mpq_numb(this->dpointer->privatevalue);
1051  number<cpp_rational_backend, et_on> cpp_numb = cpp_rational(mpq_numb);
1052  return number<backends::cpp_dec_float<bits>, eto>(cpp_numb);
1053 }
1054 #else
1055 // Specialization for the conversion double -> cpp_rational
1056 template<unsigned bits, expression_template_option eto>
1057 Rational::operator number<backends::cpp_dec_float<bits>, eto>() const
1058 {
1059  return number<backends::cpp_dec_float<bits>, eto>(this->dpointer->privatevalue);
1060 }
1061 #endif
1062 #endif
1063 
1064 // Constructor from boost number. Code is exactly same as that of construction
1065 // of Rational from mpq_t, basically a wrapper around the assignment operator
1066 // (=) of the Private class; calls the boost number assignment operator.
1067 #ifdef SOPLEX_WITH_MPFR
1068 template <typename T, boost::multiprecision::expression_template_option eto>
1069 Rational::Rational(const boost::multiprecision::number<T, eto>& q)
1070 {
1071 
1072  // TODO Figure out why SCIP complains about the static variable problem
1073  // (that useListMem doesn't exist)
1075  {
1076  dpointer = unusedPrivateList.last();
1077 
1078  if(dpointer != nullptr)
1079  {
1080  assert(unusedPrivateList.first() != 0);
1081  unusedPrivateList.remove(dpointer);
1082  *dpointer = q;
1083  }
1084  else
1085  {
1086  assert(unusedPrivateList.first() == 0);
1088  new(dpointer) Private(q);
1089  }
1090  }
1091  else
1092  {
1093  assert(unusedPrivateList.length() == 0);
1094  dpointer = 0;
1095  spx_alloc(dpointer);
1096  new(dpointer) Private(q);
1097  }
1098 
1099  assert(dpointer != 0);
1100 
1101 }
1102 #endif // SOPLEX_WITH_CPPMPF
1103 
1104 #ifdef SOPLEX_WITH_CPPMPF
1105 template <typename T, boost::multiprecision::expression_template_option eto>
1106 Rational::Rational(const boost::multiprecision::number<T, eto>& q)
1107 {
1108  dpointer = 0;
1110  new(dpointer) Private(q);
1111 
1112  assert(dpointer != 0);
1113 }
1114 #endif // SOPLEX_WITH_CPPMPF
1115 #endif
1116 
1117 // A dummy function to deal with the rational scalar issue. This will never be
1118 // called
1119 inline Rational spxFrexp(Rational r, int* d)
1120 {
1121  assert(false);
1122  return Rational(0);
1123 }
1124 
1125 // same as before
1126 inline Rational spxLdexp(Rational x, int exp)
1127 {
1128  // This call shouldn't happen. This is a dummy function to deal with the
1129  // Rational Scalar issue.
1130  assert(false);
1131  return 0;
1132 }
1133 
1134 
1135 
1136 //@}
1137 
1138 } // namespace soplex
1139 
1140 #endif // _RATIONAL_H_
Rational & addProduct(const Rational &r, const Rational &s)
add product of two rationals
Definition: rational.cpp:1389
bool isAdjacentTo(const double &d) const
checks if d is exactly equal to the Rational and if not, if it is one of the two adjacent doubles ...
Definition: rational.cpp:1636
bool isNextTo(const double &d)
checks if d is the closest number that can be represented by double
Definition: rational.cpp:1609
Generic Real linked list.
friend Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:2934
Memory allocation routines.
friend std::string rationalToString(const Rational &r, const int precision)
convert rational number to string
Definition: rational.cpp:1858
int dlcmSizeRational(const Rational *vector, const int length, const int base)
Size of least common multiple of denominators in rational vector.
Definition: rational.cpp:2979
static const Rational ZERO
rational zero (GMP only)
Definition: rational.h:80
Generic Real linked list.Class IdList implements an intrusive Real linked list as a template class...
Definition: idlist.h:123
friend bool operator<(const Rational &r, const Rational &s)
less than operator
Definition: rational.cpp:2100
static THREADLOCAL bool useListMem
list of unused Private objects; note that this cannot be used if SOPLEX_WITH_GMP is not defined...
Definition: rational.h:70
Private & operator=(const int &i)
assignment operator from int
Definition: rational.h:842
Rational operator*(const Rational &r) const
multiplication operator
Definition: rational.cpp:868
Private *const & prev() const
previous Private element
Definition: rational.h:914
~Rational()
destructor
Definition: rational.cpp:305
int sizeInBase(const int base=2) const
Size in specified base (bit size for base 2)
Definition: rational.cpp:1671
friend bool operator<=(const Rational &r, const Rational &s)
less than or equal to operator
Definition: rational.cpp:2108
Rational operator-(const Rational &r) const
subtraction operator
Definition: rational.cpp:681
friend bool operator!=(const Rational &r, const Rational &s)
inequality operator
Definition: rational.cpp:2092
Rational & subProduct(const Rational &r, const Rational &s)
subtract product of two rationals
Definition: rational.cpp:1440
Rational & invert()
inversion
Definition: rational.cpp:1567
friend bool operator>=(const Rational &r, const Rational &s)
greater than or equal to operator
Definition: rational.cpp:2124
Private *& prev()
previous Private element
Definition: rational.h:908
int totalSizeRational(const Rational *vector, const int length, const int base)
Total size of rational vector.
Definition: rational.cpp:2962
Wrapper for GMP type mpq_class.We wrap mpq_class so that we can replace it by a double type if GMP is...
Definition: rational.h:62
static void disableListMem()
disables list memory
Definition: rational.cpp:351
Private *& next()
next Private element
Definition: rational.h:920
Private & operator=(const long double &r)
assignment operator from long double
Definition: rational.h:766
static const Rational NEGONE
rational minus one (GMP only)
Definition: rational.h:82
Private & operator=(const double &r)
assignment operator from double
Definition: rational.h:804
Rational spxLdexp(Rational x, int exp)
Definition: rational.h:1126
Rational & operator/=(const Rational &r)
division assignment operator
Definition: rational.cpp:1163
Rational & operator-=(const Rational &r)
subtraction assignment operator
Definition: rational.cpp:709
void spx_alloc(T &p, int n=1)
Allocate memory.
Definition: spxalloc.h:49
static void freeListMem()
frees the unused rational elements in the memory list
Definition: rational.cpp:342
int dmaxSizeRational(const Rational *vector, const int length, const int base)
Size of largest denominator in rational vector.
Definition: rational.cpp:3002
Private * theprev
pointer to the previous element in the list
Definition: rational.h:640
Private()
default constructor
Definition: rational.h:644
Rational & operator*=(const Rational &r)
multiplication assignment operator operator
Definition: rational.cpp:905
Private & operator=(const Private &p)
assignment operator
Definition: rational.h:751
Private(const double &r)
constructor from double
Definition: rational.h:682
bool readString(const char *s)
read Rational from string
Definition: rational.cpp:1689
static int precision()
returns precision of Rational implementation, i.e., number of bits used to store Rational numbers (IN...
Definition: rational.cpp:1680
friend int sign(const Rational &r)
Sign function; returns 1 if r > 0, 0 if r = 0, and -1 if r < 0.
Definition: rational.cpp:2944
Defines the "Pimpl"-class Private.
Definition: rational.h:635
friend std::ostream & operator<<(std::ostream &os, const Rational &q)
print Rational
Definition: rational.cpp:2063
mpq_t privatevalue
actual value of the Rational object
Definition: rational.h:639
Private(const int &i)
constructor from int
Definition: rational.h:701
static void enableListMem()
enables list memory
Definition: rational.cpp:328
const mpq_t & getMpqRef() const
provides read-only access to underlying mpq_t
Definition: rational.cpp:480
Private(const long double &r)
constructor from long double
Definition: rational.h:663
static const Rational POSONE
rational plus one (GMP only)
Definition: rational.h:81
Debugging, floating point type and parameter definitions.
Private * dpointer
Definition: rational.h:65
friend bool operator==(const Rational &r, const Rational &s)
equality operator
Definition: rational.cpp:2084
Rational spxFrexp(Rational r, int *d)
Definition: rational.h:1119
friend int compareRational(const Rational &r, const Rational &s)
comparison operator returning a positive value if r > s, zero if r = s, and a negative value if r < s...
Definition: rational.cpp:2076
Rational operator+(const Rational &r) const
addition operator
Definition: rational.cpp:504
Everything should be within this namespace.
Private * thenext
pointer to the next element in the list
Definition: rational.h:641
~Private()
constructor from boost number
Definition: rational.h:745
const mpq_t * getMpqPtr() const
provides read-only access to underlying mpq_t
Definition: rational.cpp:472
Rational operator/(const Rational &r) const
division operator
Definition: rational.cpp:1121
friend bool readStringRational(const char *s, Rational &value)
read Rational from string
Definition: rational.cpp:1897
Rational & operator=(const Rational &)
assignment operator
Definition: rational.cpp:360
static THREADLOCAL IdList< Private > unusedPrivateList
list of unused Private objects
Definition: rational.h:69
Rational & subQuotient(const Rational &r, const Rational &s)
subtract quotient of two rationals, r divided by s
Definition: rational.cpp:1530
friend bool operator>(const Rational &r, const Rational &s)
greater than operator
Definition: rational.cpp:2116
mpq_t * getMpqPtr_w() const
provides write access to underlying mpq_t; use with care
Definition: rational.cpp:488
Private & operator=(const mpq_t &q)
assignment operator from mpq_t
Definition: rational.h:880
Private(const Private &p)
copy constructor
Definition: rational.h:652
Private(const mpq_t &q)
constructor from mpq_t (GMP only)
Definition: rational.h:720
Rational()
default constructor
Definition: rational.cpp:108
Private *const & next() const
next Private element
Definition: rational.h:926
mpq_t & getMpqRef_w() const
provides write access to underlying mpq_t; use with care
Definition: rational.cpp:496
#define THREADLOCAL
SOPLEX_DEBUG.
Definition: spxdefines.h:154
Rational & addQuotient(const Rational &r, const Rational &s)
add quotient of two rationals, r divided by s
Definition: rational.cpp:1493
Rational & operator+=(const Rational &r)
addition assignment operator
Definition: rational.cpp:532
Rational & powRound()
round up to next power of two
Definition: rational.cpp:1576