Scippy

SCIP

Solving Constraint Integer Programs

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