13template<
typename ParametricType>
18template<
typename ParametricType>
20 : lowerBoundaries(lowerBoundaries), upperBoundaries(upperBoundaries) {
24template<
typename ParametricType>
26 : lowerBoundaries(lowerBoundaries), upperBoundaries(upperBoundaries) {
30template<
typename ParametricType>
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});
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);
46 this->splitThreshold = variables.size();
49template<
typename ParametricType>
51 return this->variables;
54template<
typename ParametricType>
57 return this->sortedOnDifference;
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;
68template<
typename ParametricType>
70 for (
auto itr = lowerBoundaries.begin(); itr != lowerBoundaries.end(); ++itr) {
71 if (itr->first.name().compare(varName) == 0) {
76 "Tried to find a lower boundary for variableName " << varName <<
" which is not specified by this region");
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;
87template<
typename ParametricType>
89 for (
auto itr = upperBoundaries.begin(); itr != upperBoundaries.end(); ++itr) {
90 if (itr->first.name().compare(varName) == 0) {
95 "Tried to find an upper boundary for variableName " << varName <<
" which is not specified by this region");
98template<
typename ParametricType>
100 return getUpperBoundary(variable) - getLowerBoundary(variable);
103template<
typename ParametricType>
105 return getUpperBoundary(varName) - getLowerBoundary(varName);
108template<
typename ParametricType>
110 return (getLowerBoundary(variable) + getUpperBoundary(variable)) / 2;
113template<
typename ParametricType>
115 return (getLowerBoundary(varName) + getUpperBoundary(varName)) / 2;
118template<
typename ParametricType>
120 return upperBoundaries;
123template<
typename ParametricType>
125 return lowerBoundaries;
128template<
typename ParametricType>
130 std::set<VariableType>
const& consideredVariables)
const {
131 std::size_t
const numOfVariables = consideredVariables.size();
132 STORM_LOG_THROW(numOfVariables <= std::numeric_limits<std::size_t>::digits, storm::exceptions::OutOfRangeException,
133 "Number of variables " << numOfVariables <<
" is too high.");
134 std::size_t
const numOfVertices = std::pow(2, numOfVariables);
135 std::vector<Valuation> resultingVector(numOfVertices);
137 for (uint_fast64_t vertexId = 0; vertexId < numOfVertices; ++vertexId) {
141 uint_fast64_t variableIndex = 0;
143 for (
auto variable : consideredVariables) {
144 if ((vertexId >> variableIndex) % 2 == 0) {
145 resultingVector[vertexId].insert(std::pair<VariableType, CoefficientType>(variable, getLowerBoundary(variable)));
147 resultingVector[vertexId].insert(std::pair<VariableType, CoefficientType>(variable, getUpperBoundary(variable)));
152 return resultingVector;
155template<
typename ParametricType>
157 return this->getLowerBoundaries();
160template<
typename ParametricType>
163 for (
auto const& variable : this->variables) {
164 result.emplace(variable, getCenter(variable));
169template<
typename ParametricType>
172 for (
auto const& variable : this->variables) {
173 if (this->getUpperBoundary(variable) != this->getLowerBoundary(variable)) {
174 result *= (this->getUpperBoundary(variable) - this->getLowerBoundary(variable));
179 result /= utility::convertNumber<CoefficientType>(2);
185template<
typename ParametricType>
187 for (
auto const& variable : this->variables) {
189 "Tried to check if a point is in a region, but the point does not contain a value for variable " << variable);
190 auto pointEntry = point.find(variable)->second;
191 if (pointEntry < this->getLowerBoundary(variable) || pointEntry > this->getUpperBoundary(variable)) {
198template<
typename ParametricType>
200 return split(splittingPoint, regionVector, variables, {});
203template<
typename ParametricType>
205 const std::set<VariableType>& consideredVariables,
const std::set<VariableType>& discreteVariables)
const {
206 std::set<VariableType> vertexVariables = consideredVariables;
209 for (
auto const& var : discreteVariables) {
210 if (this->getDifference(var) == storm::utility::zero<CoefficientType>()) {
211 vertexVariables.erase(var);
215 auto vertices = getVerticesOfRegion(vertexVariables);
217 for (
auto const& vertex : vertices) {
219 Valuation subLower, subUpper;
220 for (
auto variableBound : this->lowerBoundaries) {
221 VariableType variable = variableBound.first;
222 auto vertexEntry = vertex.find(variable);
223 if (vertexEntry != vertex.end()) {
224 if (discreteVariables.find(variable) != discreteVariables.end()) {
228 subLower.insert(
typename Valuation::value_type(variable, vertexEntry->second));
229 subUpper.insert(
typename Valuation::value_type(variable, vertexEntry->second));
231 auto splittingPointEntry = splittingPoint.find(variable);
232 subLower.insert(
typename Valuation::value_type(variable, std::min(vertexEntry->second, splittingPointEntry->second)));
233 subUpper.insert(
typename Valuation::value_type(variable, std::max(vertexEntry->second, splittingPointEntry->second)));
236 subLower.insert(
typename Valuation::value_type(variable, getLowerBoundary(variable)));
237 subUpper.insert(
typename Valuation::value_type(variable, getUpperBoundary(variable)));
241 ParameterRegion<ParametricType> subRegion(std::move(subLower), std::move(subUpper));
244 regionVector.push_back(std::move(subRegion));
249template<
typename ParametricType>
251 std::stringstream regionstringstream;
252 if (boundariesAsDouble) {
253 for (
auto var : this->getVariables()) {
254 regionstringstream << storm::utility::convertNumber<double>(this->getLowerBoundary(var));
255 regionstringstream <<
"<=";
256 regionstringstream << var;
257 regionstringstream <<
"<=";
258 regionstringstream << storm::utility::convertNumber<double>(this->getUpperBoundary(var));
259 regionstringstream <<
",";
262 for (
auto var : this->getVariables()) {
263 regionstringstream << this->getLowerBoundary(var);
264 regionstringstream <<
"<=";
265 regionstringstream << var;
266 regionstringstream <<
"<=";
267 regionstringstream << this->getUpperBoundary(var);
268 regionstringstream <<
",";
271 std::string regionstring = regionstringstream.str();
273 regionstring = regionstring.substr(0, regionstring.length() - 1) +
";";
277template<
typename ParametricType>
279 auto varsRegion = getVariables();
281 for (
auto var : varsRegion) {
282 if (std::find(varsSubRegion.begin(), varsSubRegion.end(), var) != varsSubRegion.end()) {
283 if (getLowerBoundary(var) > subRegion.
getLowerBoundary(var) || getUpperBoundary(var) < getUpperBoundary(var)) {
293template<
typename ParametricType>
296 auto val = this->getCenterPoint();
300 val[monResEntry.first] =
storm::solver::minimize(dir) ? getLowerBoundary(monResEntry.first) : getUpperBoundary(monResEntry.first);
302 val[monResEntry.first] =
storm::solver::maximize(dir) ? getLowerBoundary(monResEntry.first) : getUpperBoundary(monResEntry.first);
309template<
typename ParametricType>
311 std::set<VariableType>
const& monIncrParameters,
312 std::set<VariableType>
const& monDecrParameters)
const {
313 auto val = this->getCenterPoint();
314 for (
auto var : monIncrParameters) {
317 for (
auto var : monDecrParameters) {
324template<
typename ParametricType>
329template<
typename ParametricType>
334template<
typename ParametricType>
340#ifdef STORM_HAVE_CARL
341template class ParameterRegion<storm::RationalFunction>;
342template std::ostream& operator<<(std::ostream& out, ParameterRegion<storm::RationalFunction>
const& region);
std::map< VariableType, Monotonicity > const & getMonotonicityResult() const
Returns the results so far.
bool isDoneForVar(VariableType) const
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
bool contains(Valuation const &point) const
Returns whether the given point is in this region.
CoefficientType const & getLowerBoundary(VariableType const &variable) const
CoefficientType getBoundParent()
void split(Valuation const &splittingPoint, std::vector< ParameterRegion< ParametricType > > ®ionVector) 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.
CoefficientType getCenter(const std::string varName) const
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_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
bool constexpr maximize(OptimizationDirection d)
bool constexpr minimize(OptimizationDirection d)
bool isZero(ValueType const &a)