Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ApplyFiniteSchedulerToPomdp.cpp
Go to the documentation of this file.
2
6
7namespace storm {
8namespace transformer {
10 if (mode == "standard") {
12 } else if (mode == "simple-linear") {
14 } else if (mode == "simple-linear-inverse") {
16 } else {
17 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "Mode " << mode << " not known.");
18 }
19}
20
22 RationalFunctionConstructor(std::shared_ptr<RawPolynomialCache> const& cache) : cache(cache) {}
23
28
29 std::shared_ptr<RawPolynomialCache> cache;
30};
31
32template<typename ValueType>
33std::shared_ptr<RawPolynomialCache> getCache(storm::models::sparse::Pomdp<ValueType> const&) {
34 return std::make_shared<RawPolynomialCache>();
35}
36
37template<>
38std::shared_ptr<RawPolynomialCache> getCache(storm::models::sparse::Pomdp<storm::RationalFunction> const& model) {
39 for (auto const& entry : model.getTransitionMatrix()) {
40 if (!entry.getValue().isConstant()) {
41 return entry.getValue().nominatorAsPolynomial().pCache();
42 }
43 }
44 return std::make_shared<RawPolynomialCache>();
45}
46
47template<typename ValueType>
48std::unordered_map<uint32_t, std::vector<storm::RationalFunction>> ApplyFiniteSchedulerToPomdp<ValueType>::getObservationChoiceWeights(
49 PomdpFscApplicationMode applicationMode) const {
50 std::unordered_map<uint32_t, std::vector<storm::RationalFunction>> res;
51 RationalFunctionConstructor ratFuncConstructor(getCache(pomdp));
52
53 for (uint64_t state = 0; state < pomdp.getNumberOfStates(); ++state) {
54 auto observation = pomdp.getObservation(state);
55 auto it = res.find(observation);
56 if (it == res.end()) {
57 std::vector<storm::RationalFunction> weights;
58 storm::RationalFunction collected = storm::utility::one<storm::RationalFunction>();
59 storm::RationalFunction lastWeight = storm::utility::one<storm::RationalFunction>();
60 for (uint64_t a = 0; a < pomdp.getNumberOfChoices(state) - 1; ++a) {
61 std::string varName = "p" + std::to_string(observation) + "_" + std::to_string(a);
62 storm::RationalFunction var = ratFuncConstructor.translate(storm::createRFVariable(varName));
63 if (applicationMode == PomdpFscApplicationMode::SIMPLE_LINEAR) {
64 weights.push_back(collected * var);
65 collected *= storm::utility::one<storm::RationalFunction>() - var;
66 } else if (applicationMode == PomdpFscApplicationMode::SIMPLE_LINEAR_INVERSE) {
67 weights.push_back(collected * (storm::utility::one<storm::RationalFunction>() - var));
68 collected *= var;
69 } else if (applicationMode == PomdpFscApplicationMode::STANDARD) {
70 weights.push_back(var);
71 }
72 lastWeight -= weights.back();
73 }
74 weights.push_back(lastWeight);
75 res.emplace(observation, weights);
76 }
77 STORM_LOG_ASSERT(it == res.end() || it->second.size() == pomdp.getNumberOfChoices(state),
78 "Number of choices must be equal for every state with same number of actions");
79 }
80 return res;
81}
82
83template<typename ValueType>
84std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> ApplyFiniteSchedulerToPomdp<ValueType>::transform(
85 PomdpFscApplicationMode applicationMode) const {
86 STORM_LOG_THROW(pomdp.isCanonic(), storm::exceptions::IllegalArgumentException, "POMDP needs to be canonic");
88
89 uint64_t nrStates = pomdp.getNumberOfStates();
90 std::unordered_map<uint32_t, std::vector<storm::RationalFunction>> observationChoiceWeights = getObservationChoiceWeights(applicationMode);
92
93 for (uint64_t state = 0; state < nrStates; ++state) {
94 auto const& weights = observationChoiceWeights.at(pomdp.getObservation(state));
95 std::map<uint64_t, storm::RationalFunction> weightedTransitions;
96 for (uint64_t action = 0; action < pomdp.getNumberOfChoices(state); ++action) {
97 auto ratSum = storm::utility::zero<storm::RationalFunction>();
98 uint64_t nrEntries = pomdp.getTransitionMatrix().getRow(state, action).getNumberOfEntries();
99 uint64_t currEntry = 1;
100 for (auto const& entry : pomdp.getTransitionMatrix().getRow(state, action)) {
101 auto it = weightedTransitions.find(entry.getColumn());
102 auto entryVal = storm::utility::convertNumber<storm::RationalFunction>(entry.getValue());
103 ratSum += entryVal;
104 if (currEntry == nrEntries && storm::utility::one<storm::RationalFunction>() - ratSum != storm::utility::zero<storm::RationalFunction>()) {
105 // In case there are numeric problems with the conversion, we simply add the lost mass to the last value
106 entryVal += (storm::utility::one<storm::RationalFunction>() - ratSum);
107 }
108 if (it == weightedTransitions.end()) {
109 weightedTransitions[entry.getColumn()] = entryVal * weights[action];
110 } else {
111 it->second += entryVal * weights[action];
112 }
113 ++currEntry;
114 }
115 }
116 for (auto const& entry : weightedTransitions) {
117 smb.addNextValue(state, entry.first, entry.second);
118 }
119 }
120 modelComponents.transitionMatrix = smb.build();
121
122 for (auto const& pomdpRewardModel : pomdp.getRewardModels()) {
123 std::vector<storm::RationalFunction> stateRewards;
124
125 if (pomdpRewardModel.second.hasStateRewards()) {
126 stateRewards = storm::utility::vector::convertNumericVector<storm::RationalFunction>(pomdpRewardModel.second.getStateRewardVector());
127 } else {
128 stateRewards.resize(nrStates, storm::utility::zero<storm::RationalFunction>());
129 }
130 if (pomdpRewardModel.second.hasStateActionRewards()) {
131 std::vector<ValueType> pomdpActionRewards = pomdpRewardModel.second.getStateActionRewardVector();
132 for (uint64_t state = 0; state < nrStates; ++state) {
133 auto& stateReward = stateRewards[state];
134 auto const& weights = observationChoiceWeights.at(pomdp.getObservation(state));
135 uint64_t offset = pomdp.getTransitionMatrix().getRowGroupIndices()[state];
136 for (uint64_t action = 0; action < pomdp.getNumberOfChoices(state); ++action) {
137 if (!storm::utility::isZero(pomdpActionRewards[offset + action])) {
138 stateReward += storm::utility::convertNumber<storm::RationalFunction>(pomdpActionRewards[offset + action]) * weights[action];
139 }
140 }
141 }
142 }
144 modelComponents.rewardModels.emplace(pomdpRewardModel.first, std::move(rewardModel));
145 }
146
147 modelComponents.stateLabeling = pomdp.getStateLabeling();
148 modelComponents.stateValuations = pomdp.getOptionalStateValuations();
149
150 return std::make_shared<storm::models::sparse::Dtmc<storm::RationalFunction>>(modelComponents);
151}
152
154
157} // namespace transformer
158} // namespace storm
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
Definition Model.cpp:199
This class represents a partially observable Markov decision process.
Definition Pomdp.h:13
A class that can be used to build a sparse matrix by adding value by value.
void addNextValue(index_type row, index_type column, value_type const &value)
Sets the matrix entry at the given row and column to the given value.
SparseMatrix< value_type > build(index_type overriddenRowCount=0, index_type overriddenColumnCount=0, index_type overriddenRowGroupCount=0)
std::shared_ptr< storm::models::sparse::Model< storm::RationalFunction > > transform(PomdpFscApplicationMode applicationMode=PomdpFscApplicationMode::SIMPLE_LINEAR) const
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
std::shared_ptr< RawPolynomialCache > getCache(storm::models::sparse::Pomdp< ValueType > const &)
PomdpFscApplicationMode parsePomdpFscApplicationMode(std::string const &mode)
bool isZero(ValueType const &a)
Definition constants.cpp:39
RationalFunctionVariable createRFVariable(std::string const &name)
carl::Variable RationalFunctionVariable
carl::RationalFunction< Polynomial, true > RationalFunction
carl::MultivariatePolynomial< RationalFunctionCoefficient > RawPolynomial
std::optional< storm::storage::sparse::StateValuations > stateValuations
std::unordered_map< std::string, RewardModelType > rewardModels
storm::storage::SparseMatrix< ValueType > transitionMatrix
storm::models::sparse::StateLabeling stateLabeling
storm::RationalFunction translate(storm::RationalFunctionVariable const &var)
RationalFunctionConstructor(std::shared_ptr< RawPolynomialCache > const &cache)