#include "src/models/sparse/StandardRewardModel.h" #include "src/utility/vector.h" #include "src/exceptions/InvalidOperationException.h" #include "src/adapters/CarlAdapter.h" namespace storm { namespace models { namespace sparse { template StandardRewardModel::StandardRewardModel(boost::optional> const& optionalStateRewardVector, boost::optional> const& optionalStateActionRewardVector, boost::optional> const& optionalTransitionRewardMatrix) : optionalStateRewardVector(optionalStateRewardVector), optionalStateActionRewardVector(optionalStateActionRewardVector), optionalTransitionRewardMatrix(optionalTransitionRewardMatrix) { // Intentionally left empty. } template StandardRewardModel::StandardRewardModel(boost::optional>&& optionalStateRewardVector, boost::optional>&& optionalStateActionRewardVector, boost::optional>&& optionalTransitionRewardMatrix) : optionalStateRewardVector(std::move(optionalStateRewardVector)), optionalStateActionRewardVector(std::move(optionalStateActionRewardVector)), optionalTransitionRewardMatrix(std::move(optionalTransitionRewardMatrix)) { // Intentionally left empty. } template bool StandardRewardModel::hasStateRewards() const { return static_cast(this->optionalStateRewardVector); } template bool StandardRewardModel::hasOnlyStateRewards() const { return static_cast(this->optionalStateRewardVector) && !static_cast(this->optionalStateActionRewardVector) && !static_cast(this->optionalTransitionRewardMatrix); } template std::vector const& StandardRewardModel::getStateRewardVector() const { assert(this->hasStateRewards()); return this->optionalStateRewardVector.get(); } template std::vector& StandardRewardModel::getStateRewardVector() { assert(this->hasStateRewards()); return this->optionalStateRewardVector.get(); } template boost::optional> const& StandardRewardModel::getOptionalStateRewardVector() const { return this->optionalStateRewardVector; } template ValueType const& StandardRewardModel::getStateReward(uint_fast64_t state) const { assert(this->hasStateRewards()); assert(state < this->optionalStateRewardVector.get().size()); return this->optionalStateRewardVector.get()[state]; } template template void StandardRewardModel::setStateReward(uint_fast64_t state, T const & newReward) { assert(this->hasStateRewards()); assert(state < this->optionalStateRewardVector.get().size()); this->optionalStateRewardVector.get()[state] = newReward; } template bool StandardRewardModel::hasStateActionRewards() const { return static_cast(this->optionalStateActionRewardVector); } template std::vector const& StandardRewardModel::getStateActionRewardVector() const { assert(this->hasStateActionRewards()); return this->optionalStateActionRewardVector.get(); } template std::vector& StandardRewardModel::getStateActionRewardVector() { assert(this->hasStateActionRewards()); return this->optionalStateActionRewardVector.get(); } template ValueType const& StandardRewardModel::getStateActionReward(uint_fast64_t choiceIndex) const { assert(this->hasStateActionRewards()); assert(choiceIndex < this->optionalStateActionRewardVector.get().size()); return this->optionalStateActionRewardVector.get()[choiceIndex]; } template template void StandardRewardModel::setStateActionReward(uint_fast64_t choiceIndex, T const &newValue) { assert(this->hasStateActionRewards()); assert(choiceIndex < this->optionalStateActionRewardVector.get().size()); this->optionalStateActionRewardVector.get()[choiceIndex] = newValue; } template boost::optional> const& StandardRewardModel::getOptionalStateActionRewardVector() const { return this->optionalStateActionRewardVector; } template bool StandardRewardModel::hasTransitionRewards() const { return static_cast(this->optionalTransitionRewardMatrix); } template storm::storage::SparseMatrix const& StandardRewardModel::getTransitionRewardMatrix() const { return this->optionalTransitionRewardMatrix.get(); } template storm::storage::SparseMatrix& StandardRewardModel::getTransitionRewardMatrix() { return this->optionalTransitionRewardMatrix.get(); } template boost::optional> const& StandardRewardModel::getOptionalTransitionRewardMatrix() const { return this->optionalTransitionRewardMatrix; } template StandardRewardModel StandardRewardModel::restrictActions(storm::storage::BitVector const& enabledActions) const { boost::optional> newStateRewardVector(this->getOptionalStateRewardVector()); boost::optional> newStateActionRewardVector; if (this->hasStateActionRewards()) { newStateActionRewardVector = std::vector(enabledActions.getNumberOfSetBits()); storm::utility::vector::selectVectorValues(newStateActionRewardVector.get(), enabledActions, this->getStateActionRewardVector()); } boost::optional> newTransitionRewardMatrix; if (this->hasTransitionRewards()) { newTransitionRewardMatrix = this->getTransitionRewardMatrix().restrictRows(enabledActions); } return StandardRewardModel(std::move(newStateRewardVector), std::move(newStateActionRewardVector), std::move(newTransitionRewardMatrix)); } template template void StandardRewardModel::reduceToStateBasedRewards(storm::storage::SparseMatrix const& transitionMatrix, bool reduceToStateRewards) { if (this->hasTransitionRewards()) { if (this->hasStateActionRewards()) { storm::utility::vector::addVectors(this->getStateActionRewardVector(), transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix()), this->getStateActionRewardVector()); this->optionalTransitionRewardMatrix = boost::none; } else { this->optionalStateActionRewardVector = transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix()); } } if (reduceToStateRewards && this->hasStateActionRewards()) { STORM_LOG_THROW(transitionMatrix.getRowGroupCount() == this->getStateActionRewardVector().size(), storm::exceptions::InvalidOperationException, "The reduction to state rewards is only possible if the size of the action reward vector equals the number of states."); if (this->hasStateRewards()) { storm::utility::vector::addVectors(this->getStateActionRewardVector(), this->getStateRewardVector(), this->getStateRewardVector()); } else { this->optionalStateRewardVector = std::move(this->optionalStateActionRewardVector); } this->optionalStateActionRewardVector = boost::none; } } template template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix) const { std::vector result = this->hasTransitionRewards() ? transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix()) : (this->hasStateActionRewards() ? this->getStateActionRewardVector() : std::vector(transitionMatrix.getRowCount())); if (this->hasStateActionRewards() && this->hasTransitionRewards()) { storm::utility::vector::addVectors(result, this->getStateActionRewardVector(), result); } if (this->hasStateRewards()) { storm::utility::vector::addVectorToGroupedVector(result, this->getStateRewardVector(), transitionMatrix.getRowGroupIndices()); } return result; } template template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix, std::vector const& weights) const { std::vector result = this->hasTransitionRewards() ? transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix()) : (this->hasStateActionRewards() ? this->getStateActionRewardVector() : std::vector(transitionMatrix.getRowCount())); if (!this->hasTransitionRewards() && this->hasStateActionRewards()) { // If we initialized the result with the state-action rewards we can scale the result in place. storm::utility::vector::multiplyVectorsPointwise(result, weights, result); } if (this->hasStateActionRewards() && this->hasTransitionRewards()) { // If we initialized the result with the transition rewards and still have state-action rewards, // we need to add the scaled vector directly. storm::utility::vector::applyPointwise(weights, this->getStateActionRewardVector(), result, [] (MatrixValueType const& weight, ValueType const& rewardElement, ValueType const& resultElement) { return resultElement + weight * rewardElement; } ); } if (this->hasStateRewards()) { storm::utility::vector::addVectorToGroupedVector(result, this->getStateRewardVector(), transitionMatrix.getRowGroupIndices()); } return result; } template template std::vector StandardRewardModel::getTotalRewardVector(uint_fast64_t numberOfRows, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& filter) const { std::vector result(numberOfRows); if (this->hasTransitionRewards()) { std::vector pointwiseProductRowSumVector = transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix()); storm::utility::vector::selectVectorValues(result, filter, transitionMatrix.getRowGroupIndices(), pointwiseProductRowSumVector); } if (this->hasStateActionRewards()) { storm::utility::vector::addFilteredVectorGroupsToGroupedVector(result, this->getStateActionRewardVector(), filter, transitionMatrix.getRowGroupIndices()); } if (this->hasStateRewards()) { storm::utility::vector::addFilteredVectorToGroupedVector(result, this->getStateRewardVector(), filter, transitionMatrix.getRowGroupIndices()); } return result; } template std::vector StandardRewardModel::getTotalStateActionRewardVector(uint_fast64_t numberOfRows, std::vector const& rowGroupIndices) const { std::vector result = this->hasStateActionRewards() ? this->getStateActionRewardVector() : std::vector(numberOfRows); if (this->hasStateRewards()) { storm::utility::vector::addVectorToGroupedVector(result, this->getStateRewardVector(), rowGroupIndices); } return result; } template std::vector StandardRewardModel::getTotalStateActionRewardVector(uint_fast64_t numberOfRows, std::vector const& rowGroupIndices, storm::storage::BitVector const& filter) const { std::vector result(numberOfRows); if (this->hasStateRewards()) { storm::utility::vector::selectVectorValuesRepeatedly(result, filter, rowGroupIndices, this->getStateRewardVector()); } if (this->hasStateActionRewards()) { storm::utility::vector::addFilteredVectorGroupsToGroupedVector(result, this->getStateActionRewardVector(), filter, rowGroupIndices); } return result; } template void StandardRewardModel::setStateActionRewardValue(uint_fast64_t row, ValueType const& value) { this->optionalStateActionRewardVector.get()[row] = value; } template bool StandardRewardModel::empty() const { return !(static_cast(this->optionalStateRewardVector) || static_cast(this->optionalStateActionRewardVector) || static_cast(this->optionalTransitionRewardMatrix)); } template bool StandardRewardModel::isAllZero() const { if(hasStateRewards() && !std::all_of(getStateRewardVector().begin(), getStateRewardVector().end(), storm::utility::isZero)) { return false; } if(hasStateActionRewards() && !std::all_of(getStateActionRewardVector().begin(), getStateActionRewardVector().end(), storm::utility::isZero)) { return false; } if(hasTransitionRewards() && !std::all_of(getTransitionRewardMatrix().begin(), getTransitionRewardMatrix().end(), [](storm::storage::MatrixEntry entry){ return storm::utility::isZero(entry.getValue()); })) { return false; } return true; } template bool StandardRewardModel::isCompatible(uint_fast64_t nrStates, uint_fast64_t nrChoices) const { if(hasStateRewards()) { if(optionalStateRewardVector.get().size() != nrStates) return false; } if(hasStateActionRewards()) { if(optionalStateActionRewardVector.get().size() != nrChoices) return false; } return true; } template std::size_t StandardRewardModel::getSizeInBytes() const { std::size_t result = 0; if (this->hasStateRewards()) { result += this->getStateRewardVector().size() * sizeof(ValueType); } if (this->hasStateActionRewards()) { result += this->getStateActionRewardVector().size() * sizeof(ValueType); } if (this->hasTransitionRewards()) { result += this->getTransitionRewardMatrix().getSizeInBytes(); } return result; } template std::ostream& operator<<(std::ostream& out, StandardRewardModel const& rewardModel) { out << std::boolalpha << "reward model [state reward: " << rewardModel.hasStateRewards() << ", state-action rewards: " << rewardModel.hasStateActionRewards() << ", transition rewards: " << rewardModel.hasTransitionRewards() << "]" << std::noboolalpha; return out; } // Explicitly instantiate the class. template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix) const; template std::vector StandardRewardModel::getTotalRewardVector(uint_fast64_t numberOfRows, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& filter) const; template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix, std::vector const& weights) const; template void StandardRewardModel::reduceToStateBasedRewards(storm::storage::SparseMatrix const& transitionMatrix, bool reduceToStateRewards); template void StandardRewardModel::setStateActionReward(uint_fast64_t choiceIndex, double const & newValue); template void StandardRewardModel::setStateReward(uint_fast64_t state, double const & newValue); template class StandardRewardModel; template std::ostream& operator<<(std::ostream& out, StandardRewardModel const& rewardModel); template std::vector StandardRewardModel::getTotalRewardVector(uint_fast64_t numberOfRows, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& filter) const; template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix) const; template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix, std::vector const& weights) const; template void StandardRewardModel::reduceToStateBasedRewards(storm::storage::SparseMatrix const& transitionMatrix, bool reduceToStateRewards); template void StandardRewardModel::setStateActionReward(uint_fast64_t choiceIndex, float const & newValue); template void StandardRewardModel::setStateReward(uint_fast64_t state, float const & newValue); template class StandardRewardModel; template std::ostream& operator<<(std::ostream& out, StandardRewardModel const& rewardModel); #ifdef STORM_HAVE_CARL template std::vector StandardRewardModel::getTotalRewardVector(uint_fast64_t numberOfRows, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& filter) const; template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix) const; template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix, std::vector const& weights) const; template void StandardRewardModel::reduceToStateBasedRewards(storm::storage::SparseMatrix const& transitionMatrix, bool reduceToStateRewards); template void StandardRewardModel::setStateActionReward(uint_fast64_t choiceIndex, storm::RationalNumber const & newValue); template void StandardRewardModel::setStateReward(uint_fast64_t state, storm::RationalNumber const & newValue); template class StandardRewardModel; template std::ostream& operator<<(std::ostream& out, StandardRewardModel const& rewardModel); template std::vector StandardRewardModel::getTotalRewardVector(uint_fast64_t numberOfRows, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& filter) const; template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix) const; template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix, std::vector const& weights) const; template void StandardRewardModel::reduceToStateBasedRewards(storm::storage::SparseMatrix const& transitionMatrix, bool reduceToStateRewards); template void StandardRewardModel::setStateActionReward(uint_fast64_t choiceIndex, storm::RationalFunction const & newValue); template void StandardRewardModel::setStateReward(uint_fast64_t state, storm::RationalFunction const & newValue); template class StandardRewardModel; template std::ostream& operator<<(std::ostream& out, StandardRewardModel const& rewardModel); template std::vector StandardRewardModel::getTotalRewardVector(uint_fast64_t numberOfRows, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& filter) const; template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix) const; template std::vector StandardRewardModel::getTotalRewardVector(storm::storage::SparseMatrix const& transitionMatrix, std::vector const& weights) const; template void StandardRewardModel::setStateActionReward(uint_fast64_t choiceIndex, double const & newValue); template void StandardRewardModel::setStateActionReward(uint_fast64_t choiceIndex, storm::Interval const & newValue); template void StandardRewardModel::setStateReward(uint_fast64_t state, double const & newValue); template void StandardRewardModel::setStateReward(uint_fast64_t state, storm::Interval const & newValue); template void StandardRewardModel::reduceToStateBasedRewards(storm::storage::SparseMatrix const& transitionMatrix, bool reduceToStateRewards); template class StandardRewardModel; template std::ostream& operator<<(std::ostream& out, StandardRewardModel const& rewardModel); #endif } } }