21template<
typename ValueType>
23 std::vector<ValueType>
const& resultVector,
33 ValueType newEpsilon = epsilon;
35 for (uint64_t state : relevantPositions) {
39 ValueType relativeError = epsilon / resultVector[state];
40 if (relativeError > precision) {
41 newEpsilon = std::min(resultVector[state] * precision, newEpsilon);
45 if (newEpsilon < epsilon) {
46 STORM_LOG_INFO(
"Re-computing transient probabilities with new truncation error " << newEpsilon
47 <<
" to guarantee sound results with relative precision.");
55template<
typename ValueType>
60 std::vector<ValueType>
const& exitRates,
bool qualitative, ValueType lowerBound, std::optional<ValueType>
const& upperBound) {
62 "Exact computations not possible for bounded until probabilities.");
64 uint_fast64_t numberOfStates = rateMatrix.
getRowCount();
68 return computeUntilProbabilities(env, std::move(goal), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative);
75 std::vector<ValueType> result;
89 if (goal.hasRelevantValues()) {
90 relevantValues = std::move(goal.relevantValues());
91 relevantValues &= statesWithProbabilityGreater0;
93 relevantValues = statesWithProbabilityGreater0;
97 if (!statesWithProbabilityGreater0.
empty()) {
109 if (!statesWithProbabilityGreater0NonPsi.
empty()) {
111 ValueType uniformizationRate = 0;
112 for (uint64_t state : statesWithProbabilityGreater0NonPsi) {
113 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
115 uniformizationRate *= 1.02;
116 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException,
"The uniformization rate must be positive.");
124 for (
auto& element : b) {
125 element /= uniformizationRate;
130 std::vector<ValueType> subresult =
134 }
else if (!upperBound) {
140 psiStates, qualitative);
147 ValueType uniformizationRate = 0;
148 for (uint64_t state : relevantStates) {
149 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
151 uniformizationRate *= 1.02;
152 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException,
"The uniformization rate must be positive.");
167 if (lowerBound != *upperBound) {
173 if (!statesWithProbabilityGreater0NonPsi.
empty()) {
176 for (uint64_t state : statesWithProbabilityGreater0NonPsi) {
177 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
179 uniformizationRate *= 1.02;
180 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException,
"The uniformization rate must be positive.");
188 for (
auto& element : b) {
189 element /= uniformizationRate;
195 std::vector<ValueType> subresult =
204 for (uint64_t state : relevantStates) {
205 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
207 uniformizationRate *= 1.02;
208 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException,
"The uniformization rate must be positive.");
223 std::vector<ValueType> newSubresult = std::vector<ValueType>(statesWithProbabilityGreater0.
getNumberOfSetBits());
229 for (uint64_t state : statesWithProbabilityGreater0) {
230 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
232 uniformizationRate *= 1.02;
233 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException,
"The uniformization rate must be positive.");
255template<
typename ValueType>
262 backwardTransitions, phiStates, psiStates, qualitative)
266template<
typename ValueType>
269 std::vector<ValueType>
const& exitRateVector,
274 initialStates, phiStates, psiStates);
277template<
typename ValueType>
279 std::vector<ValueType>
const& exitRateVector,
284template<
typename ValueType,
typename RewardModelType>
288 std::vector<ValueType>
const& exitRateVector, RewardModelType
const& rewardModel,
289 ValueType timeBound) {
291 STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
292 "Computing instantaneous rewards for a reward model that does not define any state-rewards. The result is trivially 0.");
294 uint_fast64_t numberOfStates = rateMatrix.
getRowCount();
297 std::vector<ValueType> result(rewardModel.getStateRewardVector());
310 ValueType uniformizationRate = 0;
311 for (
auto const& rate : exitRateVector) {
312 uniformizationRate = std::max(uniformizationRate, rate);
314 uniformizationRate *= 1.02;
315 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException,
"The uniformization rate must be positive.");
331 if (goal.hasRelevantValues()) {
332 relevantValues = std::move(goal.relevantValues());
345template<
typename ValueType,
typename RewardModelType>
349 std::vector<ValueType>
const& exitRateVector, RewardModelType
const& rewardModel,
350 ValueType timeBound) {
352 "Exact computations not possible for cumulative expected rewards.");
355 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException,
"Missing reward model for formula. Skipping formula.");
357 uint_fast64_t numberOfStates = rateMatrix.
getRowCount();
360 if (timeBound == 0) {
367 ValueType uniformizationRate = 0;
368 for (
auto const& rate : exitRateVector) {
369 uniformizationRate = std::max(uniformizationRate, rate);
371 uniformizationRate *= 1.02;
372 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException,
"The uniformization rate must be positive.");
378 std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(rateMatrix, exitRateVector);
397 if (goal.hasRelevantValues()) {
398 relevantValues = std::move(goal.relevantValues());
404 std::vector<ValueType> result;
412template<
typename ValueType>
421 std::vector<ValueType> totalRewardVector;
422 for (
size_t i = 0; i < exitRateVector.size(); ++i) {
433 env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative)
437template<
typename ValueType,
typename RewardModelType>
442 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException,
"Missing reward model for formula. Skipping formula.");
446 std::vector<ValueType> totalRewardVector;
447 if (rewardModel.hasStateRewards()) {
448 totalRewardVector = rewardModel.getStateRewardVector();
449 typename std::vector<ValueType>::const_iterator it2 = exitRateVector.begin();
450 for (
typename std::vector<ValueType>::iterator it1 = totalRewardVector.begin(), ite1 = totalRewardVector.end(); it1 != ite1; ++it1, ++it2) {
453 if (rewardModel.hasStateActionRewards()) {
456 if (rewardModel.hasTransitionRewards()) {
460 }
else if (rewardModel.hasTransitionRewards()) {
462 if (rewardModel.hasStateActionRewards()) {
466 totalRewardVector = rewardModel.getStateActionRewardVector();
472 env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative)
476template<
typename ValueType,
typename RewardModelType>
481 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException,
"Missing reward model for formula. Skipping formula.");
485 std::vector<ValueType> totalRewardVector;
486 if (rewardModel.hasStateRewards()) {
487 totalRewardVector = rewardModel.getStateRewardVector();
488 typename std::vector<ValueType>::const_iterator it2 = exitRateVector.begin();
489 for (
typename std::vector<ValueType>::iterator it1 = totalRewardVector.begin(), ite1 = totalRewardVector.end(); it1 != ite1; ++it1, ++it2) {
492 if (rewardModel.hasStateActionRewards()) {
495 if (rewardModel.hasTransitionRewards()) {
499 }
else if (rewardModel.hasTransitionRewards()) {
501 if (rewardModel.hasStateActionRewards()) {
505 totalRewardVector = rewardModel.getStateActionRewardVector();
508 RewardModelType dtmcRewardModel(std::move(totalRewardVector));
510 dtmcRewardModel, qualitative)
514template<
typename ValueType>
520 std::vector<ValueType>
const& exitRates, ValueType timeBound) {
523 uint_fast64_t numberOfStates = rateMatrix.
getRowCount();
530 std::vector<ValueType> newRates = exitRates;
531 for (uint64_t state : psiStates) {
543 if (!relevantStates.
empty()) {
545 ValueType uniformizationRate = 0;
546 for (uint64_t state : relevantStates) {
547 uniformizationRate = std::max(uniformizationRate, newRates[state]);
549 uniformizationRate *= 1.02;
550 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException,
"The uniformization rate must be positive.");
552 transposedMatrix = transposedMatrix.
transpose();
566 "Computation of transient probabilities with relative precision not supported. Using absolute precision instead.");
571 for (uint64_t state : relevantStates) {
572 if (initialStates.
get(state)) {
573 values[i] = initDist;
578 std::vector<ValueType> subresult =
587template<
typename ValueType>
591 ValueType uniformizationRate, std::vector<ValueType>
const& exitRates) {
592 STORM_LOG_DEBUG(
"Computing uniformized matrix using uniformization rate " << uniformizationRate <<
".");
602 uint_fast64_t currentRow = 0;
603 for (uint64_t state : maybeStates) {
604 for (
auto& element : uniformizedMatrix.
getRow(currentRow)) {
605 if (element.getColumn() == currentRow) {
608 element.setValue(element.getValue() / uniformizationRate);
614 return uniformizedMatrix;
617template<
typename ValueType,
bool useMixedPoissonProbabilities>
621 std::vector<ValueType>
const* addVector, ValueType timeBound,
622 ValueType uniformizationRate, std::vector<ValueType> values, ValueType epsilon) {
624 "Very low truncation error " << epsilon <<
" requested. Numerical inaccuracies are possible.");
625 ValueType lambda = timeBound * uniformizationRate;
638 if (useMixedPoissonProbabilities) {
644 uint64_t l{0ull}, r{foxGlynnResult.
weights.size() - 1};
648 sumLeft += foxGlynnResult.
weights[l];
649 foxGlynnResult.
weights[l] = (foxGlynnResult.
totalWeight - sumLeft) / uniformizationRate;
652 auto const tmp = foxGlynnResult.
weights[r];
653 foxGlynnResult.
weights[r] = sumRight / uniformizationRate;
664 "Numerical instability when adjusting the FoxGlynn weights. Relative Difference: " << relDiff <<
".");
670 std::vector<ValueType> result;
671 uint_fast64_t startingIteration = foxGlynnResult.
left;
672 if (startingIteration == 0) {
677 if (useMixedPoissonProbabilities) {
678 result = std::vector<ValueType>(values.size());
679 std::function<ValueType(ValueType
const&)> scaleWithUniformizationRate = [&uniformizationRate](ValueType
const& a) -> ValueType {
680 return a / uniformizationRate;
684 result = std::vector<ValueType>(values.size());
689 if (!useMixedPoissonProbabilities && foxGlynnResult.
left > 1) {
691 multiplier->repeatedMultiply(env, values, addVector, foxGlynnResult.
left - 1);
692 }
else if (useMixedPoissonProbabilities) {
693 std::function<ValueType(ValueType
const&, ValueType
const&)> addAndScale = [&uniformizationRate](ValueType
const& a, ValueType
const& b) {
694 return a + b / uniformizationRate;
698 for (uint_fast64_t index = 1; index < startingIteration; ++index) {
699 multiplier->multiply(env, values,
nullptr, values);
705 if (foxGlynnResult.
left > 0) {
712 ValueType weight = 0;
713 std::function<ValueType(ValueType
const&, ValueType
const&)> addAndScale = [&weight](ValueType
const& a, ValueType
const& b) {
return a + weight * b; };
714 for (uint_fast64_t index = startingIteration; index <= foxGlynnResult.
right; ++index) {
715 multiplier->multiply(env, values, addVector, values);
717 weight = foxGlynnResult.
weights[index - foxGlynnResult.
left];
726template<
typename ValueType>
728 std::vector<ValueType>
const& exitRates) {
731 for (uint_fast64_t row = 0; row < result.
getRowCount(); ++row) {
732 for (
auto& entry : result.
getRow(row)) {
733 entry.setValue(entry.getValue() / exitRates[row]);
739template<
typename ValueType>
741 std::vector<ValueType>
const& exitRates) {
745 for (uint_fast64_t row = 0; row < generatorMatrix.
getRowCount(); ++row) {
746 for (
auto& entry : generatorMatrix.
getRow(row)) {
747 if (entry.getColumn() == row) {
748 entry.setValue(-exitRates[row] + entry.getValue());
753 return generatorMatrix;
759 std::vector<double>
const& exitRates,
bool qualitative,
double lowerBound, std::optional<double>
const& upperBound);
764 std::vector<double>
const& exitRateVector,
770 std::vector<double>
const& exitRateVector,
776 std::vector<double>
const& exitRateVector,
781 std::vector<double>
const& exitRateVector,
802 std::vector<double>
const& exitRateVector,
812 double uniformizationRate, std::vector<double>
const& exitRates);
816 std::vector<double>
const* addVector,
double timeBound,
817 double uniformizationRate, std::vector<double> values,
double epsilon);
839 std::vector<storm::RationalNumber>
const& exitRateVector,
873 std::vector<double>
const& exitRates);
SolverEnvironment & solver()
bool isForceExact() const
TimeBoundedSolverEnvironment & timeBounded()
bool isForceSoundness() const
bool const & getRelativeTerminationCriterion() const
storm::RationalNumber const & getPrecision() const
static std::vector< ValueType > computeUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &rateMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &exitRateVector, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool qualitative)
static storm::storage::SparseMatrix< ValueType > computeGeneratorMatrix(storm::storage::SparseMatrix< ValueType > const &rateMatrix, std::vector< ValueType > const &exitRates)
Converts the given rate-matrix into the generator matrix.
static std::vector< ValueType > computeCumulativeRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &rateMatrix, std::vector< ValueType > const &exitRateVector, RewardModelType const &rewardModel, ValueType timeBound)
static storm::storage::SparseMatrix< ValueType > computeProbabilityMatrix(storm::storage::SparseMatrix< ValueType > const &rateMatrix, std::vector< ValueType > const &exitRates)
Converts the given rate-matrix into a time-abstract probability matrix.
static std::vector< storm::utility::ExtendedValueType< ValueType > > computeReachabilityTimes(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &rateMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &exitRateVector, storm::storage::BitVector const &targetStates, bool qualitative)
static std::vector< ValueType > computeAllUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &rateMatrix, std::vector< ValueType > const &exitRateVector, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
static storm::storage::SparseMatrix< ValueType > computeUniformizedMatrix(storm::storage::SparseMatrix< ValueType > const &rateMatrix, storm::storage::BitVector const &maybeStates, ValueType uniformizationRate, std::vector< ValueType > const &exitRates)
Computes the matrix representing the transitions of the uniformized CTMC.
static std::vector< ValueType > computeTransientProbabilities(Environment const &env, storm::storage::SparseMatrix< ValueType > const &uniformizedMatrix, std::vector< ValueType > const *addVector, ValueType timeBound, ValueType uniformizationRate, std::vector< ValueType > values, ValueType epsilon)
Computes the transient probabilities for lambda time steps.
static std::vector< ValueType > computeAllTransientProbabilities(Environment const &env, storm::storage::SparseMatrix< ValueType > const &rateMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, std::vector< ValueType > const &exitRates, ValueType timeBound)
static std::vector< storm::utility::ExtendedValueType< ValueType > > computeReachabilityRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &rateMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &exitRateVector, RewardModelType const &rewardModel, storm::storage::BitVector const &targetStates, bool qualitative)
static std::vector< ValueType > computeBoundedUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &rateMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, std::vector< ValueType > const &exitRates, bool qualitative, ValueType lowerBound, std::optional< ValueType > const &upperBound)
static bool checkAndUpdateTransientProbabilityEpsilon(storm::Environment const &env, ValueType &epsilon, std::vector< ValueType > const &resultVector, storm::storage::BitVector const &relevantPositions)
Checks whether the given result vector is sufficiently precise, according to the provided epsilon and...
static std::vector< storm::utility::ExtendedValueType< ValueType > > computeTotalRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &rateMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &exitRateVector, RewardModelType const &rewardModel, bool qualitative)
static std::vector< ValueType > computeNextProbabilities(Environment const &env, storm::storage::SparseMatrix< ValueType > const &rateMatrix, std::vector< ValueType > const &exitRateVector, storm::storage::BitVector const &nextStates)
static std::vector< ValueType > computeInstantaneousRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &rateMatrix, std::vector< ValueType > const &exitRateVector, RewardModelType const &rewardModel, ValueType timeBound)
static DTMCSparseModelCheckingHelperReturnType< ExtendedSolutionType > computeTotalRewards(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static std::vector< SolutionType > computeAllUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
static std::vector< SolutionType > computeNextProbabilities(Environment const &env, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &nextStates)
static DTMCSparseModelCheckingHelperReturnType< ExtendedSolutionType > computeReachabilityRewards(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, storm::storage::BitVector const &targetStates, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static DTMCSparseModelCheckingHelperReturnType< SolutionType > computeUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
std::unique_ptr< Multiplier< ValueType, SolutionType > > create(Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix)
A bit vector that is internally represented as a vector of 64-bit values.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
A class that holds a possibly non-square matrix in the compressed row storage format.
const_rows getRow(index_type row) const
Returns an object representing the given row.
void makeRowsAbsorbing(storm::storage::BitVector const &rows, bool dropZeroEntries=false)
This function makes the given rows absorbing.
SparseMatrix getSubmatrix(bool useGroups, storm::storage::BitVector const &rowConstraint, storm::storage::BitVector const &columnConstraint, bool insertDiagonalEntries=false, storm::storage::BitVector const &makeZeroColumns=storm::storage::BitVector()) const
Creates a submatrix of the current matrix by dropping all rows and columns whose bits are not set to ...
std::vector< value_type > getConstrainedRowSumVector(storm::storage::BitVector const &rowConstraint, storm::storage::BitVector const &columnConstraint) const
Computes a vector whose i-th entry is the sum of the entries in the i-th selected row where only thos...
index_type getColumnCount() const
Returns the number of columns of the matrix.
std::vector< ResultValueType > getPointwiseProductRowSumVector(storm::storage::SparseMatrix< OtherValueType > const &otherMatrix) const
Performs a pointwise matrix multiplication of the matrix with the given matrix and returns a vector c...
storm::storage::SparseMatrix< value_type > transpose(bool joinGroups=false, bool keepZeros=false) const
Transposes the matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
#define STORM_LOG_INFO(message)
#define STORM_LOG_DEBUG(message)
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
storm::storage::BitVector performProbGreater0(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps)
Performs a backward depth-first search trough the underlying graph structure of the given model to de...
FoxGlynnResult< ValueType > foxGlynn(ValueType lambda, ValueType epsilon)
void addVectors(std::vector< InValueType1 > const &firstOperand, std::vector< InValueType2 > const &secondOperand, std::vector< OutValueType > &target)
Adds the two given vectors and writes the result to the target vector.
void setVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< S > const &values)
Sets the provided values at the provided positions in the given vector.
void selectVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< T > const &values)
Selects the elements from a vector at the specified positions and writes them consecutively into anot...
T maximumElementAbs(std::vector< T > const &vector)
void applyPointwise(std::vector< InValueType1 > const &firstOperand, std::vector< InValueType2 > const &secondOperand, std::vector< OutValueType > &target, Operation f=Operation())
Applies the given operation pointwise on the two given vectors and writes the result to the third vec...
void scaleVectorInPlace(std::vector< ValueType1 > &target, ValueType2 const &factor)
Multiplies each element of the given vector with the given factor and writes the result into the vect...
bool isZero(ValueType const &a)
ValueType abs(ValueType const &number)
TargetType convertNumber(SourceType const &number)
static const bool SupportsExponential
std::vector< ValueType > weights