SCIP Doxygen Documentation
Loading...
Searching...
No Matches
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{
145
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{
159
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{
173
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{
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 {
297 }
298
300 }
301 else
302 {
304
305 for( int i = oldlen; i < newlen; ++i )
306 {
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 {
327 }
328
330 }
331 else
332 {
334
335 for( int i = oldlen; i < newlen; ++i )
336 {
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 {
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 {
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
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);
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{
1974
1975 numerator = boost::multiprecision::numerator(rational->val);
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{
1991
1992 denominator = boost::multiprecision::denominator(rational->val);
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{
2008
2009 scip::Integer denominator = boost::multiprecision::denominator(rational->val);
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);
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 )
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 }
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}
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
#define infinity
Definition gastrans.c:80
SCIP_Bool SCIPrationalIsLTReal(SCIP_RATIONAL *rat, SCIP_Real real)
SCIP_Bool SCIPrationalIsFpRepresentable(SCIP_RATIONAL *rational)
void SCIPrationalMin(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_Bool SCIPrationalRoundLong(SCIP_Longint *res, SCIP_RATIONAL *src, SCIP_ROUNDMODE_RAT roundmode)
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)
void SCIPrationalInvert(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
SCIP_Bool SCIPrationalIsAbsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
SCIP_RETCODE SCIPrationalarrayIncVal(SCIP_RATIONALARRAY *rationalarray, int idx, SCIP_RATIONAL *incval)
void SCIPrationalPrint(SCIP_RATIONAL *rational)
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)
void SCIPrationalGetFrac(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
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)
void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
Definition rational.cpp:462
int SCIPrationalToString(SCIP_RATIONAL *rational, char *str, int strlen)
void SCIPrationalarrayGetVal(SCIP_RATIONALARRAY *rationalarray, int idx, SCIP_RATIONAL *result)
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)
void SCIPrationalAbs(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
void SCIPrationalRoundInteger(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_ROUNDMODE_RAT roundmode)
void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
SCIP_RETCODE SCIPrationalarrayResize(SCIP_RATIONALARRAY *rationalarray, int newsize)
SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
Definition rational.cpp:604
SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
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)
SCIP_RETCODE SCIPrationalCopyBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***result, SCIP_RATIONAL **src, int len)
Definition rational.cpp:268
SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
SCIP_Longint SCIPrationalDenominator(SCIP_RATIONAL *rational)
int SCIPrationalGetSign(const SCIP_RATIONAL *rational)
SCIP_Real SCIPrationalGetInfinity(void)
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition rational.cpp:124
void SCIPrationalAddProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
Definition rational.cpp:570
int SCIPrationalarrayGetMinIdx(SCIP_RATIONALARRAY *rationalarray)
void SCIPrationalSetString(SCIP_RATIONAL *res, const char *desc)
Definition rational.cpp:717
SCIP_Bool SCIPrationalIsGEReal(SCIP_RATIONAL *rat, SCIP_Real real)
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)
SCIP_Bool SCIPrationalDenominatorIsLE(SCIP_RATIONAL *rational, SCIP_Longint val)
void SCIPrationalMax(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
void SCIPrationalRelDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *val1, SCIP_RATIONAL *val2)
SCIP_Bool SCIPrationalIsGE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
SCIP_RETCODE SCIPrationalarraySetVal(SCIP_RATIONALARRAY *rationalarray, int idx, SCIP_RATIONAL *val)
SCIP_Bool SCIPstrToRationalValue(char *desc, SCIP_RATIONAL *value, char **endptr)
Definition rational.cpp:823
void SCIPrationalPrintDebugMessage(const char *sourcefile, int sourceline, const char *formatstr,...)
void SCIPrationalCanonicalize(SCIP_RATIONAL *rational)
Definition rational.cpp:539
void SCIPrationalMessage(SCIP_MESSAGEHDLR *msg, FILE *file, SCIP_RATIONAL *rational)
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)
SCIP_RETCODE SCIPrationalarrayCreate(SCIP_RATIONALARRAY **rationalarray, BMS_BLKMEM *blkmem)
SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
void SCIPrationalDiffReal(SCIP_RATIONAL *res, SCIP_RATIONAL *rat, SCIP_Real real)
int SCIPrationalarrayGetMaxIdx(SCIP_RATIONALARRAY *rationalarray)
SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
void SCIPrationalFreeBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***ratblockarray, int size)
Definition rational.cpp:502
SCIP_Real SCIPrationalRoundReal(SCIP_RATIONAL *rational, SCIP_ROUNDMODE_RAT roundmode)
SCIP_Longint SCIPrationalNumerator(SCIP_RATIONAL *rational)
SCIP_Bool SCIPrationalIsEQReal(SCIP_RATIONAL *rat, SCIP_Real real)
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)
SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
void SCIPrationalFree(SCIP_RATIONAL **rational)
Definition rational.cpp:451
void SCIPrationalDiffProdReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
SCIP_RETCODE SCIPrationalarrayFree(SCIP_RATIONALARRAY **rationalarray, BMS_BLKMEM *blkmem)
void SCIPrationalDivReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
SCIP_Bool SCIPrationalIsGTReal(SCIP_RATIONAL *rat, SCIP_Real real)
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)
void SCIPrationalChgInfinity(SCIP_Real inf)
void SCIPrationalDiffProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
void SCIPrationalPrintf(const char *formatstr,...)
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)
void SCIPrationalComputeApproximation(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_Longint maxdenom, int forcegreater)
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)
SCIP_Bool SCIPrationalIsLE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
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)
int SCIPrationalStrLen(SCIP_RATIONAL *rational)
void SCIPrationalAddProdReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
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
return SCIP_OKAY
int r
assert(minobj< SCIPgetCutoffbound(scip))
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_BufMem BMS_BUFMEM
Definition memory.h:721
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
std::vector< SCIP_RATIONAL > sparsevec
INLINE SCIP_Longint numerator(Rational &r)
INLINE Rational & abs(Rational &r)
Rational Integer
INLINE SCIP_Longint denominator(Rational &r)
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)
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
type definitions for message output methods
enum SCIP_VerbLevel SCIP_VERBLEVEL
struct SCIP_Messagehdlr SCIP_MESSAGEHDLR
@ SCIP_VERBLEVEL_NONE
@ SCIP_VERBLEVEL_FULL
type definitions for rational numbers
struct SCIP_Rational SCIP_RATIONAL
enum SCIP_RoundModeRational SCIP_ROUNDMODE_RAT
struct SCIP_RationalArray SCIP_RATIONALARRAY
@ SCIP_ISFPREPRESENTABLE_FALSE
@ SCIP_ISFPREPRESENTABLE_TRUE
@ SCIP_ISFPREPRESENTABLE_UNKNOWN
@ SCIP_R_ROUND_UPWARDS
@ SCIP_R_ROUND_DOWNWARDS
@ SCIP_R_ROUND_NEAREST
type definitions for return codes for SCIP methods
enum SCIP_Retcode SCIP_RETCODE
struct SCIP_Set SCIP_SET
Definition type_set.h:71