1
2 /* ----------------------------------------------------------------------
3 * This file is autogenerated from the file multiprecision.hpp.in during
4 * the cmake configuration of your project. If you need to make changes
5 * edit the original file.
6 * ----------------------------------------------------------------------
7 */
8 #ifndef __SOPLEX_MULTIPRECISION_HPP_
9 #define __SOPLEX_MULTIPRECISION_HPP_
10 #define SOPLEX_DEBUG
11 #include <numeric>
12 #include <vector>
13 #include <string>
14 #include "soplex/spxdefines.h"
15
16 #ifdef SOPLEX_WITH_GMP
17 #include <gmp.h>
18 #endif
19
20 #ifdef SOPLEX_WITH_BOOST
21 #include <boost/multiprecision/number.hpp>
22
23 #ifdef SOPLEX_WITH_GMP
24 #include <boost/multiprecision/gmp.hpp>
25
26 namespace soplex
27 {
28
29 using namespace boost::multiprecision;
30 using Rational = number<gmp_rational, et_off>;
31 using Integer = number<gmp_int, et_off>;
32 inline void SpxLcm(Integer& result, Integer a, Integer b)
33 {
34 mpz_lcm(result.backend().data(), a.backend().data(), b.backend().data());
35 }
36 inline void SpxGcd(Integer& result, Integer a, Integer b)
37 {
38 mpz_gcd(result.backend().data(), a.backend().data(), b.backend().data());
39 }
40
41 } // namespace soplex
42 #else
43 #include <boost/multiprecision/cpp_int.hpp>
44 #include <boost/multiprecision/detail/default_ops.hpp>
45
46 namespace soplex
47 {
48
49 using namespace boost::multiprecision;
50 using Rational = cpp_rational;
51 using Integer = cpp_int;
52 inline void SpxLcm(Integer& result, Integer a, Integer b)
53 {
54 result = boost::multiprecision::lcm(a, b);
55 }
56 inline void SpxGcd(Integer& result, Integer a, Integer b)
57 {
58 result = boost::multiprecision::gcd(a, b);
59 }
60
61 } // namespace soplex
62 #endif
63
64 namespace soplex
65 {
66
67 inline void printRational(Rational r)
68 {
69 std::cout << r << std::endl;
70 }
71
72 inline void printInteger(Integer r)
73 {
74 std::cout << r << std::endl;
75 }
76 inline bool isAdjacentTo(const Rational& r, const double& d)
77 {
78 double x = (double) r;
79 double a;
80 double b;
81 Rational tmp = x;
82
83 // the rational value is representable in double precision
84 if(tmp == r)
85 return true;
86 // the rounded value is smaller than the rational value
87 else if(tmp < r)
88 {
89 a = x;
90 b = (double)nextafter(a, 1e100);
91 }
92 // the rounded value is larger than the rational value
93 else
94 {
95 b = x;
96 a = (double)nextafter(b, -1e100);
97 }
98
99 return ((a == d) || (b == d));
100 }
101
102 inline void invert(Rational& r)
103 {
104 r = Rational(denominator(r), numerator(r));
105 }
106
107 /// round up to next power of two
108 inline void powRound(Rational& r)
109 {
110 Integer roundval;
111 Integer den;
112 Integer num;
113
114 MSG_DEBUG(std::cout << "rounding " << str(r) <<
115 " to power of two" << "\n");
116
117 num = numerator(r);
118 den = denominator(r);
119 roundval = num / den;
120
121 MSG_DEBUG(std::cout << " --> " << str(roundval) << "\n");
122
123 size_t binlog = roundval == 0 ? 1 : msb(roundval) + 1;
124 Integer base = 2;
125
126 MSG_DEBUG(std::cout << " --> 2^" << binlog << "\n");
127
128 roundval = boost::multiprecision::pow(base, (unsigned int)binlog);
129
130 MSG_DEBUG(std::cout << " --> " << str(roundval) << "\n");
131
132 r = roundval;
133
134 MSG_DEBUG(std::cout << " --> " << str(r) << "\n");
135 }
136
137 /* find substring, ignore case */
138 static
139 std::string::const_iterator findSubStringIC(const std::string& substr, const std::string& str)
140 {
141 auto it = std::search(
142 str.begin(), str.end(),
143 substr.begin(), substr.end(),
144 [](char ch1, char ch2)
145 {
146 return std::toupper(ch1) == std::toupper(ch2);
147 }
148 );
149 return it;
150 }
151
152 inline Rational ratFromString(const char* desc)
153 {
154 Rational res;
155
156 if(0 == strcmp(desc, "inf"))
157 {
158 res = 1e100;
159 }
160 else if(0 == strcmp(desc, "-inf"))
161 {
162 res = -1e100;
163 }
164 else
165 {
166 std::string s(desc);
167
168 /* case 1: string is given in nom/den format */
169 if(s.find('.') == std::string::npos)
170 {
171 if(s[0] == '+')
172 res = Rational(desc + 1);
173 else
174 res = Rational(desc);
175 }
176 /* case 2: string is given as base-10 decimal number */
177 else
178 {
179 std::string::const_iterator it = findSubStringIC("e", s);
180 int mult = 0;
181
182 if(it != s.end())
183 {
184 int exponentidx = int(it - s.begin());
185 mult = std::stoi(s.substr(exponentidx + 1, s.length()));
186 s = s.substr(0, exponentidx);
187 }
188
189 // std::cout << s << std::endl;
190 if(s[0] == '.')
191 s.insert(0, "0");
192
193 size_t pos = s.find('.');
194 size_t exp = s.length() - 1 - pos;
195 std::string den("1");
196
197 for(size_t i = 0; i < exp; ++i)
198 den.append("0");
199
200 s.erase(pos, 1);
201 assert(std::all_of(s.begin() + 1, s.end(), ::isdigit));
202
203 // remove padding 0s
204 if(s[0] == '-')
205 s.erase(1, std::min(s.substr(1).find_first_not_of('0'), s.size() - 1));
206 else
207 s.erase(0, std::min(s.find_first_not_of('0'), s.size() - 1));
208
209 s.append("/");
210 s.append(den);
211 res = Rational(s);
212 res *= pow(10, mult);
213 }
214 }
215
216 return res;
217 }
218
219 } // namespace soplex
220 #else
221
222 #ifndef SOPLEX_WITH_GMP
223 using mpq_t = char;
224 #endif
225
226 using Integer = int;
227 // this is a placeholder class to ensure compilation when boost ist not linked. Rationals need BOOST in order to function.
228 class Rational
229 {
230
231 public:
232
233 ///@name Construction and destruction
234 ///@{
235
236 inline void rationalErrorMessage() const
237 {
238 MSG_ERROR(std::cerr << "Using rational methods without linking boost is not supported" << std::endl;
239 )
240 };
241
242 /// default constructor
243 inline Rational()
244 {
245 };
246 /// copy constructor
247 inline Rational(const Rational& r)
248 {
249 };
250 /// constructor from long double
251 inline Rational(const long double& r)
252 {
253 };
254 /// constructor from double
255 inline Rational(const double& r)
256 {
257 };
258 ///constructor from int
259 inline Rational(const int& i)
260 {
261 };
262 /// constructor from Integer
263 inline Rational(const Integer& num, const Integer& den)
264 {
265 };
266 /// constructor from mpq_t (GMP only)
267 inline Rational(const mpq_t& q)
268 {
269 };
270 #ifdef SOPLEX_WITH_BOOST
271 // constructor from boost number
272 inline template <typename T, boost::multiprecision::expression_template_option eto>
273 Rational(const boost::multiprecision::number<T, eto>& q)
274 {
275 };
276 #endif
277 /// destructor
278 inline ~Rational()
279 {
280 };
281
282 /// assignment operator
283 inline Rational& operator=(const Rational&)
284 {
285 return *this;
286 };
287 /// assignment operator from long double
288 inline Rational& operator=(const long double& r)
289 {
290 return *this;
291 };
292 /// assignment operator from double
293 inline Rational& operator=(const double& r)
294 {
295 return *this;
296 };
297 /// assignment operator from int
298 inline Rational& operator=(const int& i)
299 {
300 return *this;
301 };
302 /// assignment operator from mpq_t
303 inline Rational& operator=(const mpq_t& q)
304 {
305 return *this;
306 };
307
308 inline void assign(const Rational&)
309 {
310 rationalErrorMessage();
311 };
312 inline void assign(const long double& r)
313 {
314 rationalErrorMessage();
315 };
316 inline void assign(const double& r)
317 {
318 rationalErrorMessage();
319 };
320 inline void assign(const int& i)
321 {
322 rationalErrorMessage();
323 };
324
325 ///@name Typecasts
326 ///@{
327
328 inline operator double() const
329 {
330 return 0;
331 };
332 inline operator long double() const
333 {
334 return 0;
335 };
336 inline operator float() const
337 {
338 return 0;
339 };
340 #ifdef SOPLEX_WITH_BOOST
341 #ifndef SOPLEX_WITH_CPPMPF
342 // Operator to typecast Rational to one of the Boost Number types
343 inline template <typename T, boost::multiprecision::expression_template_option eto>
344 operator boost::multiprecision::number<T, eto>() const
345 {
346 rationalErrorMessage();
347 return 0;
348 };
349 #else
350 // Operator to typecast Rational to one of the Boost Number types
351 inline template <unsigned bits, boost::multiprecision::expression_template_option eto>
352 operator boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<bits>, eto>()
353 const
354 {
355 rationalErrorMessage();
356 return 0;
357 };
358 #endif
359 #endif
360
361 ///@name Typecasts
362 ///@{
363
364 ///@}
365
366
367 ///@name Arithmetic operators
368 ///@{
369
370 /// addition operator
371 inline Rational operator+(const Rational& r) const
372 {
373 rationalErrorMessage();
374 return *this;
375 }
376 /// addition assignment operator
377 inline Rational operator+=(const Rational& r)
378 {
379 rationalErrorMessage();
380 return *this;
381 }
382 /// addition operator for doubles
383 inline Rational operator+(const double& r) const
384 {
385 rationalErrorMessage();
386 return *this;
387 }
388 /// addition assignment operator for doubles
389 inline Rational operator+=(const double& r)
390 {
391 rationalErrorMessage();
392 return *this;
393 }
394 /// addition operator for ints
395 inline Rational operator+(const int& r) const
396 {
397 rationalErrorMessage();
398 return *this;
399 }
400 /// addition assignment operator for ints
401 inline Rational operator+=(const int& r)
402 {
403 rationalErrorMessage();
404 return *this;
405 }
406 /// subtraction operator
407 inline Rational operator-(const Rational& r) const
408 {
409 rationalErrorMessage();
410 return *this;
411 }
412 /// subtraction assignment operator
413 inline Rational operator-=(const Rational& r)
414 {
415 rationalErrorMessage();
416 return *this;
417 }
418 /// subtraction operator for doubles
419 inline Rational operator-(const double& r) const
420 {
421 rationalErrorMessage();
422 return *this;
423 }
424 /// subtraction assignment operator for doubles
425 inline Rational operator-=(const double& r)
426 {
427 rationalErrorMessage();
428 return *this;
429 }
430 /// subtraction operator for ints
431 inline Rational operator-(const int& r) const
432 {
433 rationalErrorMessage();
434 return *this;
435 }
436 /// subtraction assignment operator for ints
437 inline Rational operator-=(const int& r)
438 {
439 rationalErrorMessage();
440 return *this;
441 }
442 /// multiplication operator
443 inline Rational operator*(const Rational& r) const
444 {
445 rationalErrorMessage();
446 return *this;
447 }
448 /// multiplication assignment operator operator
449 inline Rational operator*=(const Rational& r)
450 {
451 rationalErrorMessage();
452 return *this;
453 }
454 /// multiplication operator for doubles
455 inline Rational operator*(const double& r) const
456 {
457 rationalErrorMessage();
458 return *this;
459 }
460 /// multiplication assignment operator for doubles
461 inline Rational operator*=(const double& r)
462 {
463 rationalErrorMessage();
464 return *this;
465 }
466 /// multiplication operator for ints
467 inline Rational operator*(const int& r) const
468 {
469 rationalErrorMessage();
470 return *this;
471 }
472 /// multiplication assignment operator for ints
473 inline Rational operator*=(const int& r)
474 {
475 rationalErrorMessage();
476 return *this;
477 }
478 /// division operator
479 inline Rational operator/(const Rational& r) const
480 {
481 rationalErrorMessage();
482 return *this;
483 }
484 /// division assignment operator
485 inline Rational operator/=(const Rational& r)
486 {
487 rationalErrorMessage();
488 return *this;
489 }
490 /// division operator for doubles
491 inline Rational operator/(const double& r) const
492 {
493 rationalErrorMessage();
494 return *this;
495 }
496 /// division assignment operator for doubles
497 inline Rational operator/=(const double& r)
498 {
499 rationalErrorMessage();
500 return *this;
501 }
502 /// division operator for ints
503 inline Rational operator/(const int& r) const
504 {
505 rationalErrorMessage();
506 return *this;
507 }
508 /// division assignment operator for ints
509 inline Rational operator/=(const int& r)
510 {
511 rationalErrorMessage();
512 return *this;
513 }
514 /// add product of two rationals
515 Rational& addProduct(const Rational& r, const Rational& s)
516 {
517 rationalErrorMessage();
518 return *this;
519 }
520
521 /// subtract product of two rationals
522 Rational& subProduct(const Rational& r, const Rational& s)
523 {
524 rationalErrorMessage();
525 return *this;
526 }
527
528 /// add quotient of two rationals, r divided by s
529 Rational& addQuotient(const Rational& r, const Rational& s)
530 {
531 rationalErrorMessage();
532 return *this;
533 }
534
535 /// subtract quotient of two rationals, r divided by s
536 Rational& subQuotient(const Rational& r, const Rational& s)
537 {
538 rationalErrorMessage();
539 return *this;
540 }
541
542 ///@}
543
544
545 ///@name Methods for checking exactness of doubles
546 ///@{
547
548 /// checks if \p d is exactly equal to the Rational and if not, if it is one of the two adjacent doubles
549 inline bool isAdjacentTo(const double& d) const
550 {
551 rationalErrorMessage();
552 return false;
553 };
554
555 ///@}
556
557
558 ///@name Methods for querying size
559 ///@{
560
561 /// Size in specified base (bit size for base 2)
562 int sizeInBase(const int base = 2) const
563 {
564 rationalErrorMessage();
565 return 0;
566 };
567
568 ///@}
569
570
571 ///@name Conversion from and to String
572 ///@{
573 inline friend std::ostream& operator<<(std::ostream& os, const Rational& r)
574 {
575 r.rationalErrorMessage();
576 return os;
577 };
578 inline std::string str() const
579 {
580 this->rationalErrorMessage();
581 return std::string("");
582 };
583 ///@}
584
585 ///@name Friends
586 ///@{
587
588 inline friend int compareRational(const Rational& r, const Rational& s)
589 {
590 r.rationalErrorMessage();
591 return 0;
592 };
593 inline friend bool operator!=(const Rational& r, const Rational& s)
594 {
595 r.rationalErrorMessage();
596 return false;
597 };
598 inline friend bool operator==(const Rational& r, const Rational& s)
599 {
600 r.rationalErrorMessage();
601 return false;
602 };
603 inline friend bool operator<(const Rational& r, const Rational& s)
604 {
605 r.rationalErrorMessage();
606 return false;
607 };
608 inline friend bool operator<=(const Rational& r, const Rational& s)
609 {
610 r.rationalErrorMessage();
611 return false;
612 };
613 inline friend bool operator>(const Rational& r, const Rational& s)
614 {
615 r.rationalErrorMessage();
616 return false;
617 };
618 inline friend bool operator>=(const Rational& r, const Rational& s)
619 {
620 r.rationalErrorMessage();
621 return false;
622 };
623
624 inline friend bool operator!=(const Rational& r, const double& s)
625 {
626 r.rationalErrorMessage();
627 return false;
628 };
629 inline friend bool operator==(const Rational& r, const double& s)
630 {
631 r.rationalErrorMessage();
632 return false;
633 };
634 inline friend bool operator<(const Rational& r, const double& s)
635 {
636 r.rationalErrorMessage();
637 return false;
638 };
639 inline friend bool operator<=(const Rational& r, const double& s)
640 {
641 r.rationalErrorMessage();
642 return false;
643 };
644 inline friend bool operator>(const Rational& r, const double& s)
645 {
646 r.rationalErrorMessage();
647 return false;
648 };
649 inline friend bool operator>=(const Rational& r, const double& s)
650 {
651 r.rationalErrorMessage();
652 return false;
653 };
654
655 inline friend bool operator!=(const double& r, const Rational& s)
656 {
657 s.rationalErrorMessage();
658 return false;
659 };
660 inline friend bool operator==(const double& r, const Rational& s)
661 {
662 s.rationalErrorMessage();
663 return false;
664 };
665 inline friend bool operator<(const double& r, const Rational& s)
666 {
667 s.rationalErrorMessage();
668 return false;
669 };
670 inline friend bool operator<=(const double& r, const Rational& s)
671 {
672 s.rationalErrorMessage();
673 return false;
674 };
675 inline friend bool operator>(const double& r, const Rational& s)
676 {
677 s.rationalErrorMessage();
678 return false;
679 };
680 inline friend bool operator>=(const double& r, const Rational& s)
681 {
682 s.rationalErrorMessage();
683 return false;
684 };
685
686 inline friend bool operator!=(const Rational& r, const long double& s)
687 {
688 r.rationalErrorMessage();
689 return false;
690 };
691 inline friend bool operator==(const Rational& r, const long double& s)
692 {
693 r.rationalErrorMessage();
694 return false;
695 };
696 inline friend bool operator<(const Rational& r, const long double& s)
697 {
698 r.rationalErrorMessage();
699 return false;
700 };
701 inline friend bool operator<=(const Rational& r, const long double& s)
702 {
703 r.rationalErrorMessage();
704 return false;
705 };
706 inline friend bool operator>(const Rational& r, const long double& s)
707 {
708 r.rationalErrorMessage();
709 return false;
710 };
711 inline friend bool operator>=(const Rational& r, const long double& s)
712 {
713 r.rationalErrorMessage();
714 return false;
715 };
716
717 inline friend bool operator!=(const long double& r, const Rational& s)
718 {
719 s.rationalErrorMessage();
720 return false;
721 };
722 inline friend bool operator==(const long double& r, const Rational& s)
723 {
724 s.rationalErrorMessage();
725 return false;
726 };
727 inline friend bool operator<(const long double& r, const Rational& s)
728 {
729 s.rationalErrorMessage();
730 return false;
731 };
732 inline friend bool operator<=(const long double& r, const Rational& s)
733 {
734 s.rationalErrorMessage();
735 return false;
736 };
737 inline friend bool operator>(const long double& r, const Rational& s)
738 {
739 s.rationalErrorMessage();
740 return false;
741 };
742 inline friend bool operator>=(const long double& r, const Rational& s)
743 {
744 s.rationalErrorMessage();
745 return false;
746 };
747
748 inline friend bool operator!=(const Rational& r, const float& s)
749 {
750 r.rationalErrorMessage();
751 return false;
752 };
753 inline friend bool operator==(const Rational& r, const float& s)
754 {
755 r.rationalErrorMessage();
756 return false;
757 };
758 inline friend bool operator<(const Rational& r, const float& s)
759 {
760 r.rationalErrorMessage();
761 return false;
762 };
763 inline friend bool operator<=(const Rational& r, const float& s)
764 {
765 r.rationalErrorMessage();
766 return false;
767 };
768 inline friend bool operator>(const Rational& r, const float& s)
769 {
770 r.rationalErrorMessage();
771 return false;
772 };
773 inline friend bool operator>=(const Rational& r, const float& s)
774 {
775 r.rationalErrorMessage();
776 return false;
777 };
778
779 inline friend bool operator!=(const float& r, const Rational& s)
780 {
781 s.rationalErrorMessage();
782 return false;
783 };
784 inline friend bool operator==(const float& r, const Rational& s)
785 {
786 s.rationalErrorMessage();
787 return false;
788 };
789 inline friend bool operator<(const float& r, const Rational& s)
790 {
791 s.rationalErrorMessage();
792 return false;
793 };
794 inline friend bool operator<=(const float& r, const Rational& s)
795 {
796 s.rationalErrorMessage();
797 return false;
798 };
799 inline friend bool operator>(const float& r, const Rational& s)
800 {
801 s.rationalErrorMessage();
802 return false;
803 };
804 inline friend bool operator>=(const float& r, const Rational& s)
805 {
806 s.rationalErrorMessage();
807 return false;
808 };
809
810 inline friend Rational operator+(const double& d, const Rational& r)
811 {
812 r.rationalErrorMessage();
813 return r;
814 };
815 inline friend Rational operator-(const double& d, const Rational& r)
816 {
817 r.rationalErrorMessage();
818 return r;
819 };
820 inline friend Rational operator*(const double& d, const Rational& r)
821 {
822 r.rationalErrorMessage();
823 return r;
824 };
825 inline friend Rational operator/(const double& d, const Rational& r)
826 {
827 r.rationalErrorMessage();
828 return r;
829 };
830
831 inline friend bool operator!=(const Rational& r, const int& s)
832 {
833 r.rationalErrorMessage();
834 return false;
835 };
836 inline friend bool operator==(const Rational& r, const int& s)
837 {
838 r.rationalErrorMessage();
839 return false;
840 };
841 inline friend bool operator<(const Rational& r, const int& s)
842 {
843 r.rationalErrorMessage();
844 return false;
845 };
846 inline friend bool operator<=(const Rational& r, const int& s)
847 {
848 r.rationalErrorMessage();
849 return false;
850 };
851 inline friend bool operator>(const Rational& r, const int& s)
852 {
853 r.rationalErrorMessage();
854 return false;
855 };
856 inline friend bool operator>=(const Rational& r, const int& s)
857 {
858 r.rationalErrorMessage();
859 return false;
860 };
861
862 inline friend bool operator!=(const int& r, const Rational& s)
863 {
864 s.rationalErrorMessage();
865 return false;
866 };
867 inline friend bool operator==(const int& r, const Rational& s)
868 {
869 s.rationalErrorMessage();
870 return false;
871 };
872 inline friend bool operator<(const int& r, const Rational& s)
873 {
874 s.rationalErrorMessage();
875 return false;
876 };
877 inline friend bool operator<=(const int& r, const Rational& s)
878 {
879 s.rationalErrorMessage();
880 return false;
881 };
882 inline friend bool operator>(const int& r, const Rational& s)
883 {
884 s.rationalErrorMessage();
885 return false;
886 };
887 inline friend bool operator>=(const int& r, const Rational& s)
888 {
889 s.rationalErrorMessage();
890 return false;
891 };
892
893 inline friend Rational operator+(const int& d, const Rational& r)
894 {
895 r.rationalErrorMessage();
896 return r;
897 };
898 inline friend Rational operator-(const int& d, const Rational& r)
899 {
900 r.rationalErrorMessage();
901 return r;
902 };
903 inline friend Rational operator*(const int& d, const Rational& r)
904 {
905 r.rationalErrorMessage();
906 return r;
907 };
908 inline friend Rational operator/(const int& d, const Rational& r)
909 {
910 r.rationalErrorMessage();
911 return r;
912 };
913
914 inline friend Rational spxAbs(const Rational& r)
915 {
916 r.rationalErrorMessage();
917 return r;
918 };
919 inline friend int sign(const Rational& r)
920 {
921 r.rationalErrorMessage();
922 return 0;
923 };
924 inline friend Rational operator-(const Rational& q)
925 {
926 q.rationalErrorMessage();
927 return q;
928 };///@name Construction and destruction
929 ///@{
930 };
931
932 inline Integer numerator(const Rational& r)
933 {
934 r.rationalErrorMessage();
935 return 0;
936 }
937 inline Integer denominator(const Rational& r)
938 {
939 r.rationalErrorMessage();
940 return 0;
941 }
942 inline Rational ratFromString(const char* desc)
943 {
944 return Rational();
945 }
946 inline void SpxLcm(Integer& result, Integer a, Integer b) {}
947 inline void SpxGcd(Integer& result, Integer a, Integer b) {}
948 inline void divide_qr(Integer& result, Integer& result2, Integer a, Integer b) {}
949 inline void invert(Rational& r)
950 {
951 r.rationalErrorMessage();
952 }
953 inline void powRound(Rational& r)
954 {
955 r.rationalErrorMessage();
956 }
957 #endif
958
959 namespace soplex
960 {
961
962 /// Size in specified base (bit size for base 2)
963 inline int sizeInBase(const Rational R, const int base)
964 {
965 #ifndef SOPLEX_WITH_BOOST
966 MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
967 return 0;
968 #else
969
970 if(R == Rational(0))
971 return 3;
972
973 Integer num = numerator(R);
974 Integer den = denominator(R);
975 size_t numsize, densize;
976
977 #ifdef SOPLEX_WITH_GMP
978 densize = mpz_sizeinbase(den.backend().data(), base);
979 numsize = mpz_sizeinbase(num.backend().data(), base);
980 #else
981
982 if(base != 2)
983 {
984 densize = (size_t)(log2(den.convert_to<double>()) / log2(double(base))) + 1;
985 numsize = (size_t)(log2(num.convert_to<double>()) / log2(double(base))) + 1;
986 }
987 else
988 {
989 densize = msb(den) + 1;
990 numsize = msb(num) + 1;
991 }
992
993 #endif
994
995 return (int)(densize + numsize);
996 #endif
997 }
998 /// Total size of rational vector.
999 inline int totalSizeRational(const Rational* vector, const int length, const int base)
1000 {
1001 assert(vector != 0);
1002 assert(length >= 0);
1003 assert(base >= 0);
1004
1005 int size = 0;
1006
1007 for(int i = 0; i < length; i++)
1008 size += sizeInBase(vector[i], base);
1009
1010 return size;
1011 }
1012
1013 /// Size of least common multiple of denominators in rational vector.
1014 inline int dlcmSizeRational(const Rational* vector, const int length, const int base)
1015 {
1016 assert(vector != 0);
1017 assert(length >= 0);
1018
1019 #ifndef SOPLEX_WITH_BOOST
1020 MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
1021 return 0;
1022 #else
1023
1024 Integer lcm = 1;
1025
1026 for(int i = 0; i < length; i++)
1027 SpxLcm(lcm, lcm, denominator(vector[i]));
1028
1029 int size = sizeInBase(Rational(lcm), base) + 1;
1030
1031 return size;
1032 #endif
1033 }
1034
1035 /// Size of largest denominator in rational vector.
1036 inline int dmaxSizeRational(const Rational* vector, const int length, const int base)
1037 {
1038 assert(vector != 0);
1039 assert(length >= 0);
1040 #ifndef SOPLEX_WITH_BOOST
1041 MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
1042 return 0;
1043 #else
1044
1045 size_t dmax = 0;
1046
1047 for(int i = 0; i < length; i++)
1048 {
1049 size_t dsize = sizeInBase(Rational(denominator(vector[i])), base) + 1;
1050
1051 if(dsize > dmax)
1052 dmax = dsize;
1053 }
1054
1055 return (int)dmax;
1056 #endif
1057 }
1058
1059 } // namespace soplex
1060 #endif
1061 //}
1062