Scippy

    SCIP

    Solving Constraint Integer Programs

    rational.cpp
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-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 SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file rational.cpp
    26 * @ingroup OTHER_CFILES
    27 * @brief wrapper for rational number arithmetic
    28 * @author Leon Eifler
    29 * @author Dominik Kamp
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    35#include "scip/rational.h"
    36#include "scip/rationalgmp.h"
    39#include "scip/type_message.h"
    40#include "scip/type_retcode.h"
    41#include "scip/type_rational.h"
    42#include "scip/pub_message.h"
    43#include "scip/pub_misc.h"
    44#include "scip/intervalarith.h"
    45#include "scip/set.h"
    46#include <iostream>
    47#include <time.h>
    48#include <stdlib.h>
    49#include <numeric>
    50#include <string.h>
    51#include <algorithm>
    52
    53#ifdef SCIP_WITH_MPFR
    54#include <mpfr.h>
    55#endif
    56
    57#ifdef SCIP_WITH_BOOST
    58#include <boost/format.hpp>
    59#ifdef SCIP_WITH_GMP
    60#include <boost/multiprecision/gmp.hpp>
    61#endif
    62#include <boost/multiprecision/number.hpp>
    63#else
    64using namespace scip;
    65#endif
    66
    67/** print SCIP_RATIONAL to output stream */
    68std::ostream& operator<<(
    69 std::ostream& os, /**< output stream */
    70 SCIP_RATIONAL const & r /**< rational to print */
    71 )
    72{
    73 if( r.isinf )
    74 os << (r.val.sign() > 0 ? "+" : "-") << "infinity";
    75 else
    76 os << r.val;
    77
    78 return os;
    79}
    80
    81extern "C" {
    82
    83#ifdef SCIP_THREADSAFE
    84constexpr static SCIP_Real infinity = SCIP_DEFAULT_INFINITY; /* values above this are considered to be infinite */
    85#else
    86static SCIP_Real infinity = SCIP_DEFAULT_INFINITY; /* values above this are considered to be infinite */
    87#endif
    88
    89/*
    90 * Creation methods
    91 */
    92
    93/** allocate and create a rational from nominator and denominator using ordinary memory */
    95 SCIP_RATIONAL** rational /**< pointer to the rational to create */
    96 )
    97{
    98 SCIP_ALLOC( BMSallocMemory(rational) );
    99
    100 new (&(*rational)->val) scip::Rational(0.0);
    101 (*rational)->isinf = FALSE;
    102 (*rational)->isfprepresentable = SCIP_ISFPREPRESENTABLE_TRUE;
    103
    104 return SCIP_OKAY;
    105}
    106
    107/** allocate and create a rational from nominator and denominator using block memory */
    109 BMS_BLKMEM* blkmem, /**< block memory */
    110 SCIP_RATIONAL** rational /**< pointer to the rational to create */
    111 )
    112{
    113 SCIP_ALLOC( BMSallocBlockMemory(blkmem, rational) );
    114
    115 new (&(*rational)->val) scip::Rational(0.0);
    116 (*rational)->isinf = FALSE;
    117 (*rational)->isfprepresentable = SCIP_ISFPREPRESENTABLE_TRUE;
    118
    119 return SCIP_OKAY;
    120}
    121
    122/** allocate and create a rational from nominator and denominator using buffer memory */
    124 BMS_BUFMEM* bufmem, /**< buffer memory */
    125 SCIP_RATIONAL** rational /**< pointer to the rational to create */
    126 )
    127{
    128 BMSallocBufferMemory(bufmem, rational);
    129
    130 new (&(*rational)->val) scip::Rational(0.0);
    131 (*rational)->isinf = FALSE;
    132 (*rational)->isfprepresentable = SCIP_ISFPREPRESENTABLE_TRUE;
    133
    134 return SCIP_OKAY;
    135}
    136
    137/** creates a copy of a rational using ordinary memory */
    139 SCIP_RATIONAL** result, /**< pointer to the rational to create */
    140 SCIP_RATIONAL* src /**< rational to copy */
    141 )
    142{
    143 SCIP_CALL( SCIPrationalCreate(result) );
    144
    145 SCIPrationalSetRational(*result, src);
    146
    147 return SCIP_OKAY;
    148}
    149
    150/** creates a copy of a rational using block memory */
    152 BMS_BLKMEM* mem, /**< block memory */
    153 SCIP_RATIONAL** result, /**< pointer to the rational to create */
    154 SCIP_RATIONAL* src /**< rational to copy */
    155 )
    156{
    157 SCIP_CALL( SCIPrationalCreateBlock(mem, result) );
    158
    159 SCIPrationalSetRational(*result, src);
    160
    161 return SCIP_OKAY;
    162}
    163
    164/** creates a copy of a rational using buffer memory */
    166 BMS_BUFMEM* bufmem, /**< buffer memory */
    167 SCIP_RATIONAL** result, /**< pointer to the rational to create */
    168 SCIP_RATIONAL* src /**< rational to copy */
    169 )
    170{
    171 SCIP_CALL( SCIPrationalCreateBuffer(bufmem, result) );
    172
    173 SCIPrationalSetRational(*result, src);
    174
    175 return SCIP_OKAY;
    176}
    177
    178/** create an array of rationals using ordinary memory */
    180 SCIP_RATIONAL*** rational, /**< pointer to the array to create */
    181 int size /**< the size of the array */
    182 )
    183{
    184 BMSallocMemoryArray(rational, size);
    185
    186 for( int i = 0; i < size; ++i )
    187 {
    188 SCIP_CALL( SCIPrationalCreate(&(*rational)[i]) );
    189 (*rational)[i]->isfprepresentable = SCIP_ISFPREPRESENTABLE_TRUE;
    190 }
    191
    192 return SCIP_OKAY;
    193}
    194
    195/** create an array of rationals using block memory */
    197 BMS_BLKMEM* mem, /**< block memory */
    198 SCIP_RATIONAL*** rational, /**< pointer to the array to create */
    199 int size /**< the size of the array */
    200 )
    201{
    202 BMSallocBlockMemoryArray(mem, rational, size);
    203
    204 for( int i = 0; i < size; ++i )
    205 {
    206 SCIP_CALL( SCIPrationalCreateBlock(mem, &(*rational)[i]) );
    207 (*rational)[i]->isfprepresentable = SCIP_ISFPREPRESENTABLE_TRUE;
    208 }
    209
    210 return SCIP_OKAY;
    211}
    212
    213/** create an array of rationals using buffer memory */
    215 BMS_BUFMEM* mem, /**< block memory */
    216 SCIP_RATIONAL*** rational, /**< pointer to the arrat to create */
    217 int size /**< the size of the array */
    218 )
    219{
    220 BMSallocBufferMemoryArray(mem, rational, size);
    221
    222 for( int i = 0; i < size; ++i )
    223 {
    224 SCIP_CALL( SCIPrationalCreateBuffer(mem, &(*rational)[i]) );
    225 (*rational)[i]->isfprepresentable = SCIP_ISFPREPRESENTABLE_TRUE;
    226 }
    227
    228 return SCIP_OKAY;
    229}
    230
    231/** copy an array of rationals using ordinary memory */
    233 SCIP_RATIONAL*** target, /**< address to copy to */
    234 SCIP_RATIONAL** src, /**< src array */
    235 int len /**< size of src array */
    236 )
    237{
    238 BMSduplicateMemoryArray(target, src, len);
    239
    240 for( int i = 0; i < len; ++i )
    241 {
    242 SCIP_CALL( SCIPrationalCopy(&(*target)[i], src[i]) );
    243 }
    244
    245 return SCIP_OKAY;
    246}
    247
    248/** copy an array of rationals using block memory */
    250 BMS_BLKMEM* mem, /**< block memory */
    251 SCIP_RATIONAL*** target, /**< address to copy to */
    252 SCIP_RATIONAL** src, /**< src array */
    253 int len /**< size of src array */
    254 )
    255{
    256 BMSduplicateBlockMemoryArray(mem, target, src, len);
    257
    258 for( int i = 0; i < len; ++i )
    259 {
    260 SCIP_CALL( SCIPrationalCopyBlock(mem, &(*target)[i], src[i]) );
    261 }
    262
    263 return SCIP_OKAY;
    264}
    265
    266/** copy an array of rationals using buffer memory */
    268 BMS_BUFMEM* mem, /**< buffer memory */
    269 SCIP_RATIONAL*** result, /**< address to copy to */
    270 SCIP_RATIONAL** src, /**< src array */
    271 int len /**< size of src array */
    272 )
    273{
    274 BMSduplicateBufferMemoryArray(mem, result, src, len);
    275
    276 for( int i = 0; i < len; ++i )
    277 {
    278 SCIP_CALL( SCIPrationalCopyBuffer(mem, &(*result)[i], src[i]) );
    279 }
    280
    281 return SCIP_OKAY;
    282}
    283
    284/** realloc a rational ordinary arrray */
    286 SCIP_RATIONAL*** result, /**< address to copy to */
    287 int oldlen, /**< size of src array */
    288 int newlen /**< size of src array */
    289 )
    290{
    291 if( newlen < oldlen )
    292 {
    293 for( int i = oldlen - 1; i >= newlen; --i )
    294 {
    295 SCIPrationalFree(*result + i);
    296 }
    297
    298 SCIP_ALLOC( BMSreallocMemoryArray(result, newlen) );
    299 }
    300 else
    301 {
    302 SCIP_ALLOC( BMSreallocMemoryArray(result, newlen) );
    303
    304 for( int i = oldlen; i < newlen; ++i )
    305 {
    306 SCIP_CALL( SCIPrationalCreate(*result + i) );
    307 }
    308 }
    309
    310 return SCIP_OKAY;
    311}
    312
    313/** realloc a rational buffer arrray */
    315 BMS_BUFMEM* mem, /**< buffer memory */
    316 SCIP_RATIONAL*** result, /**< address to copy to */
    317 int oldlen, /**< size of src array */
    318 int newlen /**< size of src array */
    319 )
    320{
    321 if( newlen < oldlen )
    322 {
    323 for( int i = oldlen - 1; i >= newlen; --i )
    324 {
    325 SCIPrationalFreeBuffer(mem, *result + i);
    326 }
    327
    328 SCIP_ALLOC( BMSreallocBufferMemoryArray(mem, result, newlen) );
    329 }
    330 else
    331 {
    332 SCIP_ALLOC( BMSreallocBufferMemoryArray(mem, result, newlen) );
    333
    334 for( int i = oldlen; i < newlen; ++i )
    335 {
    336 SCIP_CALL( SCIPrationalCreateBuffer(mem, *result + i) );
    337 }
    338 }
    339
    340 return SCIP_OKAY;
    341}
    342
    343/** realloc a rational block arrray */
    345 BMS_BLKMEM* mem, /**< block memory */
    346 SCIP_RATIONAL*** result, /**< address to copy to */
    347 int oldlen, /**< size of src array */
    348 int newlen /**< size of src array */
    349 )
    350{
    351 if( newlen < oldlen )
    352 {
    353 for( int i = oldlen - 1; i >= newlen; --i )
    354 {
    355 SCIPrationalFreeBlock(mem, *result + i);
    356 }
    357
    358 SCIP_ALLOC( BMSreallocBlockMemoryArray(mem, result, oldlen, newlen) );
    359 }
    360 else
    361 {
    362 SCIP_ALLOC( BMSreallocBlockMemoryArray(mem, result, oldlen, newlen) );
    363
    364 for( int i = oldlen; i < newlen; ++i )
    365 {
    366 SCIP_CALL( SCIPrationalCreateBlock(mem, *result + i) );
    367 }
    368 }
    369
    370 return SCIP_OKAY;
    371}
    372
    373#if defined(SCIP_WITH_BOOST) && defined(SCIP_WITH_GMP)
    374/** gets the underlying gmp rational pointer */
    375mpq_t* SCIPrationalGetGMP(
    376 SCIP_RATIONAL* rational /**< rational to access */
    377 )
    378{
    379 assert(rational != nullptr);
    380 assert(!rational->isinf);
    381
    382 return &(rational->val.backend().data());
    383}
    384
    385/** sets rational to gmp rational */
    386void SCIPrationalSetGMP(
    387 SCIP_RATIONAL* rational, /**< rational to define */
    388 const mpq_t numb /**< gmp rational to set */
    389 )
    390{
    391 rational->val = numb;
    394}
    395
    396/** creates rational from gmp rational */
    397SCIP_RETCODE SCIPrationalCreateBlockGMP(
    398 BMS_BLKMEM* mem, /**< block memory */
    399 SCIP_RATIONAL** rational, /**< pointer to the rational to create */
    400 mpq_t numb /**< gmp rational to set */
    401 )
    402{
    403 SCIP_CALL( SCIPrationalCreateBlock(mem, rational) );
    404 SCIPrationalSetGMP(*rational, numb);
    405
    406 return SCIP_OKAY;
    407}
    408
    409/** sets gmp rational array to values of rational array */
    410void SCIPrationalSetGMPArray(
    411 mpq_t* mpqaaray, /**< gmp rational array */
    412 SCIP_RATIONAL** ratarrray, /**< rational array */
    413 int len /**< array length */
    414 )
    415{
    416 for( int i = 0; i < len; i++ )
    417 {
    418 mpq_init(mpqaaray[i]);
    419 mpq_set(mpqaaray[i], *SCIPrationalGetGMP(ratarrray[i]));
    420 }
    421}
    422
    423/** sets rational array to values of gmp rational array */
    424void SCIPrationalSetArrayGMP(
    425 SCIP_RATIONAL** ratarray, /**< rational array */
    426 mpq_t* mpqarray, /**< gmp rational array */
    427 int len /**< array length */
    428 )
    429{
    430 for( int i = 0; i < len; i++ )
    431 {
    432 SCIPrationalSetGMP(ratarray[i], mpqarray[i]);
    433 }
    434}
    435
    436/** clears gmp rational array */
    437void SCIPrationalClearArrayGMP(
    438 mpq_t* mpqarray, /**< gmp rational array */
    439 int len /**< array length */
    440 )
    441{
    442 for( int i = 0; i < len; i++ )
    443 {
    444 mpq_clear(mpqarray[i]);
    445 }
    446}
    447#endif
    448
    449/** delete a rational and free the allocated ordinary memory */
    451 SCIP_RATIONAL** rational /**< address of the rational */
    452 )
    453{
    454 assert(*rational != nullptr);
    455
    456 (*rational)->val.scip::Rational::~Rational();
    457 BMSfreeMemory(rational);
    458}
    459
    460/** delete a rational and free the allocated block memory */
    462 BMS_BLKMEM* mem, /**< block memory */
    463 SCIP_RATIONAL** rational /**< address of the rational */
    464 )
    465{
    466 assert(*rational != nullptr);
    467
    468 (*rational)->val.scip::Rational::~Rational();
    469 BMSfreeBlockMemory(mem, rational);
    470}
    471
    472/** delete a rational and free the allocated buffer memory */
    474 BMS_BUFMEM* bufmem, /**< buffer memory */
    475 SCIP_RATIONAL** rational /**< address of the rational */
    476 )
    477{
    478 assert(*rational != nullptr);
    479
    480 (*rational)->val.scip::Rational::~Rational();
    481 BMSfreeBufferMemory(bufmem, rational);
    482}
    483
    484/** deletes an array of rationals and frees the allocated ordinary memory */
    486 SCIP_RATIONAL*** ratarray, /**< pointer to the array */
    487 int size /**< size of the array */
    488 )
    489{
    490 assert(ratarray != nullptr);
    491
    492 for( int i = 0; i < size; ++i )
    493 {
    494 SCIPrationalFree(&((*ratarray)[i]));
    495 }
    496
    497 BMSfreeMemoryArrayNull(ratarray);
    498}
    499
    500/** deletes an array of rationals and frees the allocated block memory */
    502 BMS_BLKMEM* mem, /**< block memory */
    503 SCIP_RATIONAL*** ratblockarray, /**< pointer to the array */
    504 int size /**< size of the array */
    505 )
    506{
    507 assert(ratblockarray != nullptr);
    508
    509 for( int i = 0; i < size; ++i )
    510 {
    511 SCIPrationalFreeBlock(mem, &((*ratblockarray)[i]));
    512 }
    513
    514 BMSfreeBlockMemoryArrayNull(mem, ratblockarray, size);
    515}
    516
    517/** deletes an array of rationals and frees the allocated buffer memory */
    519 BMS_BUFMEM* mem, /**< buffer memory */
    520 SCIP_RATIONAL*** ratbufarray, /**< pointer to the array */
    521 int size /**< size of the array */
    522 )
    523{
    524 assert(ratbufarray != nullptr);
    525
    526 for( int i = size - 1; i >= 0; --i )
    527 {
    528 SCIPrationalFreeBuffer(mem, &((*ratbufarray)[i]));
    529 }
    530
    531 BMSfreeBufferMemoryArrayNull(mem, ratbufarray);
    532}
    533
    534/** transforms rational into canonical form
    535 *
    536 * @todo extend this method to work with cpp_rational
    537 */
    539 SCIP_RATIONAL* rational /**< rational to put in canonical form */
    540 )
    541{
    542 assert(rational != nullptr);
    543#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_BOOST)
    544 mpq_canonicalize(rational->val.backend().data());
    545#endif
    546}
    547
    548/** checks if the underlying rational has a value >= infinity;
    549 *
    550 * needed after underlying value was directly set, e.g. by exact lp solver
    551 */
    553 SCIP_RATIONAL* rational /**< rational number */
    554 )
    555{
    556 if( rational->val * rational->val.sign() >= infinity )
    557 {
    558 rational->val = rational->val.sign();
    559 rational->isinf = TRUE;
    561 }
    562 else
    563 {
    564 rational->isinf = FALSE;
    565 }
    566}
    567
    568/** set a rational to the value of another rational */
    570 SCIP_RATIONAL* res, /**< the result */
    571 SCIP_RATIONAL* src /**< the src */
    572 )
    573{
    574 assert(res != nullptr);
    575
    576 res->val = src->val;
    577 res->isinf = src->isinf;
    579}
    580
    581/** set a rational to a nom/denom value */
    583 SCIP_RATIONAL* res, /**< the result */
    584 SCIP_Longint nom, /**< the nominator */
    585 SCIP_Longint denom /**< the denominator */
    586 )
    587{
    588 assert(res != nullptr);
    589 assert(denom != 0);
    590
    591 if( denom < 0 )
    592 {
    593 nom *= -1;
    594 denom *= -1;
    595 }
    596
    597 res->val = scip::Rational(nom, denom);
    600}
    601
    602/** set a rational to the value of another a real */
    604 SCIP_RATIONAL* res, /**< the result */
    605 SCIP_Real real /**< real to set from */
    606 )
    607{
    608 assert(res != nullptr);
    609
    610 res->val = real;
    613
    614 assert(SCIPrationalIsEQReal(res, real));
    615}
    616
    617/** sets a rational to positive infinity */
    619 SCIP_RATIONAL* res /**< the result */
    620 )
    621{
    622 assert(res != nullptr);
    623
    624 res->val = 1;
    625 res->isinf = TRUE;
    627}
    628
    629/** sets a rational to negative infinity */
    631 SCIP_RATIONAL* res /**< the result */
    632 )
    633{
    634 assert(res != nullptr);
    635
    636 res->val = -1;
    637 res->isinf = TRUE;
    639}
    640
    641/** resets the flag isfprepresentable to SCIP_ISFPREPRESENTABLE_UNKNOWN */
    643 SCIP_RATIONAL* rat /**< the number to set flag for */
    644 )
    645{
    646 assert(rat != nullptr);
    647
    649}
    650
    651/** checks if a string describes a rational number */
    653 const char* desc /**< string to check */
    654 )
    655{
    656 assert(desc != NULL);
    657
    658 if( *desc == '-' || *desc == '+' )
    659 ++desc;
    660
    661 if( *desc == '\0' || *desc == '/' )
    662 return FALSE;
    663
    664 if( SCIPstrncasecmp(desc, "inf", 3) == 0 )
    665 return TRUE;
    666
    667 desc += strspn(desc, "0123456789");
    668
    669 if( *desc == '\0' )
    670 return TRUE;
    671
    672 /* parse rational format */
    673 if( *desc == '/' )
    674 {
    675 ++desc;
    676
    677 if( *desc == '\0' )
    678 return FALSE;
    679
    680 desc += strspn(desc, "0123456789");
    681 }
    682 /* parse real format */
    683 else
    684 {
    685 if( *desc == '.' )
    686 {
    687 size_t mantissalen;
    688
    689 ++desc;
    690 mantissalen = strspn(desc, "0123456789");
    691
    692 if( mantissalen == 0 )
    693 return FALSE;
    694
    695 desc += mantissalen;
    696 }
    697
    698 if( *desc == 'e' || *desc == 'E' )
    699 {
    700 ++desc;
    701
    702 if( *desc == '-' || *desc == '+' )
    703 ++desc;
    704
    705 if( *desc == '\0' )
    706 return FALSE;
    707
    708 desc += strspn(desc, "0123456789");
    709 }
    710 }
    711
    712 return (SCIP_Bool) (*desc == '\0');
    713}
    714
    715/** sets a rational to the value described by a string */
    717 SCIP_RATIONAL* res, /**< the result */
    718 const char* desc /**< the string describing the rational */
    719 )
    720{
    721 bool negative;
    722
    723 assert(res != NULL);
    724 assert(desc != NULL);
    725
    726 switch( *desc )
    727 {
    728 case '-':
    729 ++desc;
    730 negative = true;
    731 break;
    732 case '+':
    733 ++desc;
    734 /*lint -fallthrough*/
    735 default:
    736 negative = false;
    737 break;
    738 }
    739
    740 if( SCIPstrncasecmp(desc, "inf", 3) == 0 )
    741 {
    742 res->val = negative ? -1 : 1;
    743 res->isinf = TRUE;
    745 }
    746 else
    747 {
    748 std::string s(desc);
    749 size_t exponentidx = s.find_first_of("eE");
    750 int exponent = 0;
    751
    752 /* split into decimal and power */
    753 if( exponentidx != std::string::npos )
    754 {
    755 exponent = std::stoi(s.substr(exponentidx + 1, s.length()));
    756 s.resize(exponentidx);
    757 }
    758
    759 /* convert decimal into fraction */
    760 if( s.find('.') != std::string::npos )
    761 {
    762 SCIPdebug(std::cout << s << std::endl);
    763
    764 if( s[0] == '.' )
    765 (void) s.insert(0, "0");
    766
    767 /* transform decimal into fraction */
    768 size_t decimalpos = s.find('.');
    769 size_t exponentpos = s.length() - 1 - decimalpos;
    770 std::string denominator("1");
    771
    772 if( decimalpos != std::string::npos )
    773 {
    774 for( size_t i = 0; i < exponentpos; ++i )
    775 (void) denominator.append("0");
    776
    777 (void) s.erase(decimalpos, 1);
    778 }
    779 assert(std::all_of(s.begin()+1, s.end(), ::isdigit));
    780
    781 if( s[0] == '+' )
    782 s = s.substr(1);
    783
    784 (void) s.append("/");
    785 (void) s.append(denominator);
    786 }
    787
    788 res->val = negative ? -scip::Rational(s) : scip::Rational(s);
    789 res->val *= pow(10, exponent);
    792 }
    793}
    794
    795/** allocates and creates a rational from a string if known, otherwise assigns a null pointer */
    797 BMS_BLKMEM* mem, /**< block memory */
    798 SCIP_RATIONAL** rational, /**< pointer to the rational to create */
    799 const char* desc /**< the string describing the rational */
    800 )
    801{
    802 assert(rational != NULL);
    803 assert(desc != NULL);
    804
    805 if( SCIPstrncasecmp(desc, "unk", 3) == 0 )
    806 {
    807 *rational = NULL;
    808 return SCIP_OKAY;
    809 }
    810
    811 SCIP_CALL( SCIPrationalCreateBlock(mem, rational) );
    812
    813 SCIPrationalSetString(*rational, desc);
    814
    815 return SCIP_OKAY;
    816}
    817
    818/** extract the next token as a rational value if it is one; in case no value is parsed the endptr is set to @p desc
    819 *
    820 * @return Returns TRUE if a value could be extracted, otherwise FALSE
    821 */
    823 char* desc, /**< string to search */
    824 SCIP_RATIONAL* value, /**< pointer to store the parsed value */
    825 char** endptr /**< pointer to store the final string position if successfully parsed, otherwise @p desc */
    826 )
    827{
    828 bool negative;
    829
    830 assert(desc != NULL);
    831 assert(value != NULL);
    832 assert(endptr != NULL);
    833
    834 *endptr = desc;
    835
    836 switch( *desc )
    837 {
    838 case '-':
    839 ++desc;
    840 negative = true;
    841 break;
    842 case '+':
    843 ++desc;
    844 /*lint -fallthrough*/
    845 default:
    846 negative = false;
    847 break;
    848 }
    849
    850 if( *desc == '\0' || *desc == '/' )
    851 return FALSE;
    852
    853 if( SCIPstrncasecmp(desc, "inf", 3) == 0 )
    854 {
    855 if( negative )
    857 else
    859
    860 *endptr = desc + 2;
    861
    862 if( *(++(*endptr)) == 'i' )
    863 {
    864 if( *(++(*endptr)) == 'n' )
    865 {
    866 if( *(++(*endptr)) == 'i' )
    867 {
    868 if( *(++(*endptr)) == 't' )
    869 {
    870 if( *(++(*endptr)) == 'y' )
    871 ++(*endptr);
    872 }
    873 }
    874 }
    875 }
    876
    877 return TRUE;
    878 }
    879
    880 desc += strspn(desc, "0123456789");
    881
    882 /* parse rational format */
    883 if( *desc == '/' )
    884 {
    885 ++desc;
    886
    887 if( *desc == '\0' )
    888 return FALSE;
    889
    890 desc += strspn(desc, "0123456789");
    891 }
    892 /* parse real format */
    893 else if( *desc != '\0' )
    894 {
    895 if( *desc == '.' )
    896 {
    897 size_t mantissalen;
    898
    899 ++desc;
    900 mantissalen = strspn(desc, "0123456789");
    901
    902 if( mantissalen == 0 )
    903 return FALSE;
    904
    905 desc += mantissalen;
    906 }
    907
    908 if( *desc == 'e' || *desc == 'E' )
    909 {
    910 ++desc;
    911
    912 if( *desc == '-' || *desc == '+' )
    913 ++desc;
    914
    915 if( *desc == '\0' )
    916 return FALSE;
    917
    918 desc += strspn(desc, "0123456789");
    919 }
    920 }
    921
    922 std::string s(*endptr, desc);
    923
    924 SCIPrationalSetString(value, s.c_str());
    925 *endptr = desc;
    926
    927 return TRUE;
    928}
    929
    930/*
    931 * Computing methods
    932 */
    933
    934/** add two rationals and save the result in res */
    936 SCIP_RATIONAL* res, /**< the result */
    937 SCIP_RATIONAL* op1, /**< first operand */
    938 SCIP_RATIONAL* op2 /**< second operand */
    939 )
    940{
    941 assert(res != nullptr && op1 != nullptr && op2 != nullptr);
    942
    943 if( op1->isinf || op2->isinf )
    944 {
    945 SCIPrationalSetRational(res, op1->isinf ? op1 : op2 );
    946 if( op1->val.sign() != op2->val.sign() && op1->isinf && op2->isinf )
    947 {
    948 SCIPerrorMessage("addition of pos and neg infinity not supported \n");
    949 SCIPABORT();
    950 }
    951 }
    952 else
    953 {
    954 res->isinf = FALSE;
    955 res->val = op1->val + op2->val;
    956 }
    958}
    959
    960/** add a rational and a real and save the result in res */
    962 SCIP_RATIONAL* res, /**< the result */
    963 SCIP_RATIONAL* rat, /**< rational number */
    964 SCIP_Real real /**< real number */
    965 )
    966{
    967 assert(res != nullptr && rat != nullptr);
    968 if( rat->isinf )
    969 SCIPrationalSetRational(res, rat);
    970 else if( REALABS(real) >= infinity )
    971 {
    973 }
    974 else
    975 {
    976 res->isinf = FALSE;
    977 res->val = rat->val + real;
    978 }
    980}
    981
    982/*** subtract two rationals and save the result in res */
    984 SCIP_RATIONAL* res, /**< the result */
    985 SCIP_RATIONAL* op1, /**< first operand */
    986 SCIP_RATIONAL* op2 /**< second operand */
    987 )
    988{
    989 assert(res != nullptr && op1 != nullptr && op2 != nullptr);
    990
    991 if( op1->isinf || op2->isinf )
    992 {
    993 op1->isinf ? SCIPrationalSetRational(res, op1) : SCIPrationalNegate(res, op2);
    994 if( op1->val.sign() == op2->val.sign() && op1->isinf && op2->isinf )
    995 {
    996 SCIPerrorMessage("subtraction of two infinities with same sign not supported \n");
    997 SCIPABORT();
    998 }
    999 }
    1000 else
    1001 {
    1002 res->isinf = FALSE;
    1003 res->val = (op1->val) - (op2->val);
    1004 }
    1006}
    1007
    1008/** subtract a rational and a real and save the result in res */
    1010 SCIP_RATIONAL* res, /**< the result */
    1011 SCIP_RATIONAL* rat, /**< rational number */
    1012 SCIP_Real real /**< real number */
    1013 )
    1014{
    1015 assert(res != nullptr && rat != nullptr);
    1016
    1017 SCIPrationalAddReal(res, rat, -real);
    1018}
    1019
    1020/** returns the relative difference: (val1-val2)/max(|val1|,|val2|,1.0)
    1021 *
    1022 * @note this method handles infinity like finite numbers
    1023 */
    1025 SCIP_RATIONAL* res,
    1026 SCIP_RATIONAL* val1, /**< first value to be compared */
    1027 SCIP_RATIONAL* val2 /**< second value to be compared */
    1028 )
    1029{
    1030 scip::Rational absval1;
    1031 scip::Rational absval2;
    1032 scip::Rational quot;
    1033
    1034 assert(res != nullptr && val1 != nullptr && val2 != nullptr);
    1035
    1036 if(val1->isinf)
    1037 {
    1038 if(val2->isinf)
    1039 {
    1040 res->val = SCIPrationalGetSign(val1) == SCIPrationalGetSign(val2) ? 0 : 2 * SCIPrationalGetSign(val1);
    1041 }
    1042 else
    1043 {
    1044 res->val = SCIPrationalGetSign(val1);
    1045 }
    1046 }
    1047 else if(val2->isinf)
    1048 {
    1049 res->val = -SCIPrationalGetSign(val2);
    1050 }
    1051 else
    1052 {
    1053 absval1 = abs(val1->val);
    1054 absval2 = abs(val2->val);
    1055 quot = absval1 >= absval2 ? absval1 : absval2;
    1056 if( quot < 1.0 )
    1057 quot = 1.0;
    1058
    1059 res->val = ((val1->val)-(val2->val))/quot;
    1060 }
    1061
    1063}
    1064
    1065/** multiply two rationals and save the result in res */
    1067 SCIP_RATIONAL* res, /**< the result */
    1068 SCIP_RATIONAL* op1, /**< first operand */
    1069 SCIP_RATIONAL* op2 /**< second operand */
    1070 )
    1071{
    1072 assert(res != nullptr && op1 != nullptr && op2 != nullptr);
    1073
    1074 if( op1->isinf || op2->isinf )
    1075 {
    1076 if( op1->val.is_zero() || op2->val.is_zero() )
    1077 {
    1078 res->val = 0;
    1079 res->isinf = FALSE;
    1080 }
    1081 else
    1082 {
    1083 res->val = op1->val.sign() * op2->val.sign();
    1084 res->isinf = TRUE;
    1085 }
    1086 res->isfprepresentable = TRUE;
    1087 }
    1088 else
    1089 {
    1090 res->val = op1->val * op2->val;
    1091 res->isinf = FALSE;
    1093 }
    1094}
    1095
    1096/** multiplies a rational and a real and saves the result in res */
    1098 SCIP_RATIONAL* res, /**< the result */
    1099 SCIP_RATIONAL* op1, /**< first operand */
    1100 SCIP_Real op2 /**< second operand */
    1101 )
    1102{
    1103 assert(res != nullptr && op1 != nullptr);
    1104
    1105 if( op1->isinf )
    1106 {
    1107 SCIPdebugMessage("multiplying with infinity might produce undesired behavior \n");
    1108 if( op2 == 0.0 )
    1109 {
    1110 res->isinf = FALSE;
    1111 res->val = 0;
    1112 }
    1113 else
    1114 {
    1115 op2 > 0 ? SCIPrationalSetRational(res, op1) : SCIPrationalNegate(res, op1);
    1116 }
    1117 }
    1118 else if( REALABS(op2) >= infinity )
    1119 {
    1120 SCIPrationalSetReal(res, op2 * op1->val.sign());
    1121 }
    1122 else
    1123 {
    1124 res->val = op1->val * op2;
    1125 res->isinf = FALSE;
    1126 }
    1128}
    1129
    1130
    1131/** divides two rationals and saves the result in res */
    1133 SCIP_RATIONAL* res, /**< the result */
    1134 SCIP_RATIONAL* op1, /**< first operand */
    1135 SCIP_RATIONAL* op2 /**< second operand */
    1136 )
    1137{
    1138 assert(res != nullptr && op1 != nullptr && op2 != nullptr);
    1139 assert(!SCIPrationalIsZero(op2));
    1140 assert(!op1->isinf && !op2->isinf);
    1141
    1142 res->val = op1->val / op2->val;
    1144}
    1145
    1146/** divides a rational by a real and saves the result in res */
    1148 SCIP_RATIONAL* res, /**< the result */
    1149 SCIP_RATIONAL* op1, /**< first operand */
    1150 SCIP_Real op2 /**< second operand */
    1151 )
    1152{
    1153 assert(res != nullptr && op1 != nullptr);
    1154 assert(op2 != 0.0);
    1155
    1156 if( op1->isinf )
    1157 {
    1158 op2 > 0 ? SCIPrationalSetRational(res, op1) : SCIPrationalNegate(res, op1);
    1159 }
    1160 else if( REALABS(op2) >= infinity && !SCIPrationalIsZero(op1) )
    1161 {
    1162 SCIPrationalSetReal(res, op2 * op1->val.sign());
    1163 }
    1164 else
    1165 {
    1166 res->val = op1->val / scip::Rational(op2);
    1167 res->isinf = FALSE;
    1168 }
    1170}
    1171
    1172/* Computes res += op1 * op2 and saves the result in res */
    1174 SCIP_RATIONAL* res, /**< the result */
    1175 SCIP_RATIONAL* op1, /**< first operand */
    1176 SCIP_RATIONAL* op2 /**< second operand */
    1177 )
    1178{
    1179 assert(res != nullptr && op1 != nullptr && op2 != nullptr);
    1180
    1181 if( res->isinf && !op1->isinf && !op2->isinf )
    1182 return;
    1183
    1184 if( op1->isinf || op2->isinf )
    1185 {
    1186 if( op1->val.is_zero() || op2->val.is_zero() )
    1187 return;
    1188 else
    1189 {
    1190 if( res->isinf && res->val.sign() != (op1->val.sign() * op2->val.sign()) )
    1191 {
    1192 SCIPerrorMessage("inf - inf leads to undefined behavior \n");
    1193 SCIPABORT();
    1194 }
    1195
    1196 res->val = op1->val.sign() * op2->val.sign();
    1197 res->isinf = TRUE;
    1199 }
    1200 }
    1201 else
    1202 {
    1203 res->isinf = FALSE;
    1204 res->val += op1->val * op2->val;
    1206 }
    1207}
    1208
    1209/* Computes res += op1 * op2 and saves the result in res */
    1211 SCIP_RATIONAL* res, /**< the result */
    1212 SCIP_RATIONAL* op1, /**< first operand */
    1213 SCIP_Real op2 /**< second operand */
    1214 )
    1215{
    1216 assert(res != nullptr && op1 != nullptr);
    1217 assert(!res->isinf);
    1218
    1219 if( op1->isinf )
    1220 {
    1221 if( op2 == 0.0 )
    1222 return;
    1223 else
    1224 {
    1225 res->val = (op2 > 0) ? op1->val.sign() : -op1->val.sign();
    1226 res->isinf = TRUE;
    1228 }
    1229 }
    1230 else
    1231 {
    1232 res->isinf = FALSE;
    1233 res->val += op1->val * op2;
    1235 }
    1236}
    1237
    1238/* Computes res -= op1 * op2 and saves the result in res */
    1240 SCIP_RATIONAL* res, /**< the result */
    1241 SCIP_RATIONAL* op1, /**< first operand */
    1242 SCIP_RATIONAL* op2 /**< second operand */
    1243 )
    1244{
    1245 assert(res != nullptr && op1 != nullptr && op2 != nullptr);
    1246 assert(!res->isinf);
    1247
    1248 if( op1->isinf || op2->isinf )
    1249 {
    1250 if( op1->val.is_zero() || op2->val.is_zero() )
    1251 return;
    1252 else
    1253 {
    1254 res->val = op1->val.sign() * op2->val.sign();
    1255 res->isinf = TRUE;
    1257 }
    1258 }
    1259 else
    1260 {
    1261 res->isinf = FALSE;
    1262 res->val -= op1->val * op2->val;
    1264 }
    1265}
    1266
    1267/* Computes res += op1 * op2 and saves the result in res */
    1269 SCIP_RATIONAL* res, /**< the result */
    1270 SCIP_RATIONAL* op1, /**< first operand */
    1271 SCIP_Real op2 /**< second operand */
    1272 )
    1273{
    1274 assert(res != nullptr && op1 != nullptr);
    1275 assert(!res->isinf);
    1276
    1277 if( op1->isinf )
    1278 {
    1279 if( op2 == 0 )
    1280 return;
    1281 else
    1282 {
    1283 res->val = (op2 > 0) ? op1->val.sign() : -op1->val.sign();
    1284 res->isinf = TRUE;
    1286 }
    1287 }
    1288 else
    1289 {
    1290 res->isinf = FALSE;
    1291 res->val -= op1->val * op2;
    1293 }
    1294}
    1295
    1296/** set res to -op */
    1298 SCIP_RATIONAL* res, /**< the result */
    1299 SCIP_RATIONAL* op /**< operand */
    1300 )
    1301{
    1302 assert(res != nullptr && op != nullptr);
    1303
    1304 res->val = -op->val;
    1305 res->isinf = op->isinf;
    1307}
    1308
    1309/** set res to Abs(op) */
    1311 SCIP_RATIONAL* res, /**< the result */
    1312 SCIP_RATIONAL* op /**< operand */
    1313 )
    1314{
    1315 assert(res != nullptr && op != nullptr);
    1316
    1317 res->val = abs(op->val);
    1318 res->isinf = op->isinf;
    1320}
    1321
    1322/** set res to 1/op */
    1324 SCIP_RATIONAL* res, /**< the result */
    1325 SCIP_RATIONAL* op /**< operand */
    1326 )
    1327{
    1328 assert(res != nullptr && op != nullptr);
    1329 assert(!op->isinf);
    1330 assert(!op->val.is_zero());
    1331
    1332 res->val = 1 / op->val;
    1333 res->isinf = FALSE;
    1335}
    1336
    1337/*
    1338 * Comparison methods
    1339 */
    1340
    1341/** compute the minimum of two rationals */
    1343 SCIP_RATIONAL* res, /**< the result */
    1344 SCIP_RATIONAL* op1, /**< the first rational */
    1345 SCIP_RATIONAL* op2 /**< the second rational */
    1346 )
    1347{
    1348 assert(op1 != nullptr && op2 != nullptr);
    1349
    1350 if( op1->isinf )
    1351 {
    1352 if( op1->val > 0 )
    1353 SCIPrationalSetRational(res, op2);
    1354 else
    1355 SCIPrationalSetRational(res, op1);
    1356 }
    1357 else if( op2->isinf )
    1358 {
    1359 if( op2->val > 0 )
    1360 SCIPrationalSetRational(res, op1);
    1361 else
    1362 SCIPrationalSetRational(res, op2);
    1363 }
    1364 else
    1365 {
    1366 res->val = op1->val < op2->val ? op1->val : op2->val;
    1367 res->isinf = FALSE;
    1369 }
    1370}
    1371
    1372/** compute the minimum of two rationals */
    1374 SCIP_RATIONAL* res, /**< the result */
    1375 SCIP_RATIONAL* op1, /**< the first rational */
    1376 SCIP_RATIONAL* op2 /**< the second rational */
    1377 )
    1378{
    1379 assert(op1 != nullptr && op2 != nullptr);
    1380
    1381 if( op1->isinf )
    1382 {
    1383 if( op1->val > 0 )
    1384 SCIPrationalSetRational(res, op1);
    1385 else
    1386 SCIPrationalSetRational(res, op2);
    1387 }
    1388 else if( op2->isinf )
    1389 {
    1390 if( op2->val > 0 )
    1391 SCIPrationalSetRational(res, op2);
    1392 else
    1393 SCIPrationalSetRational(res, op1);
    1394 }
    1395 else
    1396 {
    1397 res->val = op1->val >= op2->val ? op1->val : op2->val;
    1398 res->isinf = FALSE;
    1400 }
    1401}
    1402
    1403/** checks if two rationals are equal */
    1405 SCIP_RATIONAL* rat1, /**< the first rational */
    1406 SCIP_RATIONAL* rat2 /**< the second rational */
    1407 )
    1408{
    1409 assert(rat1 != nullptr && rat2 != nullptr);
    1410
    1411 if( rat1->val == rat2->val )
    1412 return (SCIP_Bool)(rat1->isinf == rat2->isinf);
    1413
    1414 if( rat1->isinf && rat2->isinf )
    1415 return (SCIP_Bool)(rat1->val.sign() == rat2->val.sign());
    1416
    1417 return FALSE;
    1418}
    1419
    1420/** checks if two rationals are equal */
    1422 SCIP_RATIONAL* rat1, /**< the first rational */
    1423 SCIP_RATIONAL* rat2 /**< the second rational */
    1424 )
    1425{
    1426 assert(rat1 != nullptr && rat2 != nullptr);
    1427
    1428 if( abs(rat1->val) == abs(rat2->val) )
    1429 return (SCIP_Bool)(rat1->isinf == rat2->isinf);
    1430 if( rat1->isinf && rat2->isinf )
    1431 return TRUE;
    1432
    1433 return FALSE;
    1434}
    1435
    1436/** checks if rational and real are equal */
    1438 SCIP_RATIONAL* rat, /**< the rational */
    1439 SCIP_Real real /**< the real */
    1440 )
    1441{
    1442 assert(rat != nullptr);
    1443
    1444 if( REALABS(real) >= infinity && rat->isinf )
    1445 return (SCIP_Bool) ((real > 0 && SCIPrationalIsPositive(rat)) || (real < 0 && SCIPrationalIsNegative(rat)));
    1446
    1447 return (SCIP_Bool) (!rat->isinf && rat->val == scip::Rational(real));
    1448}
    1449
    1450/** checks if real approx of rational and real are equal */
    1452 SCIP_SET* set, /**< SCIP set pointer */
    1453 SCIP_RATIONAL* rat, /**< the rational */
    1454 SCIP_Real real, /**< the real */
    1455 SCIP_ROUNDMODE_RAT roundmode /**< the rounding mode to use */
    1456 )
    1457{
    1458 assert(rat != nullptr);
    1459
    1460 if( rat->isinf )
    1461 {
    1463 }
    1464 else
    1465 {
    1466 if( roundmode == SCIP_R_ROUND_NEAREST )
    1467 return SCIPsetIsEQ(set, real, SCIPrationalGetReal(rat));
    1468 else
    1469 return SCIPsetIsEQ(set, real, SCIPrationalRoundReal(rat, roundmode));
    1470 }
    1471}
    1472
    1473/** checks if first rational is greater than second rational */
    1475 SCIP_RATIONAL* rat1, /**< the first rational */
    1476 SCIP_RATIONAL* rat2 /**< the second rational */
    1477 )
    1478{
    1479 assert(rat1 != nullptr);
    1480 assert(rat2 != nullptr);
    1481
    1482 if( rat1->isinf )
    1483 {
    1484 if( rat1->val < 0 || ( rat2->isinf && rat2->val > 0 ) )
    1485 return FALSE;
    1486 else
    1487 return TRUE;
    1488 }
    1489 else if( rat2->isinf )
    1490 {
    1491 if( rat2->val > 0 )
    1492 return FALSE;
    1493 else
    1494 return TRUE;
    1495 }
    1496 else
    1497 {
    1498 return (SCIP_Bool)(rat1->val > rat2->val);
    1499 }
    1500}
    1501
    1502/** checks if first rational is smaller than second rational */
    1504 SCIP_RATIONAL* rat1, /**< the first rational */
    1505 SCIP_RATIONAL* rat2 /**< the second rational */
    1506 )
    1507{
    1508 return SCIPrationalIsGT(rat2, rat1);
    1509}
    1510
    1511/** checks if first rational is greater or equal than second rational */
    1513 SCIP_RATIONAL* rat1, /**< the first rational */
    1514 SCIP_RATIONAL* rat2 /**< the second rational */
    1515 )
    1516{
    1517 return (SCIP_Bool) !SCIPrationalIsGT(rat2, rat1);
    1518}
    1519
    1520/** checks if first rational is less or equal than second rational */
    1522 SCIP_RATIONAL* rat1, /**< the first rational */
    1523 SCIP_RATIONAL* rat2 /**< the second rational */
    1524 )
    1525{
    1526 return (SCIP_Bool) !SCIPrationalIsGT(rat1, rat2);
    1527}
    1528
    1529/** checks if first rational is greater than second rational */
    1531 SCIP_RATIONAL* rat1, /**< the first rational */
    1532 SCIP_RATIONAL* rat2 /**< the second rational */
    1533 )
    1534{
    1535 assert(rat1 != nullptr && rat2 != nullptr);
    1536
    1537 if( rat1->isinf && !rat2->isinf )
    1538 return TRUE;
    1539 else if( rat2->isinf )
    1540 return FALSE;
    1541 else
    1542 return (SCIP_Bool) (abs(rat1->val) > abs(rat2->val));
    1543}
    1544
    1545/** checks if rational is greater than real */
    1547 SCIP_RATIONAL* rat, /**< the rational */
    1548 SCIP_Real real /**< the real */
    1549 )
    1550{
    1551 assert(rat != nullptr);
    1552
    1553 if( real >= infinity )
    1554 return FALSE;
    1555 else if( real <= -infinity )
    1556 {
    1557 if( rat->isinf && rat->val < 0 )
    1558 return FALSE;
    1559 else
    1560 return TRUE;
    1561 }
    1562 else if( rat->isinf )
    1563 {
    1564 if( rat->val < 0 )
    1565 return FALSE;
    1566 else
    1567 return TRUE;
    1568 }
    1569 else
    1570 {
    1571 return (SCIP_Bool) (rat->val > real);
    1572 }
    1573}
    1574
    1575/** checks if rational is less than real */
    1577 SCIP_RATIONAL* rat, /**< the rational */
    1578 SCIP_Real real /**< the real */
    1579 )
    1580{
    1581 assert(rat != nullptr);
    1582
    1583 if( real <= -infinity )
    1584 return FALSE;
    1585 else if( real >= infinity )
    1586 {
    1587 if( rat->isinf && rat->val > 0 )
    1588 return FALSE;
    1589 else
    1590 return TRUE;
    1591 }
    1592 else if( rat->isinf )
    1593 {
    1594 if( rat->val > 0 )
    1595 return FALSE;
    1596 else
    1597 return TRUE;
    1598 }
    1599 else
    1600 {
    1601 return (SCIP_Bool) (rat->val < real);
    1602 }
    1603}
    1604
    1605/** checks if rational is greater or equal than real */
    1607 SCIP_RATIONAL* rat, /**< the rational */
    1608 SCIP_Real real /**< the real */
    1609 )
    1610{
    1611 return (SCIP_Bool) !SCIPrationalIsLTReal(rat, real);
    1612}
    1613
    1614/** checks if rational is less or equal than real */
    1616 SCIP_RATIONAL* rat, /**< the rational */
    1617 SCIP_Real real /**< the real */
    1618 )
    1619{
    1620 return (SCIP_Bool) !SCIPrationalIsGTReal(rat, real);
    1621}
    1622
    1623/** checks if rational is zero */
    1625 SCIP_RATIONAL* rational /**< the rational to check */
    1626 )
    1627{
    1628 assert(rational != nullptr);
    1629
    1630 if( rational->val.is_zero() )
    1631 {
    1632 assert(!rational->isinf);
    1633 return TRUE;
    1634 }
    1635 else
    1636 return FALSE;
    1637}
    1638
    1639/** checks if rational is positive */
    1641 SCIP_RATIONAL* rational /**< the rational to check */
    1642 )
    1643{
    1644 assert(rational != nullptr);
    1645
    1646 return (SCIP_Bool) (rational->val.sign() > 0);
    1647}
    1648
    1649/** checks if rational is negative */
    1651 SCIP_RATIONAL* rational /**< the rational to check */
    1652 )
    1653{
    1654 assert(rational != nullptr);
    1655
    1656 return (SCIP_Bool) (rational->val.sign() < 0);
    1657}
    1658
    1659/** checks if rational is positive infinity */
    1661 SCIP_RATIONAL* rational /**< the rational to check */
    1662 )
    1663{
    1664 assert(rational != nullptr);
    1665
    1666 return (SCIP_Bool) (rational->isinf && rational->val.sign() > 0);
    1667}
    1668
    1669/** checks if rational is negative infinity */
    1671 SCIP_RATIONAL* rational /**< the rational to check */
    1672 )
    1673{
    1674 assert(rational != nullptr);
    1675
    1676 return (SCIP_Bool) (rational->isinf && rational->val.sign() < 0);
    1677}
    1678
    1679/** checks if rational is negative infinity */
    1681 SCIP_RATIONAL* rational /**< the rational to check */
    1682 )
    1683{
    1684 assert(rational != nullptr);
    1685 assert(!rational->val.is_zero() || !rational->isinf);
    1686
    1687 return rational->isinf;
    1688}
    1689
    1690/** checks if rational is integral */
    1692 SCIP_RATIONAL* rational /**< the rational to check */
    1693 )
    1694{
    1695 assert(rational != nullptr);
    1696 if( rational->isinf )
    1697 return TRUE;
    1698 else if( denominator(rational->val) == 1 )
    1699 return TRUE;
    1700 else if( numerator(rational->val) < denominator(rational->val) )
    1701 return FALSE;
    1702 else
    1703 {
    1704 SCIPrationalCanonicalize(rational);
    1705 return (SCIP_Bool) (denominator(rational->val) == 1);
    1706 }
    1707}
    1708
    1709/** checks if rational is exactly representable as real */
    1711 SCIP_RATIONAL* rational /**< the rational to check */
    1712 )
    1713{
    1714 assert(rational != nullptr);
    1716 {
    1718 return TRUE;
    1719 }
    1720 else if( rational->isfprepresentable == SCIP_ISFPREPRESENTABLE_FALSE )
    1721 {
    1722 return FALSE;
    1723 }
    1724 else
    1725 {
    1728 }
    1729
    1731}
    1732
    1733/*
    1734 * Printing/Conversion methods
    1735 */
    1736
    1737/** converts a rational to a string for printing, returns the number of copied characters.
    1738 *
    1739 * @return number of characters printed into string, see also SCIPstrncpy()
    1740 *
    1741 * @note If return value is equal to strlen, it means the string was truncated.
    1742 */
    1744 SCIP_RATIONAL* rational, /**< the rational to print */
    1745 char* str, /**< the string to save the rational in */
    1746 int strlen /**< maximal length that can be copied to str */
    1747 )
    1748{
    1749 int ret = 0;
    1750
    1751 if( rational == NULL )
    1752 ret = SCIPstrncpy(str, "unknown", strlen);
    1753 else if( rational->isinf )
    1754 {
    1755 if( rational->val.sign() > 0 )
    1756 ret = SCIPstrncpy(str, "+infinity", strlen);
    1757 else
    1758 ret = SCIPstrncpy(str, "-infinity", strlen);
    1759 }
    1760 else
    1761 {
    1762 std::string s = rational->val.str();
    1763 ret = SCIPstrncpy(str, s.c_str(), strlen);
    1764 }
    1765 if( ret == strlen )
    1766 {
    1767 SCIPrationalDebugMessage("Rational string too long to fit in buffer. Rational : %q \n", rational);
    1768 }
    1769
    1770 return ret;
    1771}
    1772
    1773/** returns the strlen of a rational number */
    1775 SCIP_RATIONAL* rational /** rational to consider */
    1776 )
    1777{
    1778 /* unknown */
    1779 if( rational == NULL )
    1780 return 7;
    1781 /* +-infinity */
    1782 else if( rational->isinf )
    1783 return 9;
    1784 /* quotient */
    1785 else
    1786 return (int) rational->val.str().length();
    1787}
    1788
    1789/** prints rational into a file using message handler */
    1791 SCIP_MESSAGEHDLR* msg, /**< message handler */
    1792 FILE* file, /**< file pointer */
    1793 SCIP_RATIONAL* rational /**< the rational to print */
    1794 )
    1795{
    1796 if( rational == NULL )
    1797 SCIPmessageFPrintInfo(msg, file, "unknown");
    1798 else if( rational->isinf )
    1799 {
    1800 if( rational->val.sign() > 0 )
    1801 SCIPmessageFPrintInfo(msg, file, "+infinity");
    1802 else
    1803 SCIPmessageFPrintInfo(msg, file, "-infinity");
    1804 }
    1805 else
    1806 {
    1807 std::string s = rational->val.str();
    1808 SCIPmessageFPrintInfo(msg, file, "%s", s.c_str());
    1809 }
    1810}
    1811
    1812/** prints rational depending on the verbosity level */
    1814 SCIP_MESSAGEHDLR* msg, /**< message handler */
    1815 SCIP_VERBLEVEL verblevel, /**< current verbosity level */
    1816 SCIP_VERBLEVEL msgverblevel, /**< verbosity level of this message */
    1817 SCIP_RATIONAL* rational /**< the rational to print */
    1818 )
    1819{
    1820 assert(msgverblevel > SCIP_VERBLEVEL_NONE);
    1821 assert(msgverblevel <= SCIP_VERBLEVEL_FULL);
    1822 assert(verblevel <= SCIP_VERBLEVEL_FULL);
    1823
    1824 if( msgverblevel <= verblevel )
    1825 {
    1826 SCIPrationalMessage(msg, NULL, rational);
    1827 }
    1828}
    1829
    1830/** print a rational to command line (for debugging) */
    1832 SCIP_RATIONAL* rational /**< the rational to print */
    1833 )
    1834{
    1835 if( rational == NULL )
    1836 std::cout << "unknown" << std::flush;
    1837 else if( rational->isinf )
    1838 std::cout << (rational->val.sign() > 0 ? "+" : "-") << "infinity" << std::flush;
    1839 else
    1840 std::cout << rational->val << std::flush;
    1841}
    1842
    1843/** printf extension for rationals (not supporting all format options) */
    1844static
    1846 const char* formatstr, /**< format string like in printf() function */
    1847 va_list ap /**< variable argument list */
    1848 )
    1849{
    1850 SCIP_RATIONAL* rat;
    1851 char* sval;
    1852 SCIP_Real dval;
    1853 int ival;
    1854 SCIP_Longint lval;
    1855 char cval;
    1856 void* pval;
    1857 va_list arguments;
    1858
    1859 va_copy(arguments, ap); /*lint !e838*/
    1860 while( *formatstr != '\0' )
    1861 {
    1862 if( *formatstr == '%' && *(formatstr+1) != '%' )
    1863 {
    1864 switch( *++formatstr )
    1865 {
    1866 case 'q':
    1867 rat = va_arg(arguments, SCIP_RATIONAL*);
    1868 SCIPrationalPrint(rat);
    1869 break;
    1870 case 's':
    1871 for( sval = va_arg(arguments, char *); *sval; sval++ )
    1872 (void) putchar(*sval);
    1873 break;
    1874 case 'f':
    1875 dval = va_arg(arguments, SCIP_Real);
    1876 printf("%f", dval);
    1877 break;
    1878 case 'g':
    1879 dval = va_arg(arguments, SCIP_Real);
    1880 printf("%g", dval);
    1881 break;
    1882 case 'e':
    1883 dval = va_arg(arguments, SCIP_Real);
    1884 printf("%e", dval);
    1885 break;
    1886 case 'd':
    1887 case 'i':
    1888 ival = va_arg(arguments, int);
    1889 printf("%d", ival);
    1890 break;
    1891 case 'l':
    1892 lval = va_arg(arguments, SCIP_Longint);
    1893 printf("%lld", lval);
    1894 break;
    1895 case 'u':
    1896 ival = va_arg(arguments, int);
    1897 printf("%d", ival);
    1898 break;
    1899 case 'c':
    1900 cval = (char) va_arg(arguments, int);
    1901 printf("%c", cval);
    1902 break;
    1903 case 'p':
    1904 pval = va_arg(arguments, void*);
    1905 printf("%p", pval);
    1906 break;
    1907 default:
    1908 (void) putchar(*formatstr);
    1909 break;
    1910 }
    1911 }
    1912 else
    1913 {
    1914 (void) putchar(*formatstr);
    1915 }
    1916 ++formatstr;
    1917 }
    1918
    1919 va_end(arguments);
    1920}
    1921
    1922/** printf extension for rationals (does not support all format options yet) */
    1924 const char* formatstr, /**< format string like in printf() function */
    1925 ... /**< format arguments line in printf() function */
    1926 )
    1927{
    1928 va_list ap;
    1929
    1930 va_start(ap, formatstr); /*lint !e838*/
    1931 SCIPrationalVPrintf(formatstr, ap);
    1932 va_end(ap);
    1933}
    1934
    1935/** prints a debug message */
    1937 const char* sourcefile, /**< name of the source file that called the function */
    1938 int sourceline, /**< line in the source file where the function was called */
    1939 const char* formatstr, /**< format string like in printf() function */
    1940 ... /**< format arguments line in printf() function */
    1941 )
    1942{
    1943 const char* filename;
    1944 va_list ap;
    1945
    1946 assert(sourcefile != NULL );
    1947
    1948 /* strip directory from filename */
    1949#ifdef _WIN32
    1950 filename = strrchr(sourcefile, '\\');
    1951#else
    1952 filename = strrchr(sourcefile, '/');
    1953#endif
    1954 if( filename == NULL )
    1955 filename = sourcefile;
    1956 else
    1957 ++filename;
    1958
    1959 printf("[%s:%d] debug: ", filename, sourceline);
    1960
    1961 va_start(ap, formatstr); /*lint !e838*/
    1962 SCIPrationalVPrintf(formatstr, ap);
    1963 va_end(ap);
    1964}
    1965
    1966#ifdef SCIP_WITH_BOOST
    1967
    1968/** returns the numerator of a rational as a long */
    1970 SCIP_RATIONAL* rational /**< the rational */
    1971 )
    1972{
    1973 SCIP_Longint result;
    1975
    1977 result = numerator.convert_to<SCIP_Longint>();
    1978
    1979 if( result != numerator )
    1981
    1982 return result;
    1983}
    1984
    1985/** returns the denominator of a rational as a long */
    1987 SCIP_RATIONAL* rational /**< the rational */
    1988 )
    1989{
    1990 SCIP_Longint result;
    1992
    1994 result = denominator.convert_to<SCIP_Longint>();
    1995
    1996 if( result != denominator )
    1998
    1999 return result;
    2000}
    2001
    2002/** compares denominator of a rational to a long */
    2004 SCIP_RATIONAL* rational, /**< the rational */
    2005 SCIP_Longint val /**< long value to compare to */
    2006 )
    2007{
    2008 assert(!SCIPrationalIsAbsInfinity(rational));
    2009
    2011
    2012 return denominator <= val;
    2013}
    2014
    2015#else /* the following is for the dummy class present for systems where Boost is not available */
    2016
    2017/** returns the numerator of a rational as a long */
    2019 SCIP_RATIONAL* rational /**< the rational */
    2020 )
    2021{
    2022 assert(rational != nullptr);
    2023 return (SCIP_Longint) rational->val.val;
    2024}
    2025
    2026/** returns the denominator of a rational as a long */
    2028 SCIP_RATIONAL* rational /**< the rational */
    2029 )
    2030{
    2031 assert(rational != nullptr);
    2032 return 1;
    2033}
    2034
    2035/** returns the denominator of a rational as a long */
    2037 SCIP_RATIONAL* rational, /**< the rational */
    2038 SCIP_Longint val /**< long value to compare to */
    2039 )
    2040{
    2041 assert(rational != nullptr);
    2042 return TRUE;
    2043}
    2044
    2045#endif
    2046
    2047/** returns the sign of the rational (1 if positive, -1 if negative, 0 if zero) */
    2049 const SCIP_RATIONAL* rational /**< the rational */
    2050 )
    2051{
    2052 assert(rational != nullptr);
    2053 return rational->val.sign();
    2054}
    2055
    2056/** computes fractional part of a rational */
    2058 SCIP_RATIONAL* res, /**< rational to save the frac */
    2059 SCIP_RATIONAL* src /**< src rational */
    2060 )
    2061{
    2062 assert(src != nullptr);
    2063 assert(res != nullptr);
    2064
    2065#ifdef SCIP_WITH_BOOST
    2066
    2067 if( src->isinf )
    2068 SCIPrationalSetReal(res, 0.0);
    2069 else
    2070 {
    2071 scip::Integer roundint = 0;
    2072 scip::Integer rest = 0;
    2073
    2074 divide_qr(numerator(src->val), denominator(src->val), roundint, rest);
    2075 if( rest != 0 )
    2076 {
    2077 roundint = src->val.sign() > 0 ? roundint : roundint - 1;
    2078 }
    2079 res->val = src->val - roundint;
    2080 }
    2081#endif
    2082}
    2083
    2084/** returns approximation of rational as SCIP_Real */
    2086 SCIP_RATIONAL* rational /**< the rational */
    2087 )
    2088{
    2089 assert(rational != nullptr);
    2090
    2091#ifdef SCIP_WITH_BOOST
    2092 if( rational->isinf )
    2093 return (rational->val.sign() * infinity);
    2094
    2095#ifdef SCIP_WITH_GMP
    2096 /* mpq_get_d is faster than the boost internal implementation */
    2097 return mpq_get_d(rational->val.backend().data()); /*lint !e838*/
    2098#else
    2099 return rational->val.convert_to<SCIP_Real>(); /*lint !e838*/
    2100#endif
    2101#endif
    2102
    2103 return 0.0;
    2104}
    2105
    2106/** gets the relaxation of a rational as a real
    2107 *
    2108 * @note Requires MPFR if rational is not fp-representable and roundmode is different from SCIP_R_ROUND_NEAREST.
    2109 */
    2111 SCIP_RATIONAL* rational, /**< the rational */
    2112 SCIP_ROUNDMODE_RAT roundmode /**< the rounding direction */
    2113 )
    2114{
    2115 assert(rational != nullptr);
    2116
    2117 if( rational->isinf )
    2118 return (rational->val.sign() * infinity);
    2119 if( rational->isfprepresentable == SCIP_ISFPREPRESENTABLE_TRUE || roundmode == SCIP_R_ROUND_NEAREST )
    2120 return SCIPrationalGetReal(rational);
    2121
    2122#if defined(SCIP_WITH_MPFR) && defined(SCIP_WITH_BOOST) && defined(SCIP_WITH_GMP)
    2123 {
    2124 SCIP_Real realapprox;
    2125 mpfr_t valmpfr;
    2126 mpq_t* val;
    2127
    2128 val = SCIPrationalGetGMP(rational);
    2129 switch(roundmode)
    2130 {
    2132 (void) mpfr_init_set_q(valmpfr, *val, MPFR_RNDD);
    2133 realapprox = (SCIP_Real) mpfr_get_d(valmpfr, MPFR_RNDD);
    2134 break;
    2136 (void) mpfr_init_set_q(valmpfr, *val, MPFR_RNDU);
    2137 realapprox = (SCIP_Real) mpfr_get_d(valmpfr, MPFR_RNDU);
    2138 break;
    2140 (void) mpfr_init_set_q(valmpfr, *val, MPFR_RNDN);
    2141 realapprox = (SCIP_Real) mpfr_get_d(valmpfr, MPFR_RNDN);
    2142 break;
    2143 default:
    2144 realapprox = SCIP_INVALID;
    2145 break;
    2146 }
    2147 mpfr_clear(valmpfr);
    2148 return realapprox;
    2149 }
    2150#else
    2151 SCIPerrorMessage("method SCIPrationalRoundReal not supported when SCIP is compiled without Boost.\n");
    2152 SCIPABORT();
    2153 return SCIP_INVALID;
    2154#endif
    2155}
    2156
    2157/** rounds a rational to an integer and saves it as a rational */
    2159 SCIP_RATIONAL* res, /**< the resulting rounded integer */
    2160 SCIP_RATIONAL* src, /**< the rational to round */
    2161 SCIP_ROUNDMODE_RAT roundmode /**< the rounding direction */
    2162 )
    2163{
    2164 assert(src != nullptr);
    2165 assert(res != nullptr);
    2166#ifdef SCIP_WITH_BOOST
    2167 scip::Integer roundint, rest;
    2168
    2169 if( src->isinf )
    2170 SCIPrationalSetRational(res, src);
    2171 else
    2172 {
    2173 roundint = 0;
    2174 rest = 0;
    2175 divide_qr(numerator(src->val), denominator(src->val), roundint, rest);
    2176 if( rest != 0 )
    2177 {
    2178 switch( roundmode )
    2179 {
    2181 roundint = src->val.sign() > 0 ? roundint : roundint - 1;
    2182 break;
    2184 roundint = src->val.sign() > 0 ? roundint + 1 : roundint;
    2185 break;
    2187 roundint = abs(rest) * 2 >= denominator(src->val) ? roundint + src->val.sign() : roundint;
    2188 break;
    2189 default:
    2190 SCIPerrorMessage("roundmode not supported for integer-rounding \n");
    2191 SCIPABORT();
    2192 break;
    2193 }
    2194 }
    2195 res->val = roundint;
    2196 }
    2197#endif
    2198}
    2199
    2200/** rounds rational to next integer in direction of roundmode
    2201 *
    2202 * @return FALSE if rational outside of long-range
    2203 */
    2205 SCIP_Longint* res, /**< the resulting rounded long int */
    2206 SCIP_RATIONAL* src, /**< the rational to round */
    2207 SCIP_ROUNDMODE_RAT roundmode /**< the rounding direction */
    2208 )
    2209{
    2210 assert(src != nullptr);
    2211 assert(res != nullptr);
    2212
    2213#ifdef SCIP_WITH_BOOST
    2214 assert(!src->isinf);
    2215
    2216 scip::Integer roundint, rest;
    2217 divide_qr(numerator(src->val), denominator(src->val), roundint, rest);
    2218
    2219 if( rest != 0 )
    2220 {
    2221 switch (roundmode)
    2222 {
    2224 roundint = src->val.sign() > 0 ? roundint : roundint - 1;
    2225 break;
    2227 roundint = src->val.sign() > 0 ? roundint + 1 : roundint;
    2228 break;
    2230 roundint = abs(rest) * 2 >= denominator(src->val) ? roundint + src->val.sign() : roundint;
    2231 break;
    2232 default:
    2233 SCIPerrorMessage("roundmode not supported for integer-rounding \n");
    2234 SCIPABORT();
    2235 break;
    2236 }
    2237 }
    2238 *res = roundint.convert_to<SCIP_Longint>();
    2239 if( *res == roundint )
    2240 return TRUE;
    2241#endif
    2242 return FALSE;
    2243}
    2244
    2245#ifdef SCIP_WITH_BOOST
    2246/** choose the best semiconvergent with demnominator <= maxdenom between p1/q1 and p2/q2 */
    2247static
    2248void chooseSemiconv(
    2249 scip::Integer& resnum, /**< the resulting numerator */
    2250 scip::Integer& resden, /**< the resulting denominator */
    2251 scip::Integer* p, /**< the last 3 numerators of convergents */
    2252 scip::Integer* q, /**< the last 3 denominators of convergents */
    2253 const scip::Integer& ai, /**< the coefficient in the continuous fraction */
    2254 const scip::Integer& maxdenom /**< the maximal denominator */
    2255 )
    2256{
    2257 scip::Integer j = (maxdenom - q[0]) / q[1];
    2258
    2259 if( j >= ai / 2 )
    2260 {
    2261 resnum = j * p[1] + p[0];
    2262 resden = j * q[1] + q[0];
    2263 }
    2264 else
    2265 {
    2266 resnum = p[1];
    2267 resden = q[1];
    2268 }
    2269}
    2270
    2271/* choose the best semi-convergent with denominator <= maxdenom between p1/q1 and p2/q2 */
    2272static
    2273void chooseSemiconvLong(
    2274 SCIP_Longint& resnum, /**< the resulting numerator */
    2275 SCIP_Longint& resden, /**< the resulting denominator */
    2276 const SCIP_Longint* p, /**< the last 3 numerators of convergents */
    2277 const SCIP_Longint* q, /**< the last 3 denominators of convergents */
    2278 SCIP_Longint ai, /**< the coefficient in the continuous fraction */
    2279 SCIP_Longint maxdenom /**< the maximal denominator */
    2280 )
    2281{
    2282 SCIP_Longint j;
    2283
    2284 j = (maxdenom - q[0]) / q[1];
    2285
    2286 if( j >= ai / 2 )
    2287 {
    2288 resnum = j * p[1] + p[0];
    2289 resden = j * q[1] + q[0];
    2290 }
    2291 else
    2292 {
    2293 resnum = p[1];
    2294 resden = q[1];
    2295 }
    2296}
    2297
    2298/** compute an approximate number with denominator <= maxdenom, closest to src and save it in res using continued fractions;
    2299 * this version only uses long and is faster
    2300 */
    2301static
    2302void SCIPrationalComputeApproximationLong(
    2303 SCIP_RATIONAL* res, /**< the resulting rational */
    2304 SCIP_RATIONAL* src, /**< the source rational */
    2305 SCIP_Longint maxdenom, /**< the maximal denominator */
    2306 int forcegreater /**< 1 if res >= src should be enforced, -1 if res <= src should be enforced, 0 else */
    2307 )
    2308{
    2309 SCIP_Longint tn, td, temp, a0, ai, resnum, resden;
    2310 /* here we use p[2]=pk, p[1]=pk-1,p[0]=pk-2 and same for q */
    2311 SCIP_Longint p[3] = {0};
    2312 SCIP_Longint q[3] = {0};
    2313 int sign;
    2314 int done;
    2315
    2316 assert(res != nullptr);
    2317 assert(src != nullptr);
    2318 assert(numerator(src->val) <= SCIP_LONGINT_MAX);
    2319 assert(denominator(src->val) <= SCIP_LONGINT_MAX);
    2320
    2321 /* setup n and d for computing a_i the cont. frac. rep */
    2322 tn = SCIPrationalNumerator(src);
    2323 td = SCIPrationalDenominator(src);
    2324
    2325 /* scale to positive to avoid unnecessary complications */
    2326 sign = tn >= 0 ? 1 : -1;
    2327 tn *= sign;
    2328
    2329 assert(td >= 0);
    2330 assert(tn > 0);
    2331
    2332 if( td <= maxdenom )
    2333 {
    2334 res->val = scip::Rational(tn, td) * sign;
    2335 }
    2336 else
    2337 {
    2338 a0 = tn / td;
    2339 temp = tn % td;
    2340
    2341 /* if value is almost integer, we use the next best integer (while still adhering to <=/>= requirements) */
    2342 if( temp < td / (maxdenom * 1.0) )
    2343 {
    2344 /* do not immediately set res to a0 * sign since res and src might be the same pointer */
    2345 if( forcegreater == 1 && a0 * sign < src->val )
    2346 {
    2347 res->val = a0 * sign;
    2348 res->val += scip::Rational(1,maxdenom);
    2349 }
    2350 else if( forcegreater == -1 && a0 * sign > src->val )
    2351 {
    2352 res->val = a0 * sign;
    2353 res->val -= scip::Rational(1,maxdenom);
    2354 }
    2355 else
    2356 res->val = a0 * sign;
    2357
    2358 res->isinf = FALSE;
    2360
    2361 SCIPdebug(std::cout << "approximating " << src->val << " by " << res->val << std::endl);
    2362
    2363 return;
    2364 }
    2365
    2366 tn = td;
    2367 td = temp;
    2368
    2369 assert(td != 0L);
    2370
    2371 ai = tn / td;
    2372 temp = tn % td;
    2373
    2374 tn = td;
    2375 td = temp;
    2376
    2377 p[1] = a0;
    2378 p[2] = 1 + a0 * ai;
    2379
    2380 q[1] = 1;
    2381 q[2] = ai;
    2382
    2383 done = 0;
    2384
    2385 SCIPdebug(std::cout << "approximating " << src->val << " by continued fractions with maxdenom " << maxdenom << std::endl);
    2386 SCIPdebug(std::cout << "confrac initial values: p0 " << p[1] << " q0 " << q[1] << " p1 " << p[2] << " q1 " << q[2] << std::endl);
    2387
    2388 /* if q is already big, skip loop */
    2389 if( q[2] > maxdenom )
    2390 done = 1;
    2391
    2392 while( !done && td != 0 )
    2393 {
    2394 /* update everything: compute next ai, then update convergents */
    2395
    2396 /* update ai */
    2397 ai = tn / td;
    2398 temp = tn % td;
    2399
    2400 tn = td;
    2401 td = temp;
    2402
    2403 /* shift p,q */
    2404 q[0] = q[1];
    2405 q[1] = q[2];
    2406 p[0] = p[1];
    2407 p[1] = p[2];
    2408
    2409 /* compute next p,q */
    2410 p[2] = p[0] + p[1] * ai;
    2411 q[2] = q[0] + q[1] * ai;
    2412
    2413 SCIPdebug(std::cout << "ai " << ai << " pi " << p[2] << " qi " << q[2] << std::endl);
    2414
    2415 if( q[2] > maxdenom )
    2416 done = 1;
    2417 }
    2418
    2419 if( (forcegreater == 1 && scip::Rational(p[2],q[2]) * sign < src->val) ||
    2420 (forcegreater == -1 && scip::Rational(p[2],q[2]) * sign > src->val) )
    2421 res->val = scip::Rational(p[1],q[1]) * sign;
    2422 else
    2423 {
    2424 /* the corner case where p[2]/q[2] == res has to be considered separately, depending on the side that p[1]/q[1] lies on */
    2425 if( forcegreater != 0 && scip::Rational(p[2],q[2]) * sign == src->val )
    2426 {
    2427 /* if p[1]/q[1] is on the correct side we take it, otherwise we take the correct semiconvergent */
    2428 if( (forcegreater == 1 && scip::Rational(p[1],q[1]) * sign > src->val)
    2429 || (forcegreater == -1 && scip::Rational(p[1],q[1]) * sign < src->val) )
    2430 {
    2431 res->val = scip::Rational(p[1],q[1]) * sign;
    2432 }
    2433 else
    2434 {
    2435 SCIPdebug(std::cout << " picking semiconvergent " << std::endl);
    2436 chooseSemiconvLong(resnum, resden, p, q, 1, maxdenom);
    2437 SCIPdebug(std::cout << " use " << resnum << "/" << resden << std::endl);
    2438 res->val = scip::Rational(resnum,resden) * sign;
    2439 }
    2440 }
    2441 /* normal case -> pick semiconvergent for best approximation */
    2442 else
    2443 {
    2444 if( forcegreater != 0 )
    2445 chooseSemiconvLong(resnum, resden, p, q, 1, maxdenom);
    2446 else
    2447 chooseSemiconvLong(resnum, resden, p, q, ai, maxdenom);
    2448 SCIPdebug(std::cout << " picking semiconvergent " << std::endl);
    2449 SCIPdebug(std::cout << " use " << resnum << "/" << resden << std::endl);
    2450 res->val = scip::Rational(resnum,resden) * sign;
    2451 }
    2452 }
    2453 }
    2454
    2455 assert(forcegreater != 1 || res->val >= src->val);
    2456 assert(forcegreater != -1 || res->val <= src->val);
    2457
    2458 res->isinf = FALSE;
    2460}
    2461#endif
    2462
    2463/** compute an approximate number with denominator <= maxdenom, closest to src and save it in res using continued fractions */
    2465 SCIP_RATIONAL* res, /**< the resulting rational */
    2466 SCIP_RATIONAL* src, /**< the rational to approximate */
    2467 SCIP_Longint maxdenom, /**< maximal denominator */
    2468 int forcegreater /**< 1 if res >= src should be enforced, -1 if res <= src should be enforced, 0 else */
    2469 )
    2470{
    2471 assert(src != nullptr);
    2472 assert(res != nullptr);
    2473#ifdef SCIP_WITH_BOOST
    2474 int done;
    2475
    2476 scip::Integer temp;
    2477 scip::Integer td;
    2478 scip::Integer tn;
    2479
    2480 /* The following represent the continued fraction values a_i, the cont frac representation and p_i/q_i, the convergents */
    2481 scip::Integer a0;
    2482 scip::Integer ai;
    2483
    2484 /* here we use p[2]=pk, p[1]=pk-1,p[0]=pk-2 and same for q */
    2485 scip::Integer p[3];
    2486 scip::Integer q[3];
    2487
    2488 scip::Integer resnum;
    2489 scip::Integer resden;
    2490
    2491 int sign;
    2492
    2494
    2495 if(src->val == 0)
    2496 {
    2497 SCIPrationalSetReal(res, 0.0);
    2498 return;
    2499 }
    2500 /* close to 0, we can just set to 1/maxdenom or 0, depending on sign */
    2501 else if( src->val.sign() == 1 && SCIPrationalGetReal(src) < (1.0 / maxdenom) )
    2502 {
    2503 if( forcegreater == 1 )
    2504 SCIPrationalSetFraction(res, 1LL, maxdenom);
    2505 else
    2506 SCIPrationalSetReal(res, 0.0);
    2507
    2508 return;
    2509 }
    2510 else if( src->val.sign() == -1 && SCIPrationalGetReal(src) > (-1.0 / maxdenom) )
    2511 {
    2512 if( forcegreater == -1 )
    2513 SCIPrationalSetFraction(res, -1LL, maxdenom);
    2514 else
    2515 SCIPrationalSetReal(res, 0.0);
    2516
    2517 return;
    2518 }
    2519
    2520 /* setup n and d for computing a_i the cont. frac. rep */
    2521 tn = numerator(src->val);
    2522 td = denominator(src->val);
    2523
    2524 /* as long as the rational is small enough, we can do everythin we need in long long */
    2525 if( (tn * tn.sign() <= SCIP_LONGINT_MAX) && (td * td.sign() <= SCIP_LONGINT_MAX) )
    2526 {
    2527 SCIPrationalComputeApproximationLong(res, src, maxdenom, forcegreater);
    2528 return;
    2529 }
    2530
    2531 /* scale to positive to avoid unnecessary complications */
    2532 sign = tn.sign();
    2533 tn *= sign;
    2534
    2535 assert(td >= 0);
    2536 assert(tn >= 0);
    2537
    2538 if( td <= maxdenom )
    2539 {
    2540 res->val = scip::Rational(tn, td) * sign;
    2541 }
    2542 else
    2543 {
    2544 temp = 1;
    2545 divide_qr(tn, td, a0, temp);
    2546
    2547 /* if value is almost integer, we use the next best integer (while still adhering to <=/>= requirements) */
    2548 if( temp * maxdenom < td )
    2549 {
    2550 if( forcegreater == 1 && a0 * sign < src->val )
    2551 {
    2552 res->val = a0 * sign;
    2553 res->val += scip::Rational(1,maxdenom);
    2554 }
    2555 else if( forcegreater == -1 && a0 * sign > src->val )
    2556 {
    2557 res->val = a0 * sign;
    2558 res->val -= scip::Rational(1,maxdenom);
    2559 }
    2560 else
    2561 res->val = a0 * sign;
    2562
    2563 res->isinf = FALSE;
    2565
    2566 SCIPdebug(std::cout << "approximating " << src->val << " by " << res->val << std::endl);
    2567
    2568 return;
    2569 }
    2570
    2571 tn = td;
    2572 td = temp;
    2573
    2574 divide_qr(tn, td, ai, temp);
    2575
    2576 tn = td;
    2577 td = temp;
    2578
    2579 p[1] = a0;
    2580 p[2] = 1 + a0 * ai;
    2581
    2582 q[1] = 1;
    2583 q[2] = ai;
    2584
    2585 done = 0;
    2586
    2587 SCIPdebug(std::cout << "approximating " << src->val << " by continued fractions with maxdenom " << maxdenom << std::endl);
    2588 SCIPdebug(std::cout << "confrac initial values: p0 " << p[1] << " q0 " << q[1] << " p1 " << p[2] << " q1 " << q[2] << std::endl);
    2589
    2590 /* if q is already big, skip loop */
    2591 if( q[2] > maxdenom )
    2592 done = 1;
    2593
    2594 while(!done && td != 0)
    2595 {
    2596 /* update everything: compute next ai, then update convergents */
    2597
    2598 /* update ai */
    2599 divide_qr(tn, td, ai, temp);
    2600 tn = td;
    2601 td = temp;
    2602
    2603 /* shift p,q */
    2604 q[0] = q[1];
    2605 q[1] = q[2];
    2606 p[0] = p[1];
    2607 p[1] = p[2];
    2608
    2609 /* compute next p,q */
    2610 p[2] = p[0] + p[1] * ai;
    2611 q[2] = q[0] + q[1] * ai;
    2612
    2613 SCIPdebug(std::cout << "ai " << ai << " pi " << p[2] << " qi " << q[2] << std::endl);
    2614
    2615 if( q[2] > maxdenom )
    2616 done = 1;
    2617 }
    2618
    2619 if( (forcegreater == 1 && scip::Rational(p[2],q[2]) * sign < src->val) ||
    2620 (forcegreater == -1 && scip::Rational(p[2],q[2]) * sign > src->val) )
    2621 res->val = scip::Rational(p[1],q[1]) * sign;
    2622 else
    2623 {
    2624 /* the corner case where p[2]/q[2] == res has to be considered separately, depending on the side that p[1]/q[1] lies on */
    2625 if( forcegreater != 0 && scip::Rational(p[2],q[2]) * sign == src->val )
    2626 {
    2627 /* if p[1]/q[1] is on the correct side we take it, otherwise we take the correct semiconvergent */
    2628 if( (forcegreater == 1 && scip::Rational(p[1],q[1]) * sign > src->val)
    2629 || (forcegreater == -1 && scip::Rational(p[1],q[1]) * sign < src->val) )
    2630 {
    2631 res->val = scip::Rational(p[1],q[1]) * sign;
    2632 }
    2633 else
    2634 {
    2635 SCIPdebug(std::cout << " picking semiconvergent " << std::endl);
    2636 chooseSemiconv(resnum, resden, p, q, 1, scip::Integer(maxdenom));
    2637 SCIPdebug(std::cout << " use " << resnum << "/" << resden << std::endl);
    2638 res->val = scip::Rational(resnum,resden) * sign;
    2639 }
    2640 }
    2641 /* normal case -> pick semiconvergent for best approximation */
    2642 else
    2643 {
    2644 if( forcegreater != 0 )
    2645 chooseSemiconv(resnum, resden, p, q, 1, scip::Integer(maxdenom));
    2646 else
    2647 chooseSemiconv(resnum, resden, p, q, ai, scip::Integer(maxdenom));
    2648 SCIPdebug(std::cout << " picking semiconvergent " << std::endl);
    2649 SCIPdebug(std::cout << " use " << resnum << "/" << resden << std::endl);
    2650 res->val = scip::Rational(resnum,resden) * sign;
    2651 }
    2652 }
    2653 }
    2654
    2655 assert(forcegreater != 1 || res->val >= src->val);
    2656 assert(forcegreater != -1 || res->val <= src->val);
    2657#endif
    2658
    2659 res->isinf = FALSE;
    2661}
    2662
    2663/*
    2664 * Dynamic Arrays
    2665 */
    2666
    2667/** creates a dynamic array of real values */
    2669 SCIP_RATIONALARRAY** rationalarray, /**< pointer to store the real array */
    2670 BMS_BLKMEM* blkmem /**< block memory */
    2671 )
    2672{
    2673 assert(rationalarray != nullptr);
    2674 assert(blkmem != nullptr);
    2675
    2676 SCIP_ALLOC( BMSallocBlockMemory(blkmem, rationalarray) );
    2677 new (&(*rationalarray)->vals) scip::sparsevec();
    2678 (*rationalarray)->firstidx = -1;
    2679
    2680 return SCIP_OKAY;
    2681}
    2682
    2683/** creates a dynamic array of real values */
    2685 SCIP_RATIONALARRAY* rationalarray, /**< pointer to store the real array */
    2686 int newsize /**< new size */
    2687 )
    2688{
    2689 assert(rationalarray != nullptr);
    2690
    2691 rationalarray->vals.resize((size_t)newsize);
    2692
    2693 return SCIP_OKAY;
    2694}
    2695
    2696/** creates a copy of a dynamic array of real values */
    2698 SCIP_RATIONALARRAY** rationalarray, /**< pointer to store the copied real array */
    2699 BMS_BLKMEM* blkmem, /**< block memory */
    2700 SCIP_RATIONALARRAY* sourcerationalarray /**< dynamic rational array to copy */
    2701 )
    2702{
    2703 assert(rationalarray != nullptr);
    2704 assert(sourcerationalarray != nullptr);
    2705
    2706 SCIP_CALL( SCIPrationalarrayCreate(rationalarray, blkmem) );
    2707 (*rationalarray)->vals = sourcerationalarray->vals;
    2708 (*rationalarray)->firstidx = sourcerationalarray->firstidx;
    2709
    2710 return SCIP_OKAY;
    2711}
    2712
    2713/** frees a dynamic array of real values */
    2715 SCIP_RATIONALARRAY** rationalarray, /**< pointer to the real array */
    2716 BMS_BLKMEM* blkmem /**< block memory */
    2717 )
    2718{
    2719 assert(rationalarray != nullptr);
    2720 assert(*rationalarray != nullptr);
    2721
    2722 (*rationalarray)->vals.scip::sparsevec::~sparsevec();
    2723 BMSfreeBlockMemory(blkmem, rationalarray);
    2724
    2725 return SCIP_OKAY;
    2726}
    2727
    2728/** gets value of entry in dynamic array */
    2730 SCIP_RATIONALARRAY* rationalarray, /**< dynamic rational array */
    2731 int idx, /**< array index to get value for */
    2732 SCIP_RATIONAL* result /**< store the result */
    2733 )
    2734{
    2735 assert(rationalarray != nullptr);
    2736 assert(idx >= 0);
    2737
    2738 if( rationalarray->firstidx == -1 || idx < rationalarray->firstidx
    2739 || (size_t) idx >= rationalarray->vals.size() + (size_t) rationalarray->firstidx )
    2740 SCIPrationalSetFraction(result, 0LL, 1LL);
    2741 else
    2742 SCIPrationalSetRational(result, &rationalarray->vals[(size_t) (idx - rationalarray->firstidx)]);
    2743}
    2744
    2745/** sets value of entry in dynamic array */
    2747 SCIP_RATIONALARRAY* rationalarray, /**< dynamic rational array */
    2748 int idx, /**< array index to set value for */
    2749 SCIP_RATIONAL* val /**< value to set array index to */
    2750 )
    2751{
    2752 assert(rationalarray != nullptr);
    2753 assert(idx >= 0);
    2754
    2755 if( rationalarray-> firstidx == -1 )
    2756 {
    2757 rationalarray->vals.push_back(*val);
    2758 rationalarray->firstidx = idx;
    2759 }
    2760
    2761 if( idx < rationalarray->firstidx )
    2762 {
    2763 int ninserts = rationalarray->firstidx - idx;
    2764 SCIP_RATIONAL r = {};
    2765 (void) rationalarray->vals.insert(rationalarray->vals.begin(), ninserts, r);
    2766 rationalarray->firstidx = idx;
    2767 rationalarray->vals[0] = *val;
    2768 }
    2769 else if( (size_t) idx >= rationalarray->vals.size() + rationalarray->firstidx )
    2770 {
    2771 int ninserts = idx - (int) rationalarray->vals.size() - rationalarray->firstidx + 1;
    2772 SCIP_RATIONAL r = {};
    2773 (void) rationalarray->vals.insert(rationalarray->vals.end(), (size_t) ninserts, r);
    2774 rationalarray->vals[rationalarray->vals.size() - 1] = *val;
    2775 }
    2776 else
    2777 {
    2778 rationalarray->vals[idx - rationalarray->firstidx] = *val;
    2779 }
    2780
    2781 return SCIP_OKAY;
    2782}
    2783
    2784/** increases value of entry in dynamic array */
    2786 SCIP_RATIONALARRAY* rationalarray, /**< dynamic rational array */
    2787 int idx, /**< array index to increase value for */
    2788 SCIP_RATIONAL* incval /**< value to increase array index */
    2789 )
    2790{
    2791 assert(incval != nullptr);
    2792 assert(!incval->isinf);
    2793
    2794 if( SCIPrationalIsZero(incval) )
    2795 return SCIP_OKAY;
    2796 else if( idx < rationalarray->firstidx || (size_t) idx >= rationalarray->vals.size() + (size_t) rationalarray->firstidx )
    2797 SCIP_CALL( SCIPrationalarraySetVal(rationalarray, idx, incval) );
    2798 else
    2799 {
    2800 assert(idx >= rationalarray->firstidx);
    2801 rationalarray->vals[(size_t) (idx - rationalarray->firstidx)].val += incval->val;
    2802 rationalarray->vals[(size_t) (idx - rationalarray->firstidx)].isfprepresentable = FALSE;
    2803 }
    2804
    2805 return SCIP_OKAY;
    2806}
    2807
    2808/** prints a rationalarray to std out */
    2810 SCIP_RATIONALARRAY* rationalarray /**< dynamic rational array */
    2811 )
    2812{
    2813 printf("Array with firstidx %d, length %d \n", rationalarray->firstidx, (int) rationalarray->vals.size());
    2814 for( auto val : rationalarray->vals )
    2815 {
    2816 SCIPrationalPrint(&val);
    2817 }
    2818 printf("\n");
    2819
    2820 return SCIP_OKAY;
    2821}
    2822
    2823/** returns the minimal index of all stored non-zero elements */
    2825 SCIP_RATIONALARRAY* rationalarray /**< dynamic rational array */
    2826 )
    2827{
    2828 assert(rationalarray != nullptr);
    2829
    2830 return rationalarray->firstidx;
    2831}
    2832
    2833/** returns the maximal index of all stored non-zero elements */
    2835 SCIP_RATIONALARRAY* rationalarray /**< dynamic rational array */
    2836 )
    2837{
    2838 assert(rationalarray != nullptr);
    2839
    2840 return rationalarray->firstidx + (int) rationalarray->vals.size() - 1;
    2841}
    2842
    2843/** changes the infinity threshold to new value */
    2845 SCIP_Real inf /**< new infinity value */
    2846 )
    2847{
    2848 assert(inf > 0);
    2849
    2850#ifdef SCIP_THREADSAFE
    2851 if( inf != SCIP_DEFAULT_INFINITY )
    2852 {
    2853 SCIPerrorMessage("method SCIPrationalChgInfinity() not thread safe\n");
    2854 SCIPABORT();
    2855 }
    2856 assert(inf == SCIP_DEFAULT_INFINITY);
    2857#else
    2858 infinity = inf;
    2859#endif
    2860}
    2861
    2862/** return the infinity threshold for rationals */
    2864 void
    2865 )
    2866{
    2867 return infinity;
    2868}
    2869
    2870}
    SCIP_Real * r
    Definition: circlepacking.c:59
    int sign() const
    std::string str() const
    bool is_zero() const
    #define SCIP_DEFAULT_INFINITY
    Definition: def.h:163
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_LONGINT_MIN
    Definition: def.h:143
    #define SCIPABORT()
    Definition: def.h:327
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_LONGINT_MAX
    Definition: def.h:142
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_Bool SCIPrationalIsLTReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1576
    SCIP_Bool SCIPrationalIsFpRepresentable(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1710
    void SCIPrationalMin(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1342
    SCIP_Bool SCIPrationalRoundLong(SCIP_Longint *res, SCIP_RATIONAL *src, SCIP_ROUNDMODE_RAT roundmode)
    Definition: rational.cpp:2204
    SCIP_RETCODE SCIPrationalCreateBlock(BMS_BLKMEM *blkmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:108
    SCIP_RETCODE SCIPrationalCreate(SCIP_RATIONAL **rational)
    Definition: rational.cpp:94
    void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1066
    void SCIPrationalInvert(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
    Definition: rational.cpp:1323
    SCIP_Bool SCIPrationalIsAbsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1421
    SCIP_RETCODE SCIPrationalarrayIncVal(SCIP_RATIONALARRAY *rationalarray, int idx, SCIP_RATIONAL *incval)
    Definition: rational.cpp:2785
    void SCIPrationalPrint(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1831
    void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:618
    void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:935
    SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
    Definition: rational.cpp:2085
    void SCIPrationalGetFrac(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
    Definition: rational.cpp:2057
    SCIP_RETCODE SCIPrationalCreateString(BMS_BLKMEM *mem, SCIP_RATIONAL **rational, const char *desc)
    Definition: rational.cpp:796
    SCIP_RETCODE SCIPrationalCopy(SCIP_RATIONAL **result, SCIP_RATIONAL *src)
    Definition: rational.cpp:138
    SCIP_Bool SCIPrationalIsString(const char *desc)
    Definition: rational.cpp:652
    void SCIPrationalResetFloatingPointRepresentable(SCIP_RATIONAL *rat)
    Definition: rational.cpp:642
    SCIP_Bool SCIPrationalIsApproxEQReal(SCIP_SET *set, SCIP_RATIONAL *rat, SCIP_Real real, SCIP_ROUNDMODE_RAT roundmode)
    Definition: rational.cpp:1451
    void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:461
    int SCIPrationalToString(SCIP_RATIONAL *rational, char *str, int strlen)
    Definition: rational.cpp:1743
    void SCIPrationalarrayGetVal(SCIP_RATIONALARRAY *rationalarray, int idx, SCIP_RATIONAL *result)
    Definition: rational.cpp:2729
    SCIP_RETCODE SCIPrationalCreateBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***rational, int size)
    Definition: rational.cpp:196
    #define SCIPrationalDebugMessage
    Definition: rational.h:641
    void SCIPrationalPrintVerbInfo(SCIP_MESSAGEHDLR *msg, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, SCIP_RATIONAL *rational)
    Definition: rational.cpp:1813
    void SCIPrationalAbs(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
    Definition: rational.cpp:1310
    void SCIPrationalRoundInteger(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_ROUNDMODE_RAT roundmode)
    Definition: rational.cpp:2158
    void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1132
    SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1680
    SCIP_RETCODE SCIPrationalarrayResize(SCIP_RATIONALARRAY *rationalarray, int newsize)
    Definition: rational.cpp:2684
    SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1503
    void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
    Definition: rational.cpp:603
    SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1474
    SCIP_RETCODE SCIPrationalCopyBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **result, SCIP_RATIONAL *src)
    Definition: rational.cpp:151
    void SCIPrationalCheckInfByValue(SCIP_RATIONAL *rational)
    Definition: rational.cpp:552
    void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:473
    SCIP_RETCODE SCIPrationalCopyBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***target, SCIP_RATIONAL **src, int len)
    Definition: rational.cpp:249
    void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:983
    SCIP_Bool SCIPrationalIsLEReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1615
    SCIP_RETCODE SCIPrationalCopyBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***result, SCIP_RATIONAL **src, int len)
    Definition: rational.cpp:267
    SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1640
    SCIP_Longint SCIPrationalDenominator(SCIP_RATIONAL *rational)
    Definition: rational.cpp:2027
    int SCIPrationalGetSign(const SCIP_RATIONAL *rational)
    Definition: rational.cpp:2048
    SCIP_Real SCIPrationalGetInfinity(void)
    Definition: rational.cpp:2863
    SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:123
    void SCIPrationalAddProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1173
    SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1624
    void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
    Definition: rational.cpp:569
    int SCIPrationalarrayGetMinIdx(SCIP_RATIONALARRAY *rationalarray)
    Definition: rational.cpp:2824
    void SCIPrationalSetString(SCIP_RATIONAL *res, const char *desc)
    Definition: rational.cpp:716
    SCIP_Bool SCIPrationalIsGEReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1606
    void SCIPrationalFreeArray(SCIP_RATIONAL ***ratarray, int size)
    Definition: rational.cpp:485
    SCIP_RETCODE SCIPrationalReallocArray(SCIP_RATIONAL ***result, int oldlen, int newlen)
    Definition: rational.cpp:285
    SCIP_Bool SCIPrationalIsIntegral(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1691
    SCIP_Bool SCIPrationalDenominatorIsLE(SCIP_RATIONAL *rational, SCIP_Longint val)
    Definition: rational.cpp:2036
    void SCIPrationalMax(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1373
    void SCIPrationalRelDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *val1, SCIP_RATIONAL *val2)
    Definition: rational.cpp:1024
    SCIP_Bool SCIPrationalIsGE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1512
    SCIP_RETCODE SCIPrationalarraySetVal(SCIP_RATIONALARRAY *rationalarray, int idx, SCIP_RATIONAL *val)
    Definition: rational.cpp:2746
    SCIP_Bool SCIPstrToRationalValue(char *desc, SCIP_RATIONAL *value, char **endptr)
    Definition: rational.cpp:822
    void SCIPrationalPrintDebugMessage(const char *sourcefile, int sourceline, const char *formatstr,...)
    Definition: rational.cpp:1936
    void SCIPrationalCanonicalize(SCIP_RATIONAL *rational)
    Definition: rational.cpp:538
    void SCIPrationalMessage(SCIP_MESSAGEHDLR *msg, FILE *file, SCIP_RATIONAL *rational)
    Definition: rational.cpp:1790
    void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:630
    void SCIPrationalSetFraction(SCIP_RATIONAL *res, SCIP_Longint nom, SCIP_Longint denom)
    Definition: rational.cpp:582
    void SCIPrationalNegate(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
    Definition: rational.cpp:1297
    SCIP_RETCODE SCIPrationalarrayCreate(SCIP_RATIONALARRAY **rationalarray, BMS_BLKMEM *blkmem)
    Definition: rational.cpp:2668
    SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1650
    void SCIPrationalDiffReal(SCIP_RATIONAL *res, SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1009
    int SCIPrationalarrayGetMaxIdx(SCIP_RATIONALARRAY *rationalarray)
    Definition: rational.cpp:2834
    SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1660
    void SCIPrationalFreeBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***ratblockarray, int size)
    Definition: rational.cpp:501
    SCIP_Real SCIPrationalRoundReal(SCIP_RATIONAL *rational, SCIP_ROUNDMODE_RAT roundmode)
    Definition: rational.cpp:2110
    SCIP_Longint SCIPrationalNumerator(SCIP_RATIONAL *rational)
    Definition: rational.cpp:2018
    SCIP_Bool SCIPrationalIsEQReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1437
    SCIP_RETCODE SCIPrationalCreateArray(SCIP_RATIONAL ***rational, int size)
    Definition: rational.cpp:179
    SCIP_RETCODE SCIPrationalCreateBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***rational, int size)
    Definition: rational.cpp:214
    SCIP_RETCODE SCIPrationalarrayCopy(SCIP_RATIONALARRAY **rationalarray, BMS_BLKMEM *blkmem, SCIP_RATIONALARRAY *sourcerationalarray)
    Definition: rational.cpp:2697
    SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1670
    void SCIPrationalFree(SCIP_RATIONAL **rational)
    Definition: rational.cpp:450
    void SCIPrationalDiffProdReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1268
    SCIP_RETCODE SCIPrationalarrayFree(SCIP_RATIONALARRAY **rationalarray, BMS_BLKMEM *blkmem)
    Definition: rational.cpp:2714
    void SCIPrationalDivReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1147
    SCIP_Bool SCIPrationalIsGTReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1546
    SCIP_RETCODE SCIPrationalReallocBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***result, int oldlen, int newlen)
    Definition: rational.cpp:344
    SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1404
    void SCIPrationalChgInfinity(SCIP_Real inf)
    Definition: rational.cpp:2844
    void SCIPrationalDiffProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
    Definition: rational.cpp:1239
    void SCIPrationalPrintf(const char *formatstr,...)
    Definition: rational.cpp:1923
    SCIP_RETCODE SCIPrationalReallocBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***result, int oldlen, int newlen)
    Definition: rational.cpp:314
    void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1097
    void SCIPrationalComputeApproximation(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_Longint maxdenom, int forcegreater)
    Definition: rational.cpp:2464
    void SCIPrationalFreeBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***ratbufarray, int size)
    Definition: rational.cpp:518
    SCIP_RETCODE SCIPrationalCopyBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **result, SCIP_RATIONAL *src)
    Definition: rational.cpp:165
    SCIP_Bool SCIPrationalIsAbsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1530
    SCIP_Bool SCIPrationalIsLE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1521
    void SCIPrationalAddReal(SCIP_RATIONAL *res, SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:961
    SCIP_RETCODE SCIPrationalCopyArray(SCIP_RATIONAL ***target, SCIP_RATIONAL **src, int len)
    Definition: rational.cpp:232
    SCIP_RETCODE SCIPrationalarrayPrint(SCIP_RATIONALARRAY *rationalarray)
    Definition: rational.cpp:2809
    int SCIPrationalStrLen(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1774
    void SCIPrationalAddProdReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
    Definition: rational.cpp:1210
    int SCIPstrncpy(char *t, const char *s, int size)
    Definition: misc.c:10897
    int SCIPstrncasecmp(const char *s1, const char *s2, int length)
    Definition: misc.c:10876
    interval arithmetics for provable bounds
    memory allocation routines
    #define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
    Definition: memory.h:462
    #define BMSreallocBufferMemoryArray(mem, ptr, num)
    Definition: memory.h:733
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSfreeBlockMemory(mem, ptr)
    Definition: memory.h:465
    #define BMSfreeBufferMemory(mem, ptr)
    Definition: memory.h:740
    #define BMSduplicateBufferMemoryArray(mem, ptr, source, num)
    Definition: memory.h:737
    #define BMSallocBlockMemory(mem, ptr)
    Definition: memory.h:451
    #define BMSreallocMemoryArray(ptr, num)
    Definition: memory.h:127
    #define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
    Definition: memory.h:468
    #define BMSduplicateMemoryArray(ptr, source, num)
    Definition: memory.h:143
    #define BMSallocBufferMemory(mem, ptr)
    Definition: memory.h:727
    #define BMSallocMemoryArray(ptr, num)
    Definition: memory.h:123
    #define BMSallocBlockMemoryArray(mem, ptr, num)
    Definition: memory.h:454
    #define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
    Definition: memory.h:458
    #define BMSallocBufferMemoryArray(mem, ptr, num)
    Definition: memory.h:731
    #define BMSfreeBufferMemoryArrayNull(mem, ptr)
    Definition: memory.h:743
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSfreeMemoryArrayNull(ptr)
    Definition: memory.h:148
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    #define va_copy(dest, src)
    Definition: message.c:47
    void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
    Definition: message.c:618
    SCIP_Longint denominator(Rational &r)
    Rational & abs(Rational &r)
    SCIP_Longint numerator(Rational &r)
    std::vector< SCIP_RATIONAL > sparsevec
    double real
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    public data structures and miscellaneous methods
    static void SCIPrationalVPrintf(const char *formatstr, va_list ap)
    Definition: rational.cpp:1845
    std::ostream & operator<<(std::ostream &os, SCIP_RATIONAL const &r)
    Definition: rational.cpp:68
    static SCIP_Real infinity
    Definition: rational.cpp:86
    wrapper for rational number arithmetic
    wrapper for rational number arithmetic that interacts with GMP
    SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6537
    SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6515
    internal methods for global SCIP settings
    std::vector< SCIP_RATIONAL > vals
    unsigned int isinf
    scip::Rational val
    unsigned int isfprepresentable
    definition of wrapper class for rational numbers
    Definition: heur_padm.c:135
    type definitions for message output methods
    enum SCIP_VerbLevel SCIP_VERBLEVEL
    Definition: type_message.h:64
    @ SCIP_VERBLEVEL_NONE
    Definition: type_message.h:57
    @ SCIP_VERBLEVEL_FULL
    Definition: type_message.h:62
    type definitions for rational numbers
    enum SCIP_RoundModeRational SCIP_ROUNDMODE_RAT
    Definition: type_rational.h:61
    @ SCIP_ISFPREPRESENTABLE_FALSE
    Definition: type_rational.h:50
    @ SCIP_ISFPREPRESENTABLE_TRUE
    Definition: type_rational.h:49
    @ SCIP_ISFPREPRESENTABLE_UNKNOWN
    Definition: type_rational.h:48
    @ SCIP_R_ROUND_UPWARDS
    Definition: type_rational.h:58
    @ SCIP_R_ROUND_DOWNWARDS
    Definition: type_rational.h:57
    @ SCIP_R_ROUND_NEAREST
    Definition: type_rational.h:59
    type definitions for return codes for SCIP methods
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63