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