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