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