Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
constants.cpp
Go to the documentation of this file.
2
3#include <cmath>
4#include <type_traits>
5
7
9
11
13
17
18namespace storm {
19namespace utility {
20
21template<typename ValueType>
22ValueType one() {
23 return ValueType(1);
24}
25
26template<typename ValueType>
27ValueType zero() {
28 return ValueType(0);
29}
30
31template<typename ValueType>
32ValueType infinity() {
33 return std::numeric_limits<ValueType>::infinity();
34}
35
36template<typename ValueType>
37bool isOne(ValueType const& a) {
38 return a == one<ValueType>();
39}
40
41template<typename ValueType>
42bool isZero(ValueType const& a) {
43 return a == zero<ValueType>();
44}
45
46template<typename ValueType>
47bool isNan(ValueType const&) {
48 return false;
49}
50
51template<>
52bool isNan(double const& value) {
53 return std::isnan(value);
54}
55
56template<typename ValueType>
57bool isAlmostZero(ValueType const& a) {
58 return a < convertNumber<ValueType>(1e-12) && a > -convertNumber<ValueType>(1e-12);
59}
60
61template<typename ValueType>
62bool isAlmostOne(ValueType const& a) {
63 return a < convertNumber<ValueType>(1.0 + 1e-12) && a > convertNumber<ValueType>(1.0 - 1e-12);
64}
65
66template<typename ValueType>
67bool isConstant(ValueType const&) {
68 return true;
69}
70
71template<typename ValueType>
72bool isInfinity(ValueType const& a) {
73 return a == infinity<ValueType>();
74}
75
76template<typename ValueType>
77bool isInteger(ValueType const& number) {
78 ValueType iPart;
79 ValueType result = std::modf(number, &iPart);
80 return result == zero<ValueType>();
81}
82
83template<>
84bool isInteger(int const&) {
85 return true;
86}
87
88template<>
89bool isInteger(uint32_t const&) {
90 return true;
91}
92
93template<>
95 return true;
96}
97
98template<typename TargetType, typename SourceType>
99TargetType convertNumber(SourceType const& number) {
100 return static_cast<TargetType>(number);
101}
102
103template<>
104uint_fast64_t convertNumber(double const& number) {
105 return std::llround(number);
106}
107
108template<>
109int_fast64_t convertNumber(double const& number) {
110 return std::llround(number);
111}
112
113template<>
114double convertNumber(uint_fast64_t const& number) {
115 return number;
116}
117
118template<>
119double convertNumber(double const& number) {
120 return number;
121}
122
123template<>
124double convertNumber(long long const& number) {
125 return static_cast<double>(number);
126}
127
128template<>
130 return static_cast<storm::storage::sparse::state_type>(number);
131}
132
133template<typename ValueType>
134ValueType simplify(ValueType value) {
135 // In the general case, we don't do anything here, but merely return the value. If something else is
136 // supposed to happen here, the templated function can be specialized for this particular type.
137 return value;
138}
139
140template<typename ValueType>
141std::pair<ValueType, ValueType> minmax(std::vector<ValueType> const& values) {
142 assert(!values.empty());
143 ValueType min = values.front();
144 ValueType max = values.front();
145 for (auto const& vt : values) {
146 if (vt < min) {
147 min = vt;
148 }
149 if (vt > max) {
150 max = vt;
151 }
152 }
153 return std::make_pair(min, max);
154}
155
156template<typename ValueType>
157ValueType minimum(std::vector<ValueType> const& values) {
158 assert(!values.empty());
159 ValueType min = values.front();
160 for (auto const& vt : values) {
161 if (vt < min) {
162 min = vt;
163 }
164 }
165 return min;
166}
167
168template<typename ValueType>
169ValueType maximum(std::vector<ValueType> const& values) {
170 assert(!values.empty());
171 ValueType max = values.front();
172 for (auto const& vt : values) {
173 if (vt > max) {
174 max = vt;
175 }
176 }
177 return max;
178}
179
180template<typename K, typename ValueType>
181std::pair<ValueType, ValueType> minmax(std::map<K, ValueType> const& values) {
182 assert(!values.empty());
183 ValueType min = values.begin()->second;
184 ValueType max = values.begin()->second;
185 for (auto const& vt : values) {
186 if (vt.second < min) {
187 min = vt.second;
188 }
189 if (vt.second > max) {
190 max = vt.second;
191 }
192 }
193 return std::make_pair(min, max);
194}
195
196template<typename K, typename ValueType>
197ValueType minimum(std::map<K, ValueType> const& values) {
198 return minmax(values).first;
199}
200
201template<typename K, typename ValueType>
202ValueType maximum(std::map<K, ValueType> const& values) {
203 return minmax(values).second;
204}
205
206template<typename ValueType>
207ValueType pow(ValueType const& value, int_fast64_t exponent) {
208 return std::pow(value, exponent);
209}
210
211template<typename ValueType>
212ValueType max(ValueType const& first, ValueType const& second) {
213 return std::max(first, second);
214}
215
216template<typename ValueType>
217ValueType min(ValueType const& first, ValueType const& second) {
218 return std::min(first, second);
219}
220
221template<typename ValueType>
222ValueType sqrt(ValueType const& number) {
223 return std::sqrt(number);
224}
225
226template<typename ValueType>
227ValueType abs(ValueType const& number) {
228 return std::fabs(number);
229}
230
231template<typename ValueType>
232ValueType floor(ValueType const& number) {
233 return std::floor(number);
234}
235
236template<typename ValueType>
237ValueType ceil(ValueType const& number) {
238 return std::ceil(number);
239}
240
241template<typename ValueType>
242ValueType round(ValueType const& number) {
243 // Rounding towards infinity
244 return floor<ValueType>(number + storm::utility::convertNumber<ValueType>(0.5));
245}
246
247template<typename ValueType>
248ValueType log(ValueType const& number) {
249 return std::log(number);
250}
251
252template<typename ValueType>
253ValueType log10(ValueType const& number) {
254 return std::log10(number);
255}
256
257template<typename ValueType>
258ValueType cos(ValueType const& number) {
259 return std::cos(number);
260}
261
262template<typename ValueType>
263ValueType sin(ValueType const& number) {
264 return std::sin(number);
265}
266
267template<typename ValueType>
268uint64_t numDigits(ValueType const& number) {
269 auto numDigits = 0;
270 ValueType remaining = storm::utility::one<ValueType>() / number;
271 ValueType ten = storm::utility::convertNumber<ValueType>(10);
272 while (remaining >= storm::utility::one<ValueType>()) {
273 ++numDigits;
274 remaining = storm::utility::floor<ValueType>(remaining / ten);
275 }
276 return numDigits;
277}
278
279template<typename ValueType>
280typename NumberTraits<ValueType>::IntegerType trunc(ValueType const& number) {
281 return static_cast<typename NumberTraits<ValueType>::IntegerType>(std::trunc(number));
282}
283
284template<typename IntegerType>
285IntegerType mod(IntegerType const& first, IntegerType const& second) {
286 return std::fmod(first, second);
287}
288
289template<typename IntegerType>
290std::pair<IntegerType, IntegerType> divide(IntegerType const& dividend, IntegerType const& divisor) {
291 return std::make_pair(dividend / divisor, mod(dividend, divisor));
292}
293
294template<typename ValueType>
295std::string to_string(ValueType const& value) {
296 std::stringstream ss;
297 ss.precision(std::numeric_limits<ValueType>::max_digits10 + 2);
298 ss << value;
299 return ss.str();
300}
301
302#if defined(STORM_HAVE_CARL) && defined(STORM_HAVE_CLN)
303template<>
304storm::ClnRationalNumber infinity() {
305 // FIXME: this should be treated more properly.
306 return storm::ClnRationalNumber(100000000000);
307}
308
309template<>
310bool isOne(storm::ClnRationalNumber const& a) {
311 return carl::isOne(a);
312}
313
314template<>
315bool isZero(storm::ClnRationalNumber const& a) {
316 return carl::isZero(a);
317}
318
319template<>
320bool isInteger(storm::ClnRationalNumber const& number) {
321 return carl::isInteger(number);
322}
323
324template<>
325std::pair<storm::ClnRationalNumber, storm::ClnRationalNumber> minmax(std::vector<storm::ClnRationalNumber> const& values) {
326 assert(!values.empty());
327 storm::ClnRationalNumber min = values.front();
328 storm::ClnRationalNumber max = values.front();
329 for (auto const& vt : values) {
330 if (vt == storm::utility::infinity<storm::ClnRationalNumber>()) {
331 max = vt;
332 } else {
333 if (vt < min) {
334 min = vt;
335 }
336 if (vt > max) {
337 max = vt;
338 }
339 }
340 }
341 return std::make_pair(min, max);
342}
343
344template<>
345uint_fast64_t convertNumber(ClnRationalNumber const& number) {
346 return carl::toInt<carl::uint>(number);
347}
348
349template<>
350int_fast64_t convertNumber(ClnRationalNumber const& number) {
351 return carl::toInt<carl::sint>(number);
352}
353
354template<>
355ClnRationalNumber convertNumber(double const& number) {
356 return carl::rationalize<ClnRationalNumber>(number);
357}
358
359template<>
360ClnRationalNumber convertNumber(int const& number) {
361 return carl::rationalize<ClnRationalNumber>(number);
362}
363
364template<>
365ClnRationalNumber convertNumber(NumberTraits<ClnRationalNumber>::IntegerType const& number) {
366 return ClnRationalNumber(number);
367}
368
369template<>
370ClnRationalNumber convertNumber(uint_fast64_t const& number) {
371 STORM_LOG_ASSERT(static_cast<carl::uint>(number) == number, "Rationalizing failed, because the number is too large.");
372 return carl::rationalize<ClnRationalNumber>(static_cast<carl::uint>(number));
373}
374
375template<>
376typename NumberTraits<ClnRationalNumber>::IntegerType convertNumber(uint_fast64_t const& number) {
377 STORM_LOG_ASSERT(static_cast<unsigned long int>(number) == number, "Conversion failed, because the number is too large.");
378 return NumberTraits<ClnRationalNumber>::IntegerType(static_cast<unsigned long int>(number));
379}
380
381template<>
382typename NumberTraits<ClnRationalNumber>::IntegerType convertNumber(double const& number) {
383 if (number < static_cast<double>(std::numeric_limits<uint64_t>::max())) {
384 return NumberTraits<ClnRationalNumber>::IntegerType(static_cast<uint64_t>(number));
385 } else {
386 return carl::round(carl::rationalize<ClnRationalNumber>(number));
387 }
388}
389
390template<>
391ClnRationalNumber convertNumber(int_fast64_t const& number) {
392 STORM_LOG_ASSERT(static_cast<carl::sint>(number) == number, "Rationalizing failed, because the number is too large.");
393 return carl::rationalize<ClnRationalNumber>(static_cast<carl::sint>(number));
394}
395
396template<>
397double convertNumber(ClnRationalNumber const& number) {
398 return carl::toDouble(number);
399}
400
401template<>
402ClnRationalNumber convertNumber(std::string const& number) {
403 ClnRationalNumber result;
404 if (carl::try_parse<ClnRationalNumber>(number, result)) {
405 return result;
406 }
407 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Unable to parse '" << number << "' as a rational number.");
408}
409
410template<>
411std::pair<ClnRationalNumber, ClnRationalNumber> asFraction(ClnRationalNumber const& number) {
412 return std::make_pair(carl::getNum(number), carl::getDenom(number));
413}
414
415template<>
416ClnRationalNumber sqrt(ClnRationalNumber const& number) {
417 return carl::sqrt(number);
418}
419
420template<>
421ClnRationalNumber abs(storm::ClnRationalNumber const& number) {
422 return carl::abs(number);
423}
424
425template<>
426ClnRationalNumber floor(storm::ClnRationalNumber const& number) {
427 return carl::floor(number);
428}
429
430template<>
431ClnRationalNumber ceil(storm::ClnRationalNumber const& number) {
432 return carl::ceil(number);
433}
434
435template<>
436ClnRationalNumber log(ClnRationalNumber const& number) {
437 return carl::log(number);
438}
439
440template<>
441ClnRationalNumber log10(ClnRationalNumber const& number) {
442 return carl::log10(number);
443}
444
445template<>
446ClnRationalNumber cos(ClnRationalNumber const& number) {
447 return carl::cos(number);
448}
449
450template<>
451ClnRationalNumber sin(ClnRationalNumber const& number) {
452 return carl::sin(number);
453}
454
455template<>
456typename NumberTraits<ClnRationalNumber>::IntegerType trunc(ClnRationalNumber const& number) {
457 return cln::truncate1(number);
458}
459
460template<>
461typename NumberTraits<ClnRationalNumber>::IntegerType mod(NumberTraits<ClnRationalNumber>::IntegerType const& first,
462 NumberTraits<ClnRationalNumber>::IntegerType const& second) {
463 return carl::mod(first, second);
464}
465
466template<>
467std::pair<typename NumberTraits<ClnRationalNumber>::IntegerType, typename NumberTraits<ClnRationalNumber>::IntegerType> divide(
468 typename NumberTraits<ClnRationalNumber>::IntegerType const& dividend, typename NumberTraits<ClnRationalNumber>::IntegerType const& divisor) {
469 std::pair<typename NumberTraits<ClnRationalNumber>::IntegerType, typename NumberTraits<ClnRationalNumber>::IntegerType> result;
470 carl::divide(dividend, divisor, result.first, result.second);
471 return result;
472}
473
474template<>
475typename NumberTraits<ClnRationalNumber>::IntegerType pow(typename NumberTraits<ClnRationalNumber>::IntegerType const& value, int_fast64_t exponent) {
476 STORM_LOG_THROW(exponent >= 0, storm::exceptions::InvalidArgumentException,
477 "Tried to compute the power 'x^y' as an integer, but the exponent 'y' is negative.");
478 return carl::pow(value, exponent);
479}
480
481template<>
482ClnRationalNumber pow(ClnRationalNumber const& value, int_fast64_t exponent) {
483 if (exponent >= 0) {
484 return carl::pow(value, exponent);
485 } else {
486 return storm::utility::one<ClnRationalNumber>() / carl::pow(value, -exponent);
487 }
488}
489
490template<>
491NumberTraits<ClnRationalNumber>::IntegerType numerator(ClnRationalNumber const& number) {
492 return carl::getNum(number);
493}
494
495template<>
496NumberTraits<ClnRationalNumber>::IntegerType denominator(ClnRationalNumber const& number) {
497 return carl::getDenom(number);
498}
499#endif
500
501#if defined(STORM_HAVE_CARL) && defined(STORM_HAVE_GMP)
502template<>
503storm::GmpRationalNumber infinity() {
504 // FIXME: this should be treated more properly.
505 return storm::GmpRationalNumber(100000000000);
506}
507
508template<>
509bool isOne(storm::GmpRationalNumber const& a) {
510 return carl::isOne(a);
511}
512
513template<>
514bool isZero(storm::GmpRationalNumber const& a) {
515 return carl::isZero(a);
516}
517
518template<>
519bool isInteger(storm::GmpRationalNumber const& number) {
520 return carl::isInteger(number);
521}
522
523template<>
524std::pair<storm::GmpRationalNumber, storm::GmpRationalNumber> minmax(std::vector<storm::GmpRationalNumber> const& values) {
525 assert(!values.empty());
526 storm::GmpRationalNumber min = values.front();
527 storm::GmpRationalNumber max = values.front();
528 for (auto const& vt : values) {
529 if (vt == storm::utility::infinity<storm::GmpRationalNumber>()) {
530 max = vt;
531 } else {
532 if (vt < min) {
533 min = vt;
534 }
535 if (vt > max) {
536 max = vt;
537 }
538 }
539 }
540 return std::make_pair(min, max);
541}
542
543template<>
544std::pair<storm::GmpRationalNumber, storm::GmpRationalNumber> minmax(std::map<uint64_t, storm::GmpRationalNumber> const& values) {
545 assert(!values.empty());
546 storm::GmpRationalNumber min = values.begin()->second;
547 storm::GmpRationalNumber max = values.begin()->second;
548 for (auto const& vt : values) {
549 if (vt.second == storm::utility::infinity<storm::GmpRationalNumber>()) {
550 max = vt.second;
551 } else {
552 if (vt.second < min) {
553 min = vt.second;
554 }
555 if (vt.second > max) {
556 max = vt.second;
557 }
558 }
559 }
560 return std::make_pair(min, max);
561}
562
563template<>
564uint_fast64_t convertNumber(GmpRationalNumber const& number) {
565 return carl::toInt<carl::uint>(number);
566}
567
568template<>
569int_fast64_t convertNumber(GmpRationalNumber const& number) {
570 return carl::toInt<carl::sint>(number);
571}
572
573template<>
574GmpRationalNumber convertNumber(double const& number) {
575 return carl::rationalize<GmpRationalNumber>(number);
576}
577
578template<>
579GmpRationalNumber convertNumber(int const& number) {
580 return carl::rationalize<GmpRationalNumber>(number);
581}
582
583template<>
584GmpRationalNumber convertNumber(uint_fast64_t const& number) {
585 STORM_LOG_ASSERT(static_cast<carl::uint>(number) == number, "Rationalizing failed, because the number is too large.");
586 return carl::rationalize<GmpRationalNumber>(static_cast<carl::uint>(number));
587}
588
589template<>
590GmpRationalNumber convertNumber(NumberTraits<GmpRationalNumber>::IntegerType const& number) {
591 return GmpRationalNumber(number);
592}
593
594template<>
595typename NumberTraits<GmpRationalNumber>::IntegerType convertNumber(uint_fast64_t const& number) {
596 STORM_LOG_ASSERT(static_cast<unsigned long int>(number) == number, "Conversion failed, because the number is too large.");
597 return NumberTraits<GmpRationalNumber>::IntegerType(static_cast<unsigned long int>(number));
598}
599
600template<>
601typename NumberTraits<GmpRationalNumber>::IntegerType convertNumber(double const& number) {
602 return NumberTraits<GmpRationalNumber>::IntegerType(number);
603}
604
605template<>
606GmpRationalNumber convertNumber(int_fast64_t const& number) {
607 STORM_LOG_ASSERT(static_cast<carl::sint>(number) == number, "Rationalizing failed, because the number is too large.");
608 return carl::rationalize<GmpRationalNumber>(static_cast<carl::sint>(number));
609}
610
611template<>
612double convertNumber(GmpRationalNumber const& number) {
613 return carl::toDouble(number);
614}
615
616template<>
617GmpRationalNumber convertNumber(std::string const& number) {
618 GmpRationalNumber result;
619 if (carl::try_parse<GmpRationalNumber>(number, result)) {
620 return result;
621 }
622 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Unable to parse '" << number << "' as a rational number.");
623}
624
625template<>
626std::pair<GmpRationalNumber, GmpRationalNumber> asFraction(GmpRationalNumber const& number) {
627 return std::make_pair(carl::getNum(number), carl::getDenom(number));
628}
629
630template<>
631GmpRationalNumber sqrt(GmpRationalNumber const& number) {
632 return carl::sqrt(number);
633}
634
635template<>
636GmpRationalNumber abs(storm::GmpRationalNumber const& number) {
637 return carl::abs(number);
638}
639
640template<>
641GmpRationalNumber floor(storm::GmpRationalNumber const& number) {
642 return carl::floor(number);
643}
644
645template<>
646GmpRationalNumber ceil(storm::GmpRationalNumber const& number) {
647 return carl::ceil(number);
648}
649
650template<>
651GmpRationalNumber log(GmpRationalNumber const& number) {
652 return carl::log(number);
653}
654
655template<>
656GmpRationalNumber log10(GmpRationalNumber const& number) {
657 STORM_LOG_WARN("Using log10 for GMP rational numbers is not exact, it converts to doubles internally! Avoid if possible.");
658 return carl::log10(number);
659}
660
661template<>
662GmpRationalNumber cos(GmpRationalNumber const& number) {
663 return carl::cos(number);
664}
665
666template<>
667GmpRationalNumber sin(GmpRationalNumber const& number) {
668 return carl::sin(number);
669}
670
671template<>
672typename NumberTraits<GmpRationalNumber>::IntegerType trunc(GmpRationalNumber const& number) {
673 return carl::getNum(number) / carl::getDenom(number);
674}
675
676template<>
677typename NumberTraits<GmpRationalNumber>::IntegerType mod(typename NumberTraits<GmpRationalNumber>::IntegerType const& first,
678 typename NumberTraits<GmpRationalNumber>::IntegerType const& second) {
679 return carl::mod(first, second);
680}
681
682template<>
683std::pair<typename NumberTraits<GmpRationalNumber>::IntegerType, typename NumberTraits<GmpRationalNumber>::IntegerType> divide(
684 typename NumberTraits<GmpRationalNumber>::IntegerType const& dividend, typename NumberTraits<GmpRationalNumber>::IntegerType const& divisor) {
685 std::pair<typename NumberTraits<GmpRationalNumber>::IntegerType, typename NumberTraits<GmpRationalNumber>::IntegerType> result;
686 carl::divide(dividend, divisor, result.first, result.second);
687 return result;
688}
689
690template<>
691typename NumberTraits<GmpRationalNumber>::IntegerType pow(typename NumberTraits<GmpRationalNumber>::IntegerType const& value, int_fast64_t exponent) {
692 STORM_LOG_THROW(exponent >= 0, storm::exceptions::InvalidArgumentException,
693 "Tried to compute the power 'x^y' as an integer, but the exponent 'y' is negative.");
694 return carl::pow(value, exponent);
695}
696
697template<>
698GmpRationalNumber pow(GmpRationalNumber const& value, int_fast64_t exponent) {
699 if (exponent >= 0) {
700 return carl::pow(value, exponent);
701 } else {
702 return storm::utility::one<GmpRationalNumber>() / carl::pow(value, -exponent);
703 }
704}
705
706template<>
707typename NumberTraits<GmpRationalNumber>::IntegerType numerator(GmpRationalNumber const& number) {
708 return carl::getNum(number);
709}
710
711template<>
712typename NumberTraits<GmpRationalNumber>::IntegerType denominator(GmpRationalNumber const& number) {
713 return carl::getDenom(number);
714}
715#endif
716
717#if defined(STORM_HAVE_CARL) && defined(STORM_HAVE_GMP) && defined(STORM_HAVE_CLN)
718template<>
719storm::GmpRationalNumber convertNumber(storm::ClnRationalNumber const& number) {
720 return carl::parse<storm::GmpRationalNumber>(to_string(number));
721}
722
723template<>
724storm::ClnRationalNumber convertNumber(storm::GmpRationalNumber const& number) {
725 return carl::parse<storm::ClnRationalNumber>(to_string(number));
726}
727#endif
728
729#ifdef STORM_HAVE_CARL
730template<>
732 // FIXME: this should be treated more properly.
733 return storm::RationalFunction(convertNumber<RationalFunctionCoefficient>(100000000000));
734}
735
736template<>
737bool isOne(storm::RationalFunction const& a) {
738 return a.isOne();
739}
740
741template<>
742bool isOne(storm::Polynomial const& a) {
743 return a.isOne();
744}
745
746template<>
747bool isZero(storm::RationalFunction const& a) {
748 return a.isZero();
749}
750
751template<>
752bool isZero(storm::Polynomial const& a) {
753 return a.isZero();
754}
755
756template<>
757bool isConstant(storm::RationalFunction const& a) {
758 return a.isConstant();
759}
760
761template<>
762bool isConstant(storm::Polynomial const& a) {
763 return a.isConstant();
764}
765
766template<>
767bool isConstant(storm::Interval const& a) {
768 return a.isPointInterval();
769}
770
771template<>
772bool isInfinity(storm::RationalFunction const& a) {
773 // FIXME: this should be treated more properly.
774 return a == infinity<storm::RationalFunction>();
775}
776
777template<>
778bool isInteger(storm::RationalFunction const& func) {
779 return storm::utility::isConstant(func) && storm::utility::isOne(func.denominator());
780}
781
782template<>
783RationalFunction convertNumber(double const& number) {
784 return RationalFunction(carl::rationalize<RationalFunctionCoefficient>(number));
785}
786
787template<>
788RationalFunction convertNumber(int_fast64_t const& number) {
789 STORM_LOG_ASSERT(static_cast<carl::sint>(number) == number, "Rationalizing failed, because the number is too large.");
790 return RationalFunction(carl::rationalize<RationalFunctionCoefficient>(static_cast<carl::sint>(number)));
791}
792
793#if defined(STORM_HAVE_CLN)
794template<>
795RationalFunction convertNumber(ClnRationalNumber const& number) {
796 return RationalFunction(convertNumber<storm::RationalFunctionCoefficient>(number));
797}
798
799template<>
800ClnRationalNumber convertNumber(RationalFunction const& number) {
801 storm::RationalFunctionCoefficient tmp = number.nominatorAsNumber() / number.denominatorAsNumber();
802 return convertNumber<ClnRationalNumber>(tmp);
803}
804#endif
805
806#if defined(STORM_HAVE_GMP)
807template<>
808RationalFunction convertNumber(GmpRationalNumber const& number) {
809 return RationalFunction(convertNumber<storm::RationalFunctionCoefficient>(number));
810}
811
812template<>
813GmpRationalNumber convertNumber(RationalFunction const& number) {
814 return convertNumber<GmpRationalNumber>(number.nominatorAsNumber() / number.denominatorAsNumber());
815}
816#endif
817
818template<>
819carl::uint convertNumber(RationalFunction const& func) {
820 return carl::toInt<carl::uint>(convertNumber<RationalFunctionCoefficient>(func));
821}
822
823template<>
824carl::sint convertNumber(RationalFunction const& func) {
825 return carl::toInt<carl::sint>(convertNumber<RationalFunctionCoefficient>(func));
826}
827
828template<>
829double convertNumber(RationalFunction const& func) {
830 return carl::toDouble(convertNumber<RationalFunctionCoefficient>(func));
831}
832
833template<>
835 return number;
836}
837
838template<>
839RationalFunction convertNumber(std::string const& number) {
840 return RationalFunction(convertNumber<RationalFunctionCoefficient>(number));
841}
842
843template<>
845 return RationalFunction(convertNumber<RationalFunctionCoefficient>(number));
846}
847
848template<>
850
851template<>
853
854template<>
856 value.simplify();
857 return value;
858}
859
860template<>
862 value.simplify();
863 return value;
864}
865
866template<>
868 value.simplify();
869 return std::move(value);
870}
871
872template<>
874 return a.isConstant() && isAlmostZero(convertNumber<RationalFunctionCoefficient>(a));
875}
876
877template<>
879 return a.isConstant() && isAlmostOne(convertNumber<RationalFunctionCoefficient>(a));
880}
881
882template<>
883std::pair<storm::RationalFunction, storm::RationalFunction> minmax(std::vector<storm::RationalFunction> const&) {
884 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Minimum/maximum for rational functions is not defined.");
885}
886
887template<>
888storm::RationalFunction minimum(std::vector<storm::RationalFunction> const&) {
889 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Minimum for rational functions is not defined.");
890}
891
892template<>
893storm::RationalFunction maximum(std::vector<storm::RationalFunction> const&) {
894 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Maximum for rational functions is not defined.");
895}
896
897template<>
898std::pair<storm::RationalFunction, storm::RationalFunction> minmax(std::map<uint64_t, storm::RationalFunction> const&) {
899 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Maximum/maximum for rational functions is not defined.");
900}
901
902template<>
903storm::RationalFunction minimum(std::map<uint64_t, storm::RationalFunction> const&) {
904 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Minimum for rational functions is not defined.");
905}
906
907template<>
908storm::RationalFunction maximum(std::map<uint64_t, storm::RationalFunction> const&) {
909 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Maximum for rational functions is not defined");
910}
911
912template<>
913RationalFunction pow(RationalFunction const& value, int_fast64_t exponent) {
914 if (exponent >= 0) {
915 return carl::pow(value, exponent);
916 } else {
917 return storm::utility::one<RationalFunction>() / carl::pow(value, -exponent);
918 }
919}
920
921template<>
922std::string to_string(RationalFunction const& f) {
923 std::stringstream ss;
924 if (f.isConstant()) {
925 if (f.denominator().isOne()) {
926 ss << f.nominatorAsNumber();
927 } else {
928 ss << f.nominatorAsNumber() << "/" << f.denominatorAsNumber();
929 }
930 } else if (f.denominator().isOne()) {
931 ss << f.nominatorAsPolynomial().coefficient() * f.nominatorAsPolynomial().polynomial();
932 } else {
933 ss << "(" << f.nominatorAsPolynomial() << ")/(" << f.denominatorAsPolynomial() << ")";
934 }
935 return ss.str();
936}
937
938#endif
939
940template<>
941double convertNumber(std::string const& value) {
942 return convertNumber<double>(convertNumber<storm::RationalNumber>(value));
943}
944
945template<>
946storm::Interval convertNumber(double const& number) {
947 return storm::Interval(number);
948}
949
950template<>
951storm::Interval convertNumber(uint64_t const& number) {
952 return storm::Interval(convertNumber<double>(number));
953}
954
955#if defined(STORM_HAVE_GMP)
956template<>
957storm::Interval convertNumber(storm::GmpRationalNumber const& n) {
958 return storm::Interval(convertNumber<double>(n));
959}
960
961template<>
962storm::GmpRationalNumber convertNumber(storm::Interval const& number) {
963 STORM_LOG_ASSERT(number.isPointInterval(), "Interval must be a point interval to convert");
964 return convertNumber<storm::GmpRationalNumber>(number.lower());
965}
966#endif
967
968#if defined(STORM_HAVE_CLN)
969template<>
970storm::Interval convertNumber(storm::ClnRationalNumber const& n) {
971 return storm::Interval(convertNumber<double>(n));
972}
973
974template<>
975storm::ClnRationalNumber convertNumber(storm::Interval const& number) {
976 STORM_LOG_ASSERT(number.isPointInterval(), "Interval must be a point interval to convert");
977 return convertNumber<storm::ClnRationalNumber>(number.lower());
978}
979#endif
980
981template<>
982double convertNumber(storm::Interval const& number) {
983 STORM_LOG_ASSERT(number.isPointInterval(), "Interval must be a point interval to convert");
984 return number.lower();
985}
986
987template<>
989 return interval.abs();
990}
991
992// Explicit instantiations.
993
994// double
995template double one();
996template double zero();
997template double infinity();
998template bool isOne(double const& value);
999template bool isZero(double const& value);
1000template bool isAlmostZero(double const& value);
1001template bool isAlmostOne(double const& value);
1002template bool isConstant(double const& value);
1003template bool isInfinity(double const& value);
1004template bool isInteger(double const& number);
1005template double simplify(double value);
1006template std::pair<double, double> minmax(std::vector<double> const&);
1007template double minimum(std::vector<double> const&);
1008template double maximum(std::vector<double> const&);
1009template std::pair<double, double> minmax(std::map<uint64_t, double> const&);
1010template double minimum(std::map<uint64_t, double> const&);
1011template double maximum(std::map<uint64_t, double> const&);
1012template double pow(double const& value, int_fast64_t exponent);
1013template double max(double const& first, double const& second);
1014template double min(double const& first, double const& second);
1015template double sqrt(double const& number);
1016template double abs(double const& number);
1017template double floor(double const& number);
1018template double ceil(double const& number);
1019template double round(double const& number);
1020template double log(double const& number);
1021template double log10(double const& number);
1022template double cos(double const& number);
1023template double sin(double const& number);
1024template typename NumberTraits<double>::IntegerType trunc(double const& number);
1025template double mod(double const& first, double const& second);
1026template std::string to_string(double const& value);
1027
1028// int
1029template int one();
1030template int zero();
1031template int infinity();
1032template bool isOne(int const& value);
1033template bool isZero(int const& value);
1034template bool isConstant(int const& value);
1035template bool isInfinity(int const& value);
1036
1037// uint32_t
1038template uint32_t one();
1039template uint32_t zero();
1040template uint32_t infinity();
1041template bool isOne(uint32_t const& value);
1042template bool isZero(uint32_t const& value);
1043template bool isConstant(uint32_t const& value);
1044template bool isInfinity(uint32_t const& value);
1045
1046// storm::storage::sparse::state_type
1050template bool isOne(storm::storage::sparse::state_type const& value);
1051template bool isZero(storm::storage::sparse::state_type const& value);
1054
1055// other instantiations
1056template unsigned long convertNumber(long const&);
1057template double convertNumber(long const&);
1058
1059#if defined(STORM_HAVE_CLN)
1060// Instantiations for (CLN) rational number.
1061template storm::ClnRationalNumber one();
1063template storm::ClnRationalNumber zero();
1065template bool isConstant(storm::ClnRationalNumber const& value);
1066template bool isInfinity(storm::ClnRationalNumber const& value);
1067template bool isNan(storm::ClnRationalNumber const& value);
1068template bool isAlmostZero(storm::ClnRationalNumber const& value);
1069template bool isAlmostOne(storm::ClnRationalNumber const& value);
1071template storm::ClnRationalNumber convertNumber(storm::ClnRationalNumber const& number);
1072template storm::ClnRationalNumber simplify(storm::ClnRationalNumber value);
1073template std::pair<storm::ClnRationalNumber, storm::ClnRationalNumber> minmax(std::map<uint64_t, storm::ClnRationalNumber> const&);
1074template storm::ClnRationalNumber minimum(std::map<uint64_t, storm::ClnRationalNumber> const&);
1075template storm::ClnRationalNumber maximum(std::map<uint64_t, storm::ClnRationalNumber> const&);
1076template storm::ClnRationalNumber minimum(std::vector<storm::ClnRationalNumber> const&);
1077template storm::ClnRationalNumber maximum(std::vector<storm::ClnRationalNumber> const&);
1078template storm::ClnRationalNumber max(storm::ClnRationalNumber const& first, storm::ClnRationalNumber const& second);
1079template storm::ClnRationalNumber min(storm::ClnRationalNumber const& first, storm::ClnRationalNumber const& second);
1080template storm::ClnRationalNumber round(storm::ClnRationalNumber const& number);
1081template std::string to_string(storm::ClnRationalNumber const& value);
1082template uint64_t numDigits(const storm::ClnRationalNumber& number);
1083#endif
1084
1085#if defined(STORM_HAVE_GMP)
1086// Instantiations for (GMP) rational number.
1087template storm::GmpRationalNumber one();
1089template storm::GmpRationalNumber zero();
1091template bool isConstant(storm::GmpRationalNumber const& value);
1092template bool isInfinity(storm::GmpRationalNumber const& value);
1093template bool isNan(storm::GmpRationalNumber const& value);
1094template bool isAlmostZero(storm::GmpRationalNumber const& value);
1095template bool isAlmostOne(storm::GmpRationalNumber const& value);
1097template storm::GmpRationalNumber convertNumber(storm::GmpRationalNumber const& number);
1098template storm::GmpRationalNumber simplify(storm::GmpRationalNumber value);
1099template storm::GmpRationalNumber minimum(std::map<uint64_t, storm::GmpRationalNumber> const&);
1100template storm::GmpRationalNumber maximum(std::map<uint64_t, storm::GmpRationalNumber> const&);
1101template storm::GmpRationalNumber minimum(std::vector<storm::GmpRationalNumber> const&);
1102template storm::GmpRationalNumber maximum(std::vector<storm::GmpRationalNumber> const&);
1103template storm::GmpRationalNumber max(storm::GmpRationalNumber const& first, storm::GmpRationalNumber const& second);
1104template storm::GmpRationalNumber min(storm::GmpRationalNumber const& first, storm::GmpRationalNumber const& second);
1105template storm::GmpRationalNumber round(storm::GmpRationalNumber const& number);
1106template std::string to_string(storm::GmpRationalNumber const& value);
1107template uint64_t numDigits(const storm::GmpRationalNumber& number);
1108#endif
1109
1110#if defined(STORM_HAVE_CARL) && defined(STORM_HAVE_GMP) && defined(STORM_HAVE_CLN)
1111#endif
1112
1113#ifdef STORM_HAVE_CARL
1114// Instantiations for rational function.
1115template RationalFunction one();
1116template RationalFunction zero();
1117
1118template bool isNan(RationalFunction const&);
1119
1120// Instantiations for polynomials.
1121template Polynomial one();
1122template Polynomial zero();
1123
1124// Instantiations for intervals.
1125template Interval one();
1126template Interval zero();
1127template bool isOne(Interval const& value);
1128template bool isZero(Interval const& value);
1129template bool isInfinity(Interval const& value);
1130template bool isAlmostZero(Interval const& value);
1131
1132template std::string to_string(storm::Interval const& value);
1133#endif
1134
1135} // namespace utility
1136} // namespace storm
#define STORM_LOG_WARN(message)
Definition logging.h:25
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
ValueType max(ValueType const &first, ValueType const &second)
bool isOne(ValueType const &a)
Definition constants.cpp:37
NumberTraits< RationalType >::IntegerType denominator(RationalType const &number)
NumberTraits< RationalType >::IntegerType numerator(RationalType const &number)
bool isConstant(ValueType const &)
Definition constants.cpp:67
ValueType simplify(ValueType value)
ValueType min(ValueType const &first, ValueType const &second)
ValueType sin(ValueType const &number)
bool isAlmostZero(ValueType const &a)
Definition constants.cpp:57
bool isAlmostOne(ValueType const &a)
Definition constants.cpp:62
ValueType floor(ValueType const &number)
std::pair< ValueType, ValueType > asFraction(ValueType const &number)
bool isZero(ValueType const &a)
Definition constants.cpp:42
ValueType minimum(std::vector< ValueType > const &values)
ValueType ceil(ValueType const &number)
bool isInteger(ValueType const &number)
Definition constants.cpp:77
ValueType abs(ValueType const &number)
ValueType zero()
Definition constants.cpp:27
ValueType infinity()
Definition constants.cpp:32
bool isNan(ValueType const &)
Definition constants.cpp:47
std::string to_string(ValueType const &value)
std::pair< ValueType, ValueType > minmax(std::vector< ValueType > const &values)
NumberTraits< ValueType >::IntegerType trunc(ValueType const &number)
std::pair< IntegerType, IntegerType > divide(IntegerType const &dividend, IntegerType const &divisor)
(Integer-)Divides the dividend by the divisor and returns the result plus the remainder.
IntegerType mod(IntegerType const &first, IntegerType const &second)
ValueType pow(ValueType const &value, int_fast64_t exponent)
ValueType one()
Definition constants.cpp:22
ValueType log(ValueType const &number)
ValueType maximum(std::vector< ValueType > const &values)
ValueType cos(ValueType const &number)
ValueType sqrt(ValueType const &number)
uint64_t numDigits(ValueType const &number)
bool isInfinity(ValueType const &a)
Definition constants.cpp:72
ValueType log10(ValueType const &number)
ValueType round(ValueType const &number)
TargetType convertNumber(SourceType const &number)
Definition constants.cpp:99
LabParser.cpp.
carl::Interval< double > Interval
Interval type.
carl::RationalFunction< Polynomial, true > RationalFunction