#include "storm/storage/Distribution.h" #include #include #include "storm/utility/macros.h" #include "storm/utility/constants.h" #include "storm/utility/ConstantsComparator.h" #include "storm/settings/SettingsManager.h" #include "storm/adapters/CarlAdapter.h" namespace storm { namespace storage { template Distribution::Distribution() { // Intentionally left empty. } template void Distribution::add(Distribution const& other) { container_type newDistribution; std::set_union(this->distribution.begin(), this->distribution.end(), other.distribution.begin(), other.distribution.end(), std::inserter(newDistribution, newDistribution.begin())); this->distribution = std::move(newDistribution); } template bool Distribution::equals(Distribution const& other, storm::utility::ConstantsComparator const& comparator) const { // We need to check equality by ourselves, because we need to account for epsilon differences. if (this->distribution.size() != other.distribution.size()) { return false; } auto first1 = this->distribution.begin(); auto last1 = this->distribution.end(); auto first2 = other.distribution.begin(); for (; first1 != last1; ++first1, ++first2) { if (first1->first != first2->first) { return false; } if (!comparator.isEqual(first1->second, first2->second)) { return false; } } return true; } template void Distribution::addProbability(StateType const& state, ValueType const& probability) { auto it = this->distribution.find(state); if (it == this->distribution.end()) { this->distribution.emplace_hint(it, state, probability); } else { it->second += probability; } } template void Distribution::removeProbability(StateType const& state, ValueType const& probability, storm::utility::ConstantsComparator const& comparator) { auto it = this->distribution.find(state); STORM_LOG_ASSERT(it != this->distribution.end(), "Cannot remove probability, because the state is not in the support of the distribution."); it->second -= probability; if (comparator.isZero(it->second)) { this->distribution.erase(it); } } template void Distribution::shiftProbability(StateType const& fromState, StateType const& toState, ValueType const& probability, storm::utility::ConstantsComparator const& comparator) { removeProbability(fromState, probability, comparator); addProbability(toState, probability); } template typename Distribution::iterator Distribution::begin() { return this->distribution.begin(); } template typename Distribution::const_iterator Distribution::begin() const { return this->distribution.begin(); } template typename Distribution::const_iterator Distribution::cbegin() const { return this->begin(); } template typename Distribution::iterator Distribution::end() { return this->distribution.end(); } template typename Distribution::const_iterator Distribution::end() const { return this->distribution.end(); } template typename Distribution::const_iterator Distribution::cend() const { return this->end(); } template void Distribution::scale(StateType const& state) { auto probabilityIterator = this->distribution.find(state); if (probabilityIterator != this->distribution.end()) { ValueType scaleValue = storm::utility::one() / probabilityIterator->second; this->distribution.erase(probabilityIterator); for (auto& entry : this->distribution) { entry.second *= scaleValue; } } } template std::size_t Distribution::size() const { return this->distribution.size(); } template std::ostream& operator<<(std::ostream& out, Distribution const& distribution) { out << "{"; for (auto const& entry : distribution) { out << "[" << entry.second << ": " << entry.first << "], "; } out << "}"; return out; } template bool Distribution::less(Distribution const& other, storm::utility::ConstantsComparator const& comparator) const { if (this->size() != other.size()) { return this->size() < other.size(); } auto firstIt = this->begin(); auto firstIte = this->end(); auto secondIt = other.begin(); for (; firstIt != firstIte; ++firstIt, ++secondIt) { // If the two blocks already differ, we can decide which distribution is smaller. if (firstIt->first != secondIt->first) { return firstIt->first < secondIt->first; } // If the blocks are the same, but the probability differs, we can also decide which distribution is smaller. if (!comparator.isEqual(firstIt->second, secondIt->second)) { return comparator.isLess(firstIt->second, secondIt->second); } } return false; } template class Distribution; template std::ostream& operator<<(std::ostream& out, Distribution const& distribution); #ifdef STORM_HAVE_CARL template class Distribution; template std::ostream& operator<<(std::ostream& out, Distribution const& distribution); template class Distribution; template std::ostream& operator<<(std::ostream& out, Distribution const& distribution); #endif } }