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