Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ParameterRegion.cpp
Go to the documentation of this file.
2
3#include <limits>
4
9
10namespace storm {
11namespace storage {
12
13template<typename ParametricType>
17
18template<typename ParametricType>
19ParameterRegion<ParametricType>::ParameterRegion(Valuation const& lowerBoundaries, Valuation const& upperBoundaries)
20 : lowerBoundaries(lowerBoundaries), upperBoundaries(upperBoundaries) {
21 init();
22}
23
24template<typename ParametricType>
26 : lowerBoundaries(lowerBoundaries), upperBoundaries(upperBoundaries) {
27 init();
30template<typename ParametricType>
32 // check whether both mappings map the same variables, check that lower boundary <= upper boundary, and pre-compute the set of variables
33 for (auto const& variableWithLowerBoundary : this->lowerBoundaries) {
34 auto variableWithUpperBoundary = this->upperBoundaries.find(variableWithLowerBoundary.first);
35 STORM_LOG_THROW((variableWithUpperBoundary != upperBoundaries.end()), storm::exceptions::InvalidArgumentException,
36 "Could not create region. No upper boundary specified for Variable " << variableWithLowerBoundary.first);
37 STORM_LOG_THROW((variableWithLowerBoundary.second <= variableWithUpperBoundary->second), storm::exceptions::InvalidArgumentException,
38 "Could not create region. The lower boundary for " << variableWithLowerBoundary.first << " is larger then the upper boundary");
39 this->variables.insert(variableWithLowerBoundary.first);
40 this->sortedOnDifference.insert({variableWithLowerBoundary.second - variableWithUpperBoundary->second, variableWithLowerBoundary.first});
41 }
42 for (auto const& variableWithBoundary : this->upperBoundaries) {
43 STORM_LOG_THROW((this->variables.find(variableWithBoundary.first) != this->variables.end()), storm::exceptions::InvalidArgumentException,
44 "Could not create region. No lower boundary specified for Variable " << variableWithBoundary.first);
45 }
46 this->splitThreshold = variables.size();
48
49template<typename ParametricType>
50std::set<typename ParameterRegion<ParametricType>::VariableType> const& ParameterRegion<ParametricType>::getVariables() const {
51 return this->variables;
53
54template<typename ParametricType>
55std::multimap<typename ParameterRegion<ParametricType>::CoefficientType, typename ParameterRegion<ParametricType>::VariableType> const&
57 return this->sortedOnDifference;
58}
59
60template<typename ParametricType>
62 auto const& result = lowerBoundaries.find(variable);
63 STORM_LOG_THROW(result != lowerBoundaries.end(), storm::exceptions::InvalidArgumentException,
64 "Tried to find a lower boundary for variable " << variable << " which is not specified by this region");
65 return (*result).second;
66}
67
68template<typename ParametricType>
70 for (auto itr = lowerBoundaries.begin(); itr != lowerBoundaries.end(); ++itr) {
71 if (itr->first.name().compare(varName) == 0) {
72 return (*itr).second;
73 }
74 }
75 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException,
76 "Tried to find a lower boundary for variableName " << varName << " which is not specified by this region");
77}
79template<typename ParametricType>
81 auto const& result = upperBoundaries.find(variable);
82 STORM_LOG_THROW(result != upperBoundaries.end(), storm::exceptions::InvalidArgumentException,
83 "Tried to find an upper boundary for variable " << variable << " which is not specified by this region");
84 return (*result).second;
85}
86
87template<typename ParametricType>
89 for (auto itr = upperBoundaries.begin(); itr != upperBoundaries.end(); ++itr) {
90 if (itr->first.name().compare(varName) == 0) {
91 return (*itr).second;
92 }
93 }
94 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException,
95 "Tried to find an upper boundary for variableName " << varName << " which is not specified by this region");
96}
97
98template<typename ParametricType>
100 return getUpperBoundary(variable) - getLowerBoundary(variable);
101}
102
103template<typename ParametricType>
105 return getUpperBoundary(varName) - getLowerBoundary(varName);
106}
107
108template<typename ParametricType>
112
113template<typename ParametricType>
117
118template<typename ParametricType>
119std::vector<typename ParameterRegion<ParametricType>::Valuation> ParameterRegion<ParametricType>::getVerticesOfRegion(
120 std::set<VariableType> const& consideredVariables) const {
121 std::size_t const numOfVariables = consideredVariables.size();
122 STORM_LOG_THROW(numOfVariables <= std::numeric_limits<std::size_t>::digits, storm::exceptions::OutOfRangeException,
123 "Number of variables " << numOfVariables << " is too high.");
124 std::size_t const numOfVertices = std::pow(2, numOfVariables);
125 std::vector<Valuation> resultingVector(numOfVertices);
126
127 for (uint_fast64_t vertexId = 0; vertexId < numOfVertices; ++vertexId) {
128 // interprete vertexId as a bit sequence
129 // the consideredVariables.size() least significant bits of vertex will always represent the next vertex
130 //(00...0 = lower boundaries for all variables, 11...1 = upper boundaries for all variables)
131 uint_fast64_t variableIndex = 0;
132
133 for (auto variable : consideredVariables) {
134 if ((vertexId >> variableIndex) % 2 == 0) {
135 resultingVector[vertexId].insert(std::pair<VariableType, CoefficientType>(variable, getLowerBoundary(variable)));
136 } else {
137 resultingVector[vertexId].insert(std::pair<VariableType, CoefficientType>(variable, getUpperBoundary(variable)));
138 }
139 ++variableIndex;
140 }
141 }
142 return resultingVector;
143}
144
145template<typename ParametricType>
147 return this->getLowerBoundaries();
148}
149
150template<typename ParametricType>
152 Valuation result;
153 for (auto const& variable : this->variables) {
154 result.insert(typename Valuation::value_type(variable, (this->getLowerBoundary(variable) + this->getUpperBoundary(variable)) / 2));
155 }
156 return result;
157}
158
159template<typename ParametricType>
161 CoefficientType result = storm::utility::one<CoefficientType>();
162 for (auto const& variable : this->variables) {
163 result *= (this->getUpperBoundary(variable) - this->getLowerBoundary(variable));
164 }
165 return result;
166}
167
168template<typename ParametricType>
169void ParameterRegion<ParametricType>::split(Valuation const& splittingPoint, std::vector<ParameterRegion<ParametricType>>& regionVector) const {
170 return split(splittingPoint, regionVector, variables);
171}
172
173template<typename ParametricType>
174void ParameterRegion<ParametricType>::split(Valuation const& splittingPoint, std::vector<storm::storage::ParameterRegion<ParametricType>>& regionVector,
175 const std::set<VariableType>& consideredVariables) const {
176 auto vertices = getVerticesOfRegion(consideredVariables);
177
178 for (auto const& vertex : vertices) {
179 // The resulting subregion is the smallest region containing vertex and splittingPoint.
180 Valuation subLower, subUpper;
181 for (auto variableBound : this->lowerBoundaries) {
182 VariableType variable = variableBound.first;
183 auto vertexEntry = vertex.find(variable);
184 if (vertexEntry != vertex.end()) {
185 auto splittingPointEntry = splittingPoint.find(variable);
186 subLower.insert(typename Valuation::value_type(variable, std::min(vertexEntry->second, splittingPointEntry->second)));
187 subUpper.insert(typename Valuation::value_type(variable, std::max(vertexEntry->second, splittingPointEntry->second)));
188 } else {
189 subLower.insert(typename Valuation::value_type(variable, getLowerBoundary(variable)));
190 subUpper.insert(typename Valuation::value_type(variable, getUpperBoundary(variable)));
191 }
192 }
193
194 ParameterRegion<ParametricType> subRegion(std::move(subLower), std::move(subUpper));
195
196 if (!storm::utility::isZero(subRegion.area())) {
197 regionVector.push_back(std::move(subRegion));
198 }
199 }
200}
201
202template<typename ParametricType>
203std::string ParameterRegion<ParametricType>::toString(bool boundariesAsDouble) const {
204 std::stringstream regionstringstream;
205 if (boundariesAsDouble) {
206 for (auto var : this->getVariables()) {
207 regionstringstream << storm::utility::convertNumber<double>(this->getLowerBoundary(var));
208 regionstringstream << "<=";
209 regionstringstream << var;
210 regionstringstream << "<=";
211 regionstringstream << storm::utility::convertNumber<double>(this->getUpperBoundary(var));
212 regionstringstream << ",";
213 }
214 } else {
215 for (auto var : this->getVariables()) {
216 regionstringstream << this->getLowerBoundary(var);
217 regionstringstream << "<=";
218 regionstringstream << var;
219 regionstringstream << "<=";
220 regionstringstream << this->getUpperBoundary(var);
221 regionstringstream << ",";
222 }
223 }
224 std::string regionstring = regionstringstream.str();
225 // the last comma should actually be a semicolon
226 regionstring = regionstring.substr(0, regionstring.length() - 1) + ";";
227 return regionstring;
228}
229
230template<typename ParametricType>
232 auto varsRegion = getVariables();
233 auto varsSubRegion = subRegion.getVariables();
234 for (auto var : varsRegion) {
235 if (std::find(varsSubRegion.begin(), varsSubRegion.end(), var) != varsSubRegion.end()) {
236 if (getLowerBoundary(var) > subRegion.getLowerBoundary(var) || getUpperBoundary(var) < getUpperBoundary(var)) {
237 return false;
238 }
239 } else {
240 return false;
241 }
242 }
243 return true;
244}
245
246template<typename ParametricType>
249 auto val = this->getCenterPoint();
250 for (auto monResEntry : monRes.getMonotonicityResult()) {
251 if (monRes.isDoneForVar(monResEntry.first)) {
253 val[monResEntry.first] = storm::solver::minimize(dir) ? getLowerBoundary(monResEntry.first) : getUpperBoundary(monResEntry.first);
255 val[monResEntry.first] = storm::solver::maximize(dir) ? getLowerBoundary(monResEntry.first) : getUpperBoundary(monResEntry.first);
256 }
257 }
258 }
259 return val;
260}
261
262template<typename ParametricType>
264 std::set<VariableType> const& monIncrParameters,
265 std::set<VariableType> const& monDecrParameters) const {
266 auto val = this->getCenterPoint();
267 for (auto var : monIncrParameters) {
268 val[var] = storm::solver::minimize(dir) ? getLowerBoundary(var) : getUpperBoundary(var);
269 }
270 for (auto var : monDecrParameters) {
271 val[var] = storm::solver::maximize(dir) ? getLowerBoundary(var) : getUpperBoundary(var);
272 }
273
274 return val;
275}
276
277template<typename ParametricType>
281
282template<typename ParametricType>
284 parentBound = bound;
285}
286
287template<typename ParametricType>
288std::ostream& operator<<(std::ostream& out, ParameterRegion<ParametricType> const& region) {
289 out << region.toString();
290 return out;
291}
292
293#ifdef STORM_HAVE_CARL
294template class ParameterRegion<storm::RationalFunction>;
295template std::ostream& operator<<(std::ostream& out, ParameterRegion<storm::RationalFunction> const& region);
296#endif
297
298} // namespace storage
299} // namespace storm
std::map< VariableType, Monotonicity > getMonotonicityResult() const
Returns the results so far.
storm::utility::parametric::CoefficientType< ParametricType >::type CoefficientType
std::set< VariableType > const & getVariables() const
Valuation getCenterPoint() const
Returns the center point of this region.
CoefficientType area() const
Returns the area of this region.
void setBoundParent(CoefficientType bound)
std::string toString(bool boundariesAsDouble=false) const
storm::utility::parametric::Valuation< ParametricType > Valuation
Valuation const & getLowerBoundaries() const
CoefficientType getDifference(const std::string varName) const
storm::utility::parametric::VariableType< ParametricType >::type VariableType
Valuation getPoint(storm::solver::OptimizationDirection dir, storm::analysis::MonotonicityResult< VariableType > &monRes) const
CoefficientType const & getLowerBoundary(VariableType const &variable) const
void split(Valuation const &splittingPoint, std::vector< ParameterRegion< ParametricType > > &regionVector) const
Splits the region at the given point and inserts the resulting subregions at the end of the given vec...
bool isSubRegion(ParameterRegion< ParametricType > region)
CoefficientType const & getUpperBoundary(VariableType const &variable) const
Valuation getSomePoint() const
Returns some point that lies within this region.
Valuation const & getUpperBoundaries() const
std::multimap< CoefficientType, VariableType > const & getVariablesSorted() const
std::vector< Valuation > getVerticesOfRegion(std::set< VariableType > const &consideredVariables) const
Returns a vector of all possible combinations of lower and upper bounds of the given variables.
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
bool constexpr maximize(OptimizationDirection d)
bool constexpr minimize(OptimizationDirection d)
std::ostream & operator<<(std::ostream &out, ParameterRegion< ParametricType > const &region)
bool isZero(ValueType const &a)
Definition constants.cpp:41
LabParser.cpp.
Definition cli.cpp:18