You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
8.8 KiB
142 lines
8.8 KiB
/*
|
|
* File: Regions.cpp
|
|
* Author: Tim Quatmann
|
|
*
|
|
* Created on May 13, 2015, 12:54 PM
|
|
*/
|
|
|
|
#include <string>
|
|
|
|
#include "src/utility/regions.h"
|
|
#include "src/exceptions/NotImplementedException.h"
|
|
#include "src/exceptions/InvalidArgumentException.h"
|
|
#include "adapters/CarlAdapter.h"
|
|
|
|
namespace storm {
|
|
namespace utility{
|
|
namespace regions {
|
|
|
|
template<typename ParametricType, typename ConstantType>
|
|
void RegionParser<ParametricType, ConstantType>::parseParameterBounds(
|
|
std::map<VariableType, BoundType>& lowerBounds,
|
|
std::map<VariableType, BoundType>& upperBounds,
|
|
std::string const& parameterBoundsString,
|
|
double const precision){
|
|
double actualPrecision = (precision==0.0 ? storm::settings::generalSettings().getPrecision() : precision);
|
|
|
|
std::string::size_type positionOfFirstRelation = parameterBoundsString.find("<=");
|
|
STORM_LOG_THROW(positionOfFirstRelation!=std::string::npos, storm::exceptions::InvalidArgumentException, "When parsing the region" << parameterBoundsString << " I could not find a '<=' after the first number");
|
|
std::string::size_type positionOfSecondRelation = parameterBoundsString.find("<=", positionOfFirstRelation+2);
|
|
STORM_LOG_THROW(positionOfSecondRelation!=std::string::npos, storm::exceptions::InvalidArgumentException, "When parsing the region" << parameterBoundsString << " I could not find a '<=' after the parameter");
|
|
|
|
std::string parameter=parameterBoundsString.substr(positionOfFirstRelation+2,positionOfSecondRelation-(positionOfFirstRelation+2));
|
|
//removes all whitespaces from the parameter string:
|
|
parameter.erase(std::remove_if(parameter.begin(), parameter.end(), isspace), parameter.end());
|
|
STORM_LOG_THROW(parameter.length()>0, storm::exceptions::InvalidArgumentException, "When parsing the region" << parameterBoundsString << " I could not find a parameter");
|
|
double lowerBound, upperBound;
|
|
try{
|
|
lowerBound=std::stod(parameterBoundsString.substr(0,positionOfFirstRelation));
|
|
upperBound=std::stod(parameterBoundsString.substr(positionOfSecondRelation+2));
|
|
}
|
|
catch (std::exception const& exception) {
|
|
STORM_LOG_ERROR("Failed to parse the region: " << parameterBoundsString << ". The correct format for regions is lowerBound<=parameter<=upperbound");
|
|
throw exception;
|
|
}
|
|
|
|
VariableType var = getVariableFromString<VariableType>(parameter);
|
|
BoundType lb = convertNumber<double, BoundType>(lowerBound, true, actualPrecision);
|
|
BoundType ub = convertNumber<double, BoundType>(upperBound, false, actualPrecision);
|
|
lowerBounds.emplace(std::make_pair(var, lb));
|
|
upperBounds.emplace(std::make_pair(var, ub));
|
|
std::cout << "parsed bounds " << parameterBoundsString << ": lb=" << lowerBound << " ub=" << upperBound << " param='" << parameter << "' precision=" << actualPrecision << std::endl;
|
|
}
|
|
|
|
template<typename ParametricType, typename ConstantType>
|
|
typename RegionParser<ParametricType, ConstantType>::ParameterRegion RegionParser<ParametricType, ConstantType>::parseRegion(std::string const& regionString, double precision){
|
|
double actualPrecision = (precision==0.0 ? storm::settings::generalSettings().getPrecision() : precision);
|
|
std::map<VariableType, BoundType> lowerBounds;
|
|
std::map<VariableType, BoundType> upperBounds;
|
|
std::vector<std::string> parameterBounds;
|
|
boost::split(parameterBounds, regionString, boost::is_any_of(","));
|
|
for(auto const& parameterBound : parameterBounds){
|
|
std::cout << "parsing a parameter bound" << std::endl;
|
|
RegionParser<ParametricType, ConstantType>::parseParameterBounds(lowerBounds, upperBounds, parameterBound, actualPrecision);
|
|
std::cout << "created a parameter bound. lower bound has size" << lowerBounds.size() << std::endl;
|
|
std::cout << "parsing a param bound is done" << std::endl;
|
|
}
|
|
return ParameterRegion(lowerBounds, upperBounds);
|
|
}
|
|
|
|
template<typename ParametricType, typename ConstantType>
|
|
std::vector<typename RegionParser<ParametricType, ConstantType>::ParameterRegion> RegionParser<ParametricType, ConstantType>::parseMultipleRegions(std::string const& regionsString, double precision){
|
|
double actualPrecision = (precision==0.0 ? storm::settings::generalSettings().getPrecision() : precision);
|
|
std::vector<ParameterRegion> result;
|
|
std::vector<std::string> regionsStrVec;
|
|
boost::split(regionsStrVec, regionsString, boost::is_any_of(";"));
|
|
for(auto const& regionStr : regionsStrVec){
|
|
std::cout << "parsing a region" << std::endl;
|
|
result.emplace_back(RegionParser<ParametricType, ConstantType>::parseRegion(regionStr, actualPrecision));
|
|
std::cout << "parsing a region is done" << std::endl;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
template<>
|
|
storm::RationalFunction::CoeffType convertNumber<double, storm::RationalFunction::CoeffType>(double const& number, bool const& roundDown, double const& precision){
|
|
double actualPrecision = (precision==0.0 ? storm::settings::generalSettings().getPrecision() : precision);
|
|
uint_fast64_t denominator = 1.0/actualPrecision;
|
|
uint_fast64_t numerator;
|
|
if(roundDown){
|
|
numerator= number*denominator; //this will always round down if necessary
|
|
} else{
|
|
numerator = number*denominator*10; //*10 to look whether we have to round up
|
|
if(numerator%10>0){
|
|
numerator+=10;
|
|
}
|
|
numerator/=10;
|
|
}
|
|
storm::RationalFunction::CoeffType result=numerator;
|
|
result = result/denominator;
|
|
return result;
|
|
}
|
|
|
|
template<>
|
|
storm::RationalFunction convertNumber<double, storm::RationalFunction>(double const& number, bool const& roundDown, double const& precision){
|
|
return storm::RationalFunction(convertNumber<double, storm::RationalFunction::CoeffType>(number, roundDown, precision));
|
|
}
|
|
|
|
template<>
|
|
double convertNumber<cln::cl_RA, double>(cln::cl_RA const& number, bool const& roundDown, double const& precision){
|
|
return cln::double_approx(number);
|
|
}
|
|
|
|
template<typename SourceType, typename TargetType>
|
|
TargetType convertNumber(SourceType const& number, bool const& roundDown, double const& precision){
|
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "number conversion between the given types not implemented");
|
|
}
|
|
|
|
template<>
|
|
storm::Variable getVariableFromString<storm::Variable>(std::string variableString){
|
|
storm::Variable const& var = carl::VariablePool::getInstance().findVariableWithName(variableString);
|
|
STORM_LOG_THROW(var!=carl::Variable::NO_VARIABLE, storm::exceptions::InvalidArgumentException, "Variable '" + variableString + "' could not be found.");
|
|
return var;
|
|
}
|
|
|
|
template<typename VariableType>
|
|
VariableType getVariableFromString(std::string variableString){
|
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Variable from String not implemented for this Type");
|
|
}
|
|
|
|
//explicit instantiations
|
|
#ifdef STORM_HAVE_CARL
|
|
template class RegionParser<storm::RationalFunction, double>;
|
|
|
|
template storm::RationalFunction convertNumber<double, storm::RationalFunction>(double const& number, bool const& roundDown, double const& precision);
|
|
template storm::RationalFunction::CoeffType convertNumber<double, storm::RationalFunction::CoeffType>(double const& number, bool const& roundDown, double const& precision);
|
|
template double convertNumber<cln::cl_RA, double>(storm::RationalFunction::CoeffType const& number, bool const& roundDown, double const& precision);
|
|
|
|
template storm::Variable getVariableFromString<storm::Variable>(std::string variableString);
|
|
#endif
|
|
}
|
|
}
|
|
}
|