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
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>() const;
183 #endif
184 #endif
185 
186 #ifdef SOPLEX_WITH_GMP
187  /// provides read-only access to underlying mpq_t
188  const mpq_t* getMpqPtr() const;
189 
190  /// provides read-only access to underlying mpq_t
191  const mpq_t& getMpqRef() const;
192 
193  /// provides write access to underlying mpq_t; use with care
194  mpq_t* getMpqPtr_w() const;
195 
196  /// provides write access to underlying mpq_t; use with care
197  mpq_t& getMpqRef_w() const;
198  ///@} // end of RationalWithGMP
199 #endif
200 
201  ///@name Typecasts
202  ///@{
203 
204  ///@}
205 
206 
207  ///@name Arithmetic operators
208  ///@{
209 
210  /// addition operator
211  Rational operator+(const Rational& r) const;
212 
213  /// addition assignment operator
214  Rational& operator+=(const Rational& r);
215 
216  /// addition operator for doubles
217  Rational operator+(const double& r) const;
218 
219  /// addition assignment operator for doubles
220  Rational& operator+=(const double& r);
221 
222  /// addition operator for ints
223  Rational operator+(const int& r) const;
224 
225  /// addition assignment operator for ints
226  Rational& operator+=(const int& r);
227 
228  /// subtraction operator
229  Rational operator-(const Rational& r) const;
230 
231  /// subtraction assignment operator
232  Rational& operator-=(const Rational& r);
233 
234  /// subtraction operator for doubles
235  Rational operator-(const double& r) const;
236 
237  /// subtraction assignment operator for doubles
238  Rational& operator-=(const double& r);
239 
240  /// subtraction operator for ints
241  Rational operator-(const int& r) const;
242 
243  /// subtraction assignment operator for ints
244  Rational& operator-=(const int& r);
245 
246  /// multiplication operator
247  Rational operator*(const Rational& r) const;
248 
249  /// multiplication assignment operator operator
250  Rational& operator*=(const Rational& r);
251 
252  /// multiplication operator for doubles
253  Rational operator*(const double& r) const;
254 
255  /// multiplication assignment operator for doubles
256  Rational& operator*=(const double& r);
257 
258  /// multiplication operator for ints
259  Rational operator*(const int& r) const;
260 
261  /// multiplication assignment operator for ints
262  Rational& operator*=(const int& r);
263 
264  /// division operator
265  Rational operator/(const Rational& r) const;
266 
267  /// division assignment operator
268  Rational& operator/=(const Rational& r);
269 
270  /// division operator for doubles
271  Rational operator/(const double& r) const;
272 
273  /// division assignment operator for doubles
274  Rational& operator/=(const double& r);
275 
276  /// division operator for ints
277  Rational operator/(const int& r) const;
278 
279  /// division assignment operator for ints
280  Rational& operator/=(const int& r);
281 
282  /// add product of two rationals
283  Rational& addProduct(const Rational& r, const Rational& s);
284 
285  /// subtract product of two rationals
286  Rational& subProduct(const Rational& r, const Rational& s);
287 
288  /// add quotient of two rationals, r divided by s
289  Rational& addQuotient(const Rational& r, const Rational& s);
290 
291  /// subtract quotient of two rationals, r divided by s
292  Rational& subQuotient(const Rational& r, const Rational& s);
293 
294  /// inversion
295  Rational& invert();
296 
297  /// round up to next power of two
298  Rational& powRound();
299 
300  ///@}
301 
302 
303  ///@name Methods for checking exactness of doubles
304  ///@{
305 
306  /// checks if \p d is the closest number that can be represented by double
307  bool isNextTo(const double& d);
308 
309  /// checks if \p d is exactly equal to the Rational and if not, if it is one of the two adjacent doubles
310  bool isAdjacentTo(const double& d) const;
311 
312  ///@}
313 
314 
315  ///@name Methods for querying size
316  ///@{
317 
318  /// Size in specified base (bit size for base 2)
319  int sizeInBase(const int base = 2) const;
320 
321  ///@}
322 
323 
324  ///@name Static methods
325  ///@{
326 
327  /// returns precision of Rational implementation, i.e., number of bits used to store Rational numbers (INT_MAX if exact)
328  static int precision();
329 
330  ///@}
331 
332 
333  ///@name Conversion from and to String
334  ///@{
335 
336  /// read Rational from string
337  bool readString(const char* s);
338 
339  friend std::string rationalToString(const Rational& r, const int precision);
340  friend bool readStringRational(const char* s, Rational& value);
341  friend std::ostream& operator<<(std::ostream& os, const Rational& q);
342 
343  ///@}
344 
345  ///@name Friends
346  ///@{
347 
348  friend int compareRational(const Rational& r, const Rational& s);
349  friend bool operator!=(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 
356  friend bool operator!=(const Rational& r, const double& s);
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 
363  friend bool operator!=(const double& r, const Rational& s);
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 
370  friend bool operator!=(const Rational& r, const long double& s);
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 
377  friend bool operator!=(const long double& r, const Rational& s);
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 
384  friend bool operator!=(const Rational& r, const float& s);
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 
391  friend bool operator!=(const float& r, const Rational& s);
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 
398 
399  friend Rational operator+(const double& d, const Rational& r);
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 
404  friend bool operator!=(const Rational& r, const int& s);
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 
411  friend bool operator!=(const int& r, const Rational& s);
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 
418  friend Rational operator+(const int& d, const Rational& r);
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 
423  friend Rational spxAbs(const Rational& r);
424  friend int sign(const Rational& r);
425  friend Rational operator-(const Rational& q);
426 
427  ///@}
428 };
429 
430 /// less than operator
431 bool operator<(const Rational& r, const Rational& s);
432 
433 ///@name Parsing and printing
434 ///@{
435 
436 /// convert rational number to string
437 std::string rationalToString(const Rational& r, const int precision = 32);
438 
439 /// read Rational from string
440 bool readStringRational(const char* s, Rational& value);
441 
442 /// print Rational
443 std::ostream& operator<<(std::ostream& os, const Rational& r);
444 
445 ///@}
446 
447 /// less than operator for Rational and double
448 bool operator<(const Rational& r, const double& s);
449 
450 ///@name Relational operators
451 ///@{
452 
453 /// comparison operator returning a positive value if r > s, zero if r = s, and a negative value if r < s
454 int compareRational(const Rational& r, const Rational& s);
455 
456 /// equality operator
457 bool operator==(const Rational& r, const Rational& s);
458 
459 /// inequality operator
460 bool operator!=(const Rational& r, const Rational& s);
461 
462 /// less than operator
463 bool operator<(const Rational& r, const Rational& s);
464 
465 /// less than or equal to operator
466 bool operator<=(const Rational& r, const Rational& s);
467 
468 /// greater than operator
469 bool operator>(const Rational& r, const Rational& s);
470 
471 /// greater than or equal to operator
472 bool operator>=(const Rational& r, const Rational& s);
473 
474 /// equality operator for Rational and double
475 bool operator==(const Rational& r, const double& s);
476 
477 /// inequality operator for Rational and double
478 bool operator!=(const Rational& r, const double& s);
479 
480 /// less than operator for Rational and double
481 bool operator<(const Rational& r, const double& s);
482 
483 /// less than or equal to operator for Rational and double
484 bool operator<=(const Rational& r, const double& s);
485 
486 /// greater than operator for Rational and double
487 bool operator>(const Rational& r, const double& s);
488 
489 /// greater than or equal to operator for Rational and double
490 bool operator>=(const Rational& r, const double& s);
491 
492 /// equality operator for double and Rational
493 bool operator==(const double& r, const Rational& s);
494 
495 /// inequality operator for double and Rational
496 bool operator!=(const double& r, const Rational& s);
497 
498 /// less than operator for double and Rational
499 bool operator<(const double& r, const Rational& s);
500 
501 /// less than or equal to operator for double and Rational
502 bool operator<=(const double& r, const Rational& s);
503 
504 /// greater than operator for double and Rational
505 bool operator>(const double& r, const Rational& s);
506 
507 /// greater than or equal to operator for double and Rational
508 bool operator>=(const double& r, const Rational& s);
509 
510 /// equality operator for Rational and long double
511 bool operator==(const Rational& r, const long double& s);
512 
513 /// inequality operator for Rational and long double
514 bool operator!=(const Rational& r, const long double& s);
515 
516 /// less than operator for Rational and long double
517 bool operator<(const Rational& r, const long double& s);
518 
519 /// less than or equal to operator for Rational and long double
520 bool operator<=(const Rational& r, const long double& s);
521 
522 /// greater than operator for Rational and long double
523 bool operator>(const Rational& r, const long double& s);
524 
525 /// greater than or equal to operator for Rational and long double
526 bool operator>=(const Rational& r, const long double& s);
527 
528 /// equality operator for long double and Rational
529 bool operator==(const long double& r, const Rational& s);
530 
531 /// inequality operator for long double and Rational
532 bool operator!=(const long double& r, const Rational& s);
533 
534 /// less than operator for long double and Rational
535 bool operator<(const long double& r, const Rational& s);
536 
537 /// less than or equal to operator for long double and Rational
538 bool operator<=(const long double& r, const Rational& s);
539 
540 /// greater than operator for long double and Rational
541 bool operator>(const long double& r, const Rational& s);
542 
543 /// greater than or equal to operator for long double and Rational
544 bool operator>=(const long double& r, const Rational& s);
545 
546 /// equality operator for Rational and int
547 bool operator==(const Rational& r, const int& s);
548 
549 /// inequality operator for Rational and int
550 bool operator!=(const Rational& r, const int& s);
551 
552 /// less than operator for Rational and int
553 bool operator<(const Rational& r, const int& s);
554 
555 /// less than or equal to operator for Rational and int
556 bool operator<=(const Rational& r, const int& s);
557 
558 /// greater than operator for Rational and int
559 bool operator>(const Rational& r, const int& s);
560 
561 /// greater than or equal to operator for Rational and int
562 bool operator>=(const Rational& r, const int& s);
563 
564 /// equality operator for int and Rational
565 bool operator==(const int& r, const Rational& s);
566 
567 /// inequality operator for int and Rational
568 bool operator!=(const int& r, const Rational& s);
569 
570 /// less than operator for int and Rational
571 bool operator<(const int& r, const Rational& s);
572 
573 /// less than or equal to operator for int and Rational
574 bool operator<=(const int& r, const Rational& s);
575 
576 /// greater than operator for int and Rational
577 bool operator>(const int& r, const Rational& s);
578 
579 /// greater than or equal to operator for int and Rational
580 bool operator>=(const int& r, const Rational& s);
581 
582 ///@}
583 
584 /// Sign function; returns 1 if r > 0, 0 if r = 0, and -1 if r < 0.
585 int sign(const Rational& r);
586 
587 ///@name Non-member arithmetic operators and functions
588 ///@{
589 
590 /// addition operator for double and Rational
591 Rational operator+(const double& d, const Rational& r);
592 
593 /// addition operator for double and Rational
594 Rational operator+(const double& d, const Rational& r);
595 
596 /// addition operator for double and Rational
597 Rational operator+(const double& d, const Rational& r);
598 
599 /// addition operator for double and Rational
600 Rational operator+(const double& d, const Rational& r);
601 
602 /// addition operator for int and Rational
603 Rational operator+(const int& d, const Rational& r);
604 
605 /// addition operator for int and Rational
606 Rational operator+(const int& d, const Rational& r);
607 
608 /// addition operator for int and Rational
609 Rational operator+(const int& d, const Rational& r);
610 
611 /// addition operator for int and Rational
612 Rational operator+(const int& d, const Rational& r);
613 
614 /// absolute function
615 Rational spxAbs(const Rational& r);
616 
617 /// Sign function; returns 1 if r > 0, 0 if r = 0, and -1 if r < 0.
618 int sign(const Rational& r);
619 
620 /// Negation.
621 Rational operator-(const Rational& r);
622 
623 /// Total size of rational vector.
624 int totalSizeRational(const Rational* vector, const int length, const int base = 2);
625 
626 /// Size of least common multiple of denominators in rational vector.
627 int dlcmSizeRational(const Rational* vector, const int length, const int base = 2);
628 
629 /// Size of largest denominator in rational vector.
630 int dmaxSizeRational(const Rational* vector, const int length, const int base = 2);
631 
632 #ifdef SOPLEX_WITH_GMP
633 /// Defines the "Pimpl"-class Private
635 {
636 public:
637 
638  mpq_t privatevalue; ///< actual value of the Rational object
639  Private* theprev; ///< pointer to the previous element in the list
640  Private* thenext; ///< pointer to the next element in the list
641 
642  /// default constructor
644  : theprev(0)
645  , thenext(0)
646  {
647  mpq_init(privatevalue);
648  }
649 
650  /// copy constructor
651  Private(const Private& p)
652  : theprev(0)
653  , thenext(0)
654  {
655  // a newly constructed element is not in any list, even if the original element (p) is; hence we initialize
656  // theprev and thenext to zero
657  mpq_init(privatevalue);
658  mpq_set(this->privatevalue, p.privatevalue);
659  }
660 
661  /// constructor from long double
662  Private(const long double& r)
663  : theprev(0)
664  , thenext(0)
665  {
666  mpq_init(privatevalue);
667 
668  if(r == (long double)(1.0))
669  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
670  else if(r == (long double)(-1.0))
671  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
672  else if(r == (long double)(0.0))
673  {
674  assert(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
675  }
676  else
677  mpq_set_d(privatevalue, double(r));
678  }
679 
680  /// constructor from double
681  Private(const double& r)
682  : theprev(0)
683  , thenext(0)
684  {
685  mpq_init(privatevalue);
686 
687  if(r == 1.0)
688  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
689  else if(r == -1.0)
690  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
691  else if(r == 0.0)
692  {
693  assert(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
694  }
695  else
696  mpq_set_d(privatevalue, r);
697  }
698 
699  /// constructor from int
700  Private(const int& i)
701  : theprev(0)
702  , thenext(0)
703  {
704  mpq_init(privatevalue);
705 
706  if(i == 1)
707  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
708  else if(i == -1)
709  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
710  else if(i == 0)
711  {
712  assert(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
713  }
714  else
715  mpq_set_si(privatevalue, i, 1);
716  }
717 
718  /// constructor from mpq_t (GMP only)
719  Private(const mpq_t& q)
720  : theprev(0)
721  , thenext(0)
722  {
723  mpq_init(privatevalue);
724  mpq_set(privatevalue, q);
725  }
726 
727  /// constructor from boost number
728  // Also should satisfy SOPLEX_WITH_GMP
729 #ifdef SOPLEX_WITH_BOOST
730 #ifdef SOPLEX_WITH_GMP
731  template <typename T, boost::multiprecision::expression_template_option eto>
732  Private(const boost::multiprecision::number<T, eto>& q)
733  : theprev(0)
734  , thenext(0)
735  {
736  boost::multiprecision::mpq_rational tmp{q};
737  mpq_init(privatevalue);
738  mpq_set(privatevalue, tmp.backend().data());
739  }
740 #endif
741 #endif
742 
743  /// destructor
745  {
746  mpq_clear(privatevalue);
747  }
748 
749  /// assignment operator
751  {
752 #ifdef SOPLEX_PERFALT_4
753 
754  if(mpq_equal(this->privatevalue, p.privatevalue) != 0)
755  return *this;
756 
757 #endif
758 
759  // we only assign the value; the position in the list, i.e., theprev and thenext, must not be modified
760  mpq_set(this->privatevalue, p.privatevalue);
761  return *this;
762  }
763 
764  /// assignment operator from long double
765  Private& operator=(const long double& r)
766  {
767  // we only assign the value; the position in the list, i.e., theprev and thenext, must not be modified
768  if(r == (long double)(0.0))
769  {
770 #ifdef SOPLEX_PERFALT_5a
771 #ifdef SOPLEX_PERFALT_1
772 
773  if(mpq_sgn(privatevalue) != 0)
774 #else
775  if(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) == 0)
776 #endif
777 #endif
778  mpq_set(privatevalue, Rational::ZERO.dpointer->privatevalue);
779  }
780  else if(r == (long double)(1.0))
781  {
782 #ifdef SOPLEX_PERFALT_5b
783 
784  if(mpq_equal(privatevalue, Rational::POSONE.dpointer->privatevalue) == 0)
785 #endif
786  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
787  }
788  else if(r == (long double)(-1.0))
789  {
790 #ifdef SOPLEX_PERFALT_5b
791 
792  if(mpq_equal(privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0)
793 #endif
794  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
795  }
796  else
797  mpq_set_d(this->privatevalue, double(r));
798 
799  return *this;
800  }
801 
802  /// assignment operator from double
803  Private& operator=(const double& r)
804  {
805  // we only assign the value; the position in the list, i.e., theprev and thenext, must not be modified
806  if(r == 0.0)
807  {
808 #ifdef SOPLEX_PERFALT_5a
809 #ifdef SOPLEX_PERFALT_1
810 
811  if(mpq_sgn(privatevalue) != 0)
812 #else
813  if(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) == 0)
814 #endif
815 #endif
816  mpq_set(privatevalue, Rational::ZERO.dpointer->privatevalue);
817  }
818  else if(r == 1.0)
819  {
820 #ifdef SOPLEX_PERFALT_5b
821 
822  if(mpq_equal(privatevalue, Rational::POSONE.dpointer->privatevalue) == 0)
823 #endif
824  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
825  }
826  else if(r == -1.0)
827  {
828 #ifdef SOPLEX_PERFALT_5b
829 
830  if(mpq_equal(privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0)
831 #endif
832  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
833  }
834  else
835  mpq_set_d(privatevalue, r);
836 
837  return *this;
838  }
839 
840  /// assignment operator from int
841  Private& operator=(const int& i)
842  {
843  // we only assign the value; the position in the list, i.e., theprev and thenext, must not be modified
844  if(i == 0)
845  {
846 #ifdef SOPLEX_PERFALT_5a
847 #ifdef SOPLEX_PERFALT_1
848 
849  if(mpq_sgn(privatevalue) != 0)
850 #else
851  if(mpq_equal(privatevalue, Rational::ZERO.dpointer->privatevalue) == 0)
852 #endif
853 #endif
854  mpq_set(privatevalue, Rational::ZERO.dpointer->privatevalue);
855  }
856  else if(i == 1)
857  {
858 #ifdef SOPLEX_PERFALT_5b
859 
860  if(mpq_equal(privatevalue, Rational::POSONE.dpointer->privatevalue) == 0)
861 #endif
862  mpq_set(privatevalue, Rational::POSONE.dpointer->privatevalue);
863  }
864  else if(i == -1)
865  {
866 #ifdef SOPLEX_PERFALT_5b
867 
868  if(mpq_equal(privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0)
869 #endif
870  mpq_set(privatevalue, Rational::NEGONE.dpointer->privatevalue);
871  }
872  else
873  mpq_set_si(privatevalue, i, 1);
874 
875  return *this;
876  }
877 
878  /// assignment operator from mpq_t
879  Private& operator=(const mpq_t& q)
880  {
881 #ifdef SOPLEX_PERFALT_4
882 
883  if(mpq_equal(this->privatevalue, q) != 0)
884  return *this;
885 
886 #endif
887 
888  // we only assign the value; the position in the list, i.e., theprev and thenext, must not be modified
889  mpq_set(this->privatevalue, q);
890  return *this;
891  }
892 
893 #ifdef SOPLEX_WITH_BOOST
894  // The back end for Rational operator=.
895  template <typename T, boost::multiprecision::expression_template_option eto>
896  Private& operator=(const boost::multiprecision::number<T, eto>& q)
897  {
898  // mpq_rational is used as an intermediate to convert the mpf float to
899  // mpq_t.
900  boost::multiprecision::mpq_rational tmp{q};
901  mpq_set(this->privatevalue, tmp.backend().data());
902  return *this;
903  }
904 #endif
905 
906  /// previous Private element
908  {
909  return theprev;
910  }
911 
912  /// previous Private element
913  Private* const& prev() const
914  {
915  return theprev;
916  }
917 
918  /// next Private element
920  {
921  return thenext;
922  }
923 
924  /// next Private element
925  Private* const& next() const
926  {
927  return thenext;
928  }
929 };
930 #else // SOPLEX_WITH_GMP
931 
932 /// Defines the "Pimpl"-class Private
933 class Rational::Private
934 {
935 
936 public:
937 
938  /// value
939  long double privatevalue;
940 
941 #ifdef SOPLEX_WITH_BOOST
942  template <typename T, boost::multiprecision::expression_template_option eto>
943  Private(const boost::multiprecision::number<T, eto>& q)
944  {
945  privatevalue = (long double)q;
946  }
947 
948  template <typename T, boost::multiprecision::expression_template_option eto>
949  Private& operator=(const boost::multiprecision::number<T, eto>& q)
950  {
951  privatevalue = (long double)q;
952  return *this;
953  }
954 #endif
955 
956 
957  /// default constructor
958  Private()
959  {
960  privatevalue = 0;
961  }
962 
963  /// copy constructor
964  Private(const Private& p)
965  {
966  *this = p;
967  }
968 
969  /// constructor from long double
970  Private(const long double& r)
971  {
972  privatevalue = r;
973  }
974 
975  /// constructor from double
976  Private(const double& r)
977  {
978  privatevalue = r;
979  }
980 
981  /// constructor from int
982  Private(const int& i)
983  {
984  privatevalue = i;
985  }
986 
987  /// assignment operator
988  Private& operator=(const Private& p)
989  {
990  this->privatevalue = p.privatevalue;
991  return *this;
992  }
993 
994  /// assignment operator from long double
995  Private& operator=(const long double& r)
996  {
997  this->privatevalue = r;
998  return *this;
999  }
1000 
1001  /// assignment operator from double
1002  Private& operator=(const double& r)
1003  {
1004  this->privatevalue = (long double)(r);
1005  return *this;
1006  }
1007 
1008  /// assignment operator from int
1009  Private& operator=(const int& i)
1010  {
1011  this->privatevalue = (long double)(i);
1012  return *this;
1013  }
1014 };
1015 #endif // SOPLEX_WITH_GMP
1016 
1017 
1018 
1019 #ifdef SOPLEX_WITH_BOOST
1020 using namespace boost::multiprecision;
1021 // Definitions related to boost number and SoPlex Rational. This is still
1022 // inside the #ifdef SOPLEX_WITH_GMP
1023 
1024 // Assignment operator from boost number. Uses the API for the Private class
1025 // to do this.
1026 template <typename T, expression_template_option eto>
1027 Rational& Rational::operator=(const number<T, eto>& r)
1028 {
1029  *(this->dpointer) = r;
1030  return *this;
1031 }
1032 
1033 #ifndef SOPLEX_WITH_CPPMPF
1034 // Operator to typecast Rational to one of the Boost Number types
1035 template <typename T, expression_template_option eto>
1036 Rational::operator number<T, eto>() const
1037 {
1038  // Constructs a boost::multiprecision::number<T> with value
1039  // this->pointer->privatevalue
1040  return number<T, eto>(this->dpointer->privatevalue);
1041 }
1042 
1043 #else
1044 #ifdef SOPLEX_WITH_GMP
1045 // Specialization for the conversion mpq_t -> cpp_rational
1046 template<unsigned bits, expression_template_option eto>
1047 Rational::operator number<backends::cpp_dec_float<bits>, eto>() const
1048 {
1049  number<gmp_rational, et_on> mpq_numb(this->dpointer->privatevalue);
1050  number<cpp_rational_backend, et_on> cpp_numb = cpp_rational(mpq_numb);
1051  return number<backends::cpp_dec_float<bits>, eto>(cpp_numb);
1052 }
1053 #else
1054 // Specialization for the conversion double -> cpp_rational
1055 template<unsigned bits, expression_template_option eto>
1056 Rational::operator number<backends::cpp_dec_float<bits>, eto>() const
1057 {
1058  return number<backends::cpp_dec_float<bits>, eto>(this->dpointer->privatevalue);
1059 }
1060 #endif
1061 #endif
1062 
1063 // Constructor from boost number. Code is exactly same as that of construction
1064 // of Rational from mpq_t, basically a wrapper around the assignment operator
1065 // (=) of the Private class; calls the boost number assignment operator.
1066 #ifdef SOPLEX_WITH_MPFR
1067 template <typename T, boost::multiprecision::expression_template_option eto>
1068 Rational::Rational(const boost::multiprecision::number<T, eto>& q)
1069 {
1070 
1071  // TODO Figure out why SCIP complains about the static variable problem
1072  // (that useListMem doesn't exist)
1074  {
1075  dpointer = unusedPrivateList.last();
1076 
1077  if(dpointer != nullptr)
1078  {
1079  assert(unusedPrivateList.first() != 0);
1080  unusedPrivateList.remove(dpointer);
1081  *dpointer = q;
1082  }
1083  else
1084  {
1085  assert(unusedPrivateList.first() == 0);
1087  new(dpointer) Private(q);
1088  }
1089  }
1090  else
1091  {
1092  assert(unusedPrivateList.length() == 0);
1093  dpointer = 0;
1094  spx_alloc(dpointer);
1095  new(dpointer) Private(q);
1096  }
1097 
1098  assert(dpointer != 0);
1099 
1100 }
1101 #endif // SOPLEX_WITH_CPPMPF
1102 
1103 #ifdef SOPLEX_WITH_CPPMPF
1104 template <typename T, boost::multiprecision::expression_template_option eto>
1105 Rational::Rational(const boost::multiprecision::number<T, eto>& q)
1106 {
1107  dpointer = 0;
1109  new(dpointer) Private(q);
1110 
1111  assert(dpointer != 0);
1112 }
1113 #endif // SOPLEX_WITH_CPPMPF
1114 #endif
1115 
1116 // A dummy function to deal with the rational scalar issue. This will never be
1117 // called
1118 inline Rational spxFrexp(Rational r, int* d)
1119 {
1120  assert(false);
1121  return Rational(0);
1122 }
1123 
1124 // same as before
1125 inline Rational spxLdexp(Rational x, int exp)
1126 {
1127  // This call shouldn't happen. This is a dummy function to deal with the
1128  // Rational Scalar issue.
1129  assert(false);
1130  return 0;
1131 }
1132 
1133 
1134 
1135 //@}
1136 
1137 } // namespace soplex
1138 
1139 #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:841
Rational operator*(const Rational &r) const
multiplication operator
Definition: rational.cpp:868
Private *const & prev() const
previous Private element
Definition: rational.h:913
~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:907
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:919
Private & operator=(const long double &r)
assignment operator from long double
Definition: rational.h:765
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:803
Rational spxLdexp(Rational x, int exp)
Definition: rational.h:1125
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:639
Private()
default constructor
Definition: rational.h:643
Rational & operator*=(const Rational &r)
multiplication assignment operator operator
Definition: rational.cpp:905
Private & operator=(const Private &p)
assignment operator
Definition: rational.h:750
Private(const double &r)
constructor from double
Definition: rational.h:681
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:634
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:638
Private(const int &i)
constructor from int
Definition: rational.h:700
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:662
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:1118
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:640
~Private()
constructor from boost number
Definition: rational.h:744
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:879
Private(const Private &p)
copy constructor
Definition: rational.h:651
Private(const mpq_t &q)
constructor from mpq_t (GMP only)
Definition: rational.h:719
Rational()
default constructor
Definition: rational.cpp:108
Private *const & next() const
next Private element
Definition: rational.h:925
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