Changes to Storm for revised belief exploration - #1028
Conversation
# Conflicts: # src/storm/logic/BoundedUntilFormula.cpp
| } | ||
| switch (inputModel->getType()) { | ||
| case storm::models::ModelType::Dtmc: | ||
| return std::make_shared<storm::models::sparse::Dtmc<double>>(storm::models::sparse::Dtmc<double>(convertedComponents)); |
There was a problem hiding this comment.
this swtich case is extremely ugly. Is this the standard way to do this? @tquatmann ?
There was a problem hiding this comment.
There is buildModelFromComponents in storm/utility/builder.h.
We still need some switch case like this for the model-specific components (exit rates for MAs, player data for SMG etc
|
Thanks for the changes. I have two more nitpicky comments and would love to get @tquatmann input on the case black. |
|
I added instantiations for interval models in the transformer; this required a rework of how the different, unique reward vectors are stored and identified. I decided to to implement a potentially slower, but more readable solution. I don't think this should be a bottleneck. |
tquatmann
left a comment
There was a problem hiding this comment.
Thanks! After looking into my comments, this PR should be good to go imo.
| if (!convertedComponents.transitionMatrix.isProbabilistic(precision)) { | ||
| convertedComponents.transitionMatrix.divideRowsInPlace(convertedComponents.transitionMatrix.getRowSumVector()); | ||
| } |
There was a problem hiding this comment.
imo, this should rather go through each row individually, compute the row sum and (if necessary) scale the matrix values.
Currently, this unnecessarily allocates memory for the entire rowSumVector and also touches matrix rows that are actually precise enough.
| std::vector<double> resultVector; | ||
| resultVector.reserve(rewardModel.getStateRewardVector().size()); | ||
| for (auto const& oldValue : rewardModel.getStateRewardVector()) { | ||
| resultVector.push_back(storm::utility::convertNumber<double>(oldValue)); | ||
| } | ||
| optionalStateRewardVector = resultVector; |
There was a problem hiding this comment.
Can be simplified to
| std::vector<double> resultVector; | |
| resultVector.reserve(rewardModel.getStateRewardVector().size()); | |
| for (auto const& oldValue : rewardModel.getStateRewardVector()) { | |
| resultVector.push_back(storm::utility::convertNumber<double>(oldValue)); | |
| } | |
| optionalStateRewardVector = resultVector; | |
| optionalStateRewardVector = storm::utility::vector::convertNumericVector<double>(rewardModel.getStateRewardVector()); |
(same below)
| } | ||
| switch (inputModel->getType()) { | ||
| case storm::models::ModelType::Dtmc: | ||
| return std::make_shared<storm::models::sparse::Dtmc<double>>(storm::models::sparse::Dtmc<double>(convertedComponents)); |
There was a problem hiding this comment.
There is buildModelFromComponents in storm/utility/builder.h.
We still need some switch case like this for the model-specific components (exit rates for MAs, player data for SMG etc
| std::vector<double> resultVector; | ||
| resultVector.reserve(ctmc->getExitRateVector().size()); | ||
| for (auto const& oldValue : ctmc->getExitRateVector()) { | ||
| resultVector.push_back(storm::utility::convertNumber<double>(oldValue)); | ||
| } | ||
| convertedComponents.exitRates = resultVector; |
There was a problem hiding this comment.
| std::vector<double> resultVector; | |
| resultVector.reserve(ctmc->getExitRateVector().size()); | |
| for (auto const& oldValue : ctmc->getExitRateVector()) { | |
| resultVector.push_back(storm::utility::convertNumber<double>(oldValue)); | |
| } | |
| convertedComponents.exitRates = resultVector; |
We provide the rates in the transition matrix. A dedicated exit rate vector should not be set and will be ignored in this case.
We do need to set rateTransitions = true to indicate that the transitionMatrix contains rates, not probabilities.
| models::sparse::StochasticTwoPlayerGame<double>(convertedComponents)); | ||
| } | ||
| default: | ||
| STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentTypeException, |
There was a problem hiding this comment.
| STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentTypeException, | |
| STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, |
There was a problem hiding this comment.
IllegalArgumentTypeException is more of a storm::settings thing.
| if (oldRewardModel.hasStateRewards()) { | ||
| rewValue += oldRewardModel.getStateReward(oldState); | ||
| } |
There was a problem hiding this comment.
For continuous time models, state rewards are earned over time. Collapsing them together with the action rewards like this is usually incorrect. However, for discrete-time models, it's probably convenient to merge the rewards.
I suggest this change here:
| if (oldRewardModel.hasStateRewards()) { | |
| rewValue += oldRewardModel.getStateReward(oldState); | |
| } | |
| if (originalModel->isDiscreteTimeModel() && oldRewardModel.hasStateRewards()) { | |
| rewValue += oldRewardModel.getStateReward(oldState); | |
| } |
and below something like
std::optional<std::vector<ValueType>> newStateRewards;
if (originalModel->isContinuousTimeModel() && oldRewardModel.hasStateRewards()) {
newStateRewards.emplace(numStates, storm::utility::zero<ValueType>())
for (uint64_t origState = 0; origState < originalModel->getNumberOfStates(); ++origState) {
uint64_t const newState = originalToNewIndex[origState];
newStateRewards.value()[newState] = oldRewardModel.getStateReward(oldState);
}
}
RewardModelType newRewardModel(newStateRewards, std::move(newActionRewardVector));| auto const& transitions = originalModel->getTransitionMatrix(); | ||
| for (uint64_t row = 0; row < transitions.getRowCount(); ++row) { | ||
| rewardTransitionIterator.forEachRowEntry( | ||
| row, true, [&incomingRewards](uint64_t column, RewardValueType, detail::MultiRewardVector<RewardValueType> const& rewards) { |
There was a problem hiding this comment.
| row, true, [&incomingRewards](uint64_t column, RewardValueType, detail::MultiRewardVector<RewardValueType> const& rewards) { | |
| row, true, [&incomingRewards](uint64_t column, ValueType, detail::MultiRewardVector<RewardValueType> const& rewards) { |
|
Thanks for the comments, I have now added the requested changes. For the switch-case in the ToDoubleTransformer, I use a single buildModelFromComponents now, but opted to still include all cases explicitly. This way, if new model types are added, the default is to throw an exception instead of silently accepting it, which may lead to erroneous behaviour. |
tquatmann
left a comment
There was a problem hiding this comment.
LGTM! Just a very small nitpick.
This PR contains changes to Storm outside Storm-POMDP for the revised belief exploration implementation, see PR #1004.