Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
Distribution.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <iostream>
5
13
14namespace storm {
15namespace storage {
16
17template<typename ValueType, typename StateType>
19 // Intentionally left empty.
20}
21
22template<typename ValueType, typename StateType>
24 this->distribution.reserve(size);
25}
26
27template<typename ValueType, typename StateType>
29 this->distribution.clear();
30}
31
32template<typename ValueType, typename StateType>
34 container_type newDistribution;
35 std::set_union(this->distribution.begin(), this->distribution.end(), other.distribution.begin(), other.distribution.end(),
36 std::inserter(newDistribution, newDistribution.begin()));
37 this->distribution = std::move(newDistribution);
38}
40template<typename ValueType, typename StateType>
42 storm::utility::ConstantsComparator<ValueType> const& comparator) const {
43 // We need to check equality by ourselves, because we need to account for epsilon differences.
44 if (this->distribution.size() != other.distribution.size()) {
45 return false;
46 }
47
48 auto first1 = this->distribution.begin();
49 auto last1 = this->distribution.end();
50 auto first2 = other.distribution.begin();
51
52 for (; first1 != last1; ++first1, ++first2) {
53 if (first1->first != first2->first) {
54 return false;
55 }
56 if (!comparator.isEqual(first1->second, first2->second)) {
57 return false;
58 }
59 }
61 return true;
62}
63
64template<typename ValueType, typename StateType>
65void Distribution<ValueType, StateType>::addProbability(StateType const& state, ValueType const& probability) {
66 auto [iterator, newEntry] = this->distribution.try_emplace(state, probability);
67 if (!newEntry) {
68 iterator->second += probability;
69 }
71
72template<typename ValueType, typename StateType>
73void Distribution<ValueType, StateType>::removeProbability(StateType const& state, ValueType const& probability,
75 auto it = this->distribution.find(state);
76 STORM_LOG_ASSERT(it != this->distribution.end(), "Cannot remove probability, because the state is not in the support of the distribution.");
77 it->second -= probability;
78 if (comparator.isZero(it->second)) {
79 this->distribution.erase(it);
80 }
82
83template<typename ValueType, typename StateType>
84void Distribution<ValueType, StateType>::shiftProbability(StateType const& fromState, StateType const& toState, ValueType const& probability,
86 removeProbability(fromState, probability, comparator);
87 addProbability(toState, probability);
88}
90template<typename ValueType, typename StateType>
94
95template<typename ValueType, typename StateType>
97 return this->distribution.begin();
98}
99
100template<typename ValueType, typename StateType>
104
105template<typename ValueType, typename StateType>
109
110template<typename ValueType, typename StateType>
112 return this->distribution.end();
113}
114
115template<typename ValueType, typename StateType>
119
120template<typename ValueType, typename StateType>
121void Distribution<ValueType, StateType>::scale(StateType const& state) {
122 auto probabilityIterator = this->distribution.find(state);
123 if (probabilityIterator != this->distribution.end()) {
124 ValueType scaleValue = storm::utility::one<ValueType>() / probabilityIterator->second;
125 this->distribution.erase(probabilityIterator);
126
127 for (auto& entry : this->distribution) {
128 entry.second *= scaleValue;
129 }
130 }
131}
132
133template<typename ValueType, typename StateType>
135 return this->distribution.size();
136}
137
138template<typename ValueType, typename StateType>
139std::ostream& operator<<(std::ostream& out, Distribution<ValueType, StateType> const& distribution) {
140 out << "{";
141 for (auto const& entry : distribution) {
142 out << "[" << entry.second << ": " << entry.first << "], ";
143 }
144 out << "}";
145
146 return out;
148
149template<typename ValueType, typename StateType>
151 storm::utility::ConstantsComparator<ValueType> const& comparator) const {
152 if (this->size() != other.size()) {
153 return this->size() < other.size();
154 }
155 auto firstIt = this->begin();
156 auto firstIte = this->end();
157 auto secondIt = other.begin();
158 for (; firstIt != firstIte; ++firstIt, ++secondIt) {
159 // If the two blocks already differ, we can decide which distribution is smaller.
160 if (firstIt->first != secondIt->first) {
161 return firstIt->first < secondIt->first;
162 }
164 // If the blocks are the same, but the probability differs, we can also decide which distribution is smaller.
165 if (!comparator.isEqual(firstIt->second, secondIt->second)) {
166 return comparator.isLess(firstIt->second, secondIt->second);
167 }
168 }
169 return false;
170}
171
172template<typename ValueType, typename StateType>
173ValueType Distribution<ValueType, StateType>::getProbability(StateType const& state) const {
174 auto it = this->distribution.find(state);
175 if (it == this->distribution.end()) {
177 } else {
178 return it->second;
179 }
180}
181
182template<typename ValueType, typename StateType>
184 ValueType sum = storm::utility::zero<ValueType>();
185 for (auto const& entry : distribution) {
186 sum += entry.second;
187 }
188 for (auto& entry : distribution) {
189 entry.second /= sum;
190 }
191}
192
193template<typename ValueType, typename StateType>
194typename std::enable_if<!std::is_same<ValueType, storm::RationalFunction>::value, StateType>::type sample(
195 boost::container::flat_map<StateType, ValueType> const& distr, ValueType const& quantile) {
196 ValueType sum = storm::utility::zero<ValueType>();
197 for (auto const& entry : distr) {
198 sum += entry.second;
199 if (quantile < sum) {
200 return entry.first;
201 }
202 }
203 STORM_LOG_ASSERT(false, "This point should not be reached.");
204 return 0;
205}
206
207template<typename ValueType, typename StateType>
208typename std::enable_if<std::is_same<ValueType, storm::RationalFunction>::value, StateType>::type sample(
209 boost::container::flat_map<StateType, storm::RationalFunction> const& distr, storm::RationalFunction const& quantile) {
210 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "We cannot sample from parametric distributions.");
211}
212
213template<typename ValueType, typename StateType>
214StateType Distribution<ValueType, StateType>::sampleFromDistribution(const ValueType& quantile) const {
215 return sample<ValueType, StateType>(this->distribution, quantile);
216}
217
218template class Distribution<double>;
219template std::ostream& operator<<(std::ostream& out, Distribution<double> const& distribution);
220template class Distribution<double, uint64_t>;
221template std::ostream& operator<<(std::ostream& out, Distribution<double, uint_fast64_t> const& distribution);
222
224template std::ostream& operator<<(std::ostream& out, Distribution<storm::RationalNumber> const& distribution);
226template std::ostream& operator<<(std::ostream& out, Distribution<storm::RationalNumber, uint_fast64_t> const& distribution);
227
229template std::ostream& operator<<(std::ostream& out, Distribution<storm::RationalFunction> const& distribution);
231template std::ostream& operator<<(std::ostream& out, Distribution<storm::RationalFunction, uint64_t> const& distribution);
232
233template class Distribution<storm::Interval>;
234template std::ostream& operator<<(std::ostream& out, Distribution<storm::Interval> const& distribution);
236template std::ostream& operator<<(std::ostream& out, Distribution<storm::Interval, uint64_t> const& distribution);
237
239template std::ostream& operator<<(std::ostream& out, Distribution<storm::RationalInterval> const& distribution);
241template std::ostream& operator<<(std::ostream& out, Distribution<storm::RationalInterval, uint64_t> const& distribution);
242
243} // namespace storage
244} // namespace storm
void shiftProbability(StateType const &fromState, StateType const &toState, ValueType const &probability, storm::utility::ConstantsComparator< ValueType > const &comparator)
Removes the probability mass from one state and adds it to another.
iterator end()
Retrieves an iterator past the elements in this distribution.
void reserve(uint64_t size)
void addProbability(StateType const &state, ValueType const &probability)
Assigns the given state the given probability under this distribution.
boost::container::flat_map< uint32_t, ValueType > container_type
void removeProbability(StateType const &state, ValueType const &probability, storm::utility::ConstantsComparator< ValueType > const &comparator)
Removes the given probability mass of going to the given state.
const_iterator cend() const
Retrieves an iterator past the elements in this distribution.
bool less(Distribution< ValueType, StateType > const &other, storm::utility::ConstantsComparator< ValueType > const &comparator) const
void normalize()
Normalizes the distribution such that the values sum up to one.
container_type::const_iterator const_iterator
const_iterator cbegin() const
Retrieves an iterator to the elements in this distribution.
std::size_t size() const
Retrieves the size of the distribution, i.e.
bool equals(Distribution< ValueType, StateType > const &other, storm::utility::ConstantsComparator< ValueType > const &comparator) const
Checks whether the two distributions specify the same probabilities to go to the same states.
StateType sampleFromDistribution(ValueType const &quantile) const
Given a value q, find the event in the ordered distribution that corresponds to this prob.
iterator begin()
Retrieves an iterator to the elements in this distribution.
ValueType getProbability(StateType const &state) const
Returns the probability of the given state.
Distribution()
Creates an empty distribution.
container_type::iterator iterator
void add(Distribution const &other)
Adds the given distribution to the current one.
void scale(StateType const &state)
Scales the distribution by multiplying all the probabilities with 1/p where p is the probability of m...
void clear()
Removes all entries from this distribution.
bool isLess(ValueType const &value1, ValueType const &value2) const
bool isZero(ValueType const &value) const
bool isEqual(ValueType const &value1, ValueType const &value2) const
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
std::enable_if<!std::is_same< ValueType, storm::RationalFunction >::value, StateType >::type sample(boost::container::flat_map< StateType, ValueType > const &distr, ValueType const &quantile)
std::ostream & operator<<(std::ostream &out, ParameterRegion< ParametricType > const &region)
ValueType zero()
Definition constants.cpp:26
ValueType one()
Definition constants.cpp:21
carl::RationalFunction< Polynomial, true > RationalFunction