Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseCtmcCslHelper.cpp
Go to the documentation of this file.
2
5
7
10
12
17
19#include "storm/utility/graph.h"
23
30
31namespace storm {
32namespace modelchecker {
33namespace helper {
34
35template<typename ValueType>
37 std::vector<ValueType> const& resultVector,
38 storm::storage::BitVector const& relevantPositions) {
39 // Check if the check is necessary for the provided environment
41 // No need to update epsilon
42 return false;
43 }
44
45 ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision());
46 // If we need to compute values with relative precision, it might be necessary to increase the precision requirements (epsilon)
47 ValueType newEpsilon = epsilon;
48 // Only consider positions that are relevant for the solve goal (e.g. initial states of the model) and are supposed to have a non-zero value
49 for (auto state : relevantPositions) {
50 if (storm::utility::isZero(resultVector[state])) {
51 newEpsilon = std::min(epsilon * storm::utility::convertNumber<ValueType>(0.1), newEpsilon);
52 } else {
53 ValueType relativeError = epsilon / resultVector[state]; // epsilon is an upper bound for the absolute error we made
54 if (relativeError > precision) {
55 newEpsilon = std::min(resultVector[state] * precision, newEpsilon);
56 }
57 }
58 }
59 if (newEpsilon < epsilon) {
60 STORM_LOG_INFO("Re-computing transient probabilities with new truncation error " << newEpsilon
61 << " to guarantee sound results with relative precision.");
62 epsilon = newEpsilon;
63 return true;
64 } else {
65 return false;
66 }
67}
68
69template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type>
72 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
73 std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound) {
74 STORM_LOG_THROW(!env.solver().isForceExact(), storm::exceptions::InvalidOperationException,
75 "Exact computations not possible for bounded until probabilities.");
76
77 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
78
79 // If the time bounds are [0, inf], we rather call untimed reachability.
80 if (storm::utility::isZero(lowerBound) && upperBound == storm::utility::infinity<ValueType>()) {
81 return computeUntilProbabilities(env, std::move(goal), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative);
82 }
83
84 // From this point on, we know that we have to solve a more complicated problem [t, t'] with either t != 0
85 // or t' != inf.
86
87 // Create the result vector.
88 std::vector<ValueType> result;
89
90 // Set the possible (absolute) error allowed for truncation (epsilon for fox-glynn)
91 ValueType epsilon = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision()) / 8.0;
92
93 // If we identify the states that have probability 0 of reaching the target states, we can exclude them from the
94 // further computations.
95 storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(backwardTransitions, phiStates, psiStates);
96 STORM_LOG_INFO("Found " << statesWithProbabilityGreater0.getNumberOfSetBits() << " states with probability greater 0.");
97 storm::storage::BitVector statesWithProbabilityGreater0NonPsi = statesWithProbabilityGreater0 & ~psiStates;
98 STORM_LOG_INFO("Found " << statesWithProbabilityGreater0NonPsi.getNumberOfSetBits() << " 'maybe' states.");
99
100 // the positions within the result for which the precision needs to be checked
101 storm::storage::BitVector relevantValues;
102 if (goal.hasRelevantValues()) {
103 relevantValues = std::move(goal.relevantValues());
104 relevantValues &= statesWithProbabilityGreater0;
105 } else {
106 relevantValues = statesWithProbabilityGreater0;
107 }
108
109 do { // Iterate until the desired precision is reached (only relevant for relative precision criterion)
110 if (!statesWithProbabilityGreater0.empty()) {
111 if (storm::utility::isZero(upperBound)) {
112 // In this case, the interval is of the form [0, 0].
113 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
114 storm::utility::vector::setVectorValues<ValueType>(result, psiStates, storm::utility::one<ValueType>());
115 } else {
116 if (storm::utility::isZero(lowerBound)) {
117 // In this case, the interval is of the form [0, t].
118 // Note that this excludes [0, inf] since this is untimed reachability and we considered this case earlier.
119
120 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
121 storm::utility::vector::setVectorValues<ValueType>(result, psiStates, storm::utility::one<ValueType>());
122 if (!statesWithProbabilityGreater0NonPsi.empty()) {
123 // Find the maximal rate of all 'maybe' states to take it as the uniformization rate.
124 ValueType uniformizationRate = 0;
125 for (auto state : statesWithProbabilityGreater0NonPsi) {
126 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
127 }
128 uniformizationRate *= 1.02;
129 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
130
131 // Compute the uniformized matrix.
133 computeUniformizedMatrix(rateMatrix, statesWithProbabilityGreater0NonPsi, uniformizationRate, exitRates);
134
135 // Compute the vector that is to be added as a compensation for removing the absorbing states.
136 std::vector<ValueType> b = rateMatrix.getConstrainedRowSumVector(statesWithProbabilityGreater0NonPsi, psiStates);
137 for (auto& element : b) {
138 element /= uniformizationRate;
139 }
140
141 // Finally compute the transient probabilities.
142 std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNumberOfSetBits(), storm::utility::zero<ValueType>());
143 std::vector<ValueType> subresult =
144 computeTransientProbabilities(env, uniformizedMatrix, &b, upperBound, uniformizationRate, values, epsilon);
145 storm::utility::vector::setVectorValues(result, statesWithProbabilityGreater0NonPsi, subresult);
146 }
147 } else if (upperBound == storm::utility::infinity<ValueType>()) {
148 // In this case, the interval is of the form [t, inf] with t != 0.
149
150 // Start by computing the (unbounded) reachability probabilities of reaching psi states while
151 // staying in phi states.
152 result = computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), rateMatrix, backwardTransitions, exitRates, phiStates,
153 psiStates, qualitative);
154
155 // Determine the set of states that must be considered further.
156 storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & phiStates;
157 std::vector<ValueType> subResult(relevantStates.getNumberOfSetBits());
158 storm::utility::vector::selectVectorValues(subResult, relevantStates, result);
159
160 ValueType uniformizationRate = 0;
161 for (auto state : relevantStates) {
162 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
163 }
164 uniformizationRate *= 1.02;
165 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
166
167 // Compute the uniformized matrix.
169 computeUniformizedMatrix(rateMatrix, relevantStates, uniformizationRate, exitRates);
170
171 // Compute the transient probabilities.
172 subResult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, subResult, epsilon);
173
174 // Fill in the correct values.
175 storm::utility::vector::setVectorValues(result, ~relevantStates, storm::utility::zero<ValueType>());
176 storm::utility::vector::setVectorValues(result, relevantStates, subResult);
177 } else {
178 // In this case, the interval is of the form [t, t'] with t != 0 and t' != inf.
179
180 if (lowerBound != upperBound) {
181 // In this case, the interval is of the form [t, t'] with t != 0, t' != inf and t != t'.
182
183 storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & phiStates;
184 std::vector<ValueType> newSubresult(relevantStates.getNumberOfSetBits(), storm::utility::zero<ValueType>());
185 storm::utility::vector::setVectorValues(newSubresult, psiStates % relevantStates, storm::utility::one<ValueType>());
186 if (!statesWithProbabilityGreater0NonPsi.empty()) {
187 // Find the maximal rate of all 'maybe' states to take it as the uniformization rate.
188 ValueType uniformizationRate = storm::utility::zero<ValueType>();
189 for (auto state : statesWithProbabilityGreater0NonPsi) {
190 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
191 }
192 uniformizationRate *= 1.02;
193 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
194
195 // Compute the (first) uniformized matrix.
197 computeUniformizedMatrix(rateMatrix, statesWithProbabilityGreater0NonPsi, uniformizationRate, exitRates);
198
199 // Compute the vector that is to be added as a compensation for removing the absorbing states.
200 std::vector<ValueType> b = rateMatrix.getConstrainedRowSumVector(statesWithProbabilityGreater0NonPsi, psiStates);
201 for (auto& element : b) {
202 element /= uniformizationRate;
203 }
204
205 // Start by computing the transient probabilities of reaching a psi state in time t' - t.
206 std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNumberOfSetBits(), storm::utility::zero<ValueType>());
207 // divide the possible error by two since we will make this error two times.
208 std::vector<ValueType> subresult =
209 computeTransientProbabilities(env, uniformizedMatrix, &b, upperBound - lowerBound, uniformizationRate, values,
210 epsilon / storm::utility::convertNumber<ValueType>(2.0));
211 storm::utility::vector::setVectorValues(newSubresult, statesWithProbabilityGreater0NonPsi % relevantStates, subresult);
212 }
213
214 // Then compute the transient probabilities of being in such a state after t time units. For this,
215 // we must re-uniformize the CTMC, so we need to compute the second uniformized matrix.
216 ValueType uniformizationRate = storm::utility::zero<ValueType>();
217 for (auto state : relevantStates) {
218 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
219 }
220 uniformizationRate *= 1.02;
221 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
222
223 // Finally, we compute the second set of transient probabilities.
225 computeUniformizedMatrix(rateMatrix, relevantStates, uniformizationRate, exitRates);
226 newSubresult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult,
227 epsilon / storm::utility::convertNumber<ValueType>(2.0));
228
229 // Fill in the correct values.
230 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
231 storm::utility::vector::setVectorValues(result, ~relevantStates, storm::utility::zero<ValueType>());
232 storm::utility::vector::setVectorValues(result, relevantStates, newSubresult);
233 } else {
234 // In this case, the interval is of the form [t, t] with t != 0, t != inf.
235
236 std::vector<ValueType> newSubresult = std::vector<ValueType>(statesWithProbabilityGreater0.getNumberOfSetBits());
237 storm::utility::vector::setVectorValues(newSubresult, psiStates % statesWithProbabilityGreater0, storm::utility::one<ValueType>());
238
239 // Then compute the transient probabilities of being in such a state after t time units. For this,
240 // we must re-uniformize the CTMC, so we need to compute the second uniformized matrix.
241 ValueType uniformizationRate = storm::utility::zero<ValueType>();
242 for (auto state : statesWithProbabilityGreater0) {
243 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
244 }
245 uniformizationRate *= 1.02;
246 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
247
248 // Finally, we compute the second set of transient probabilities.
250 computeUniformizedMatrix(rateMatrix, statesWithProbabilityGreater0, uniformizationRate, exitRates);
251 newSubresult =
252 computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult, epsilon);
253
254 // Fill in the correct values.
255 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
256 storm::utility::vector::setVectorValues(result, ~statesWithProbabilityGreater0, storm::utility::zero<ValueType>());
257 storm::utility::vector::setVectorValues(result, statesWithProbabilityGreater0, newSubresult);
258 }
259 }
260 }
261 } else {
262 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
263 }
264 } while (checkAndUpdateTransientProbabilityEpsilon(env, epsilon, result, relevantValues));
265 return result;
266}
267
268template<typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type>
272 storm::storage::BitVector const&, std::vector<ValueType> const&, bool, double,
273 double) {
274 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded until probabilities is unsupported for this value type.");
275}
276
277template<typename ValueType>
280 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
281 std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates,
282 storm::storage::BitVector const& psiStates, bool qualitative) {
283 return SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(env, std::move(goal), computeProbabilityMatrix(rateMatrix, exitRateVector),
284 backwardTransitions, phiStates, psiStates, qualitative);
285}
286
287template<typename ValueType>
290 std::vector<ValueType> const& exitRateVector,
291 storm::storage::BitVector const& initialStates,
292 storm::storage::BitVector const& phiStates,
293 storm::storage::BitVector const& psiStates) {
294 return SparseDtmcPrctlHelper<ValueType>::computeAllUntilProbabilities(env, std::move(goal), computeProbabilityMatrix(rateMatrix, exitRateVector),
295 initialStates, phiStates, psiStates);
296}
297
298template<typename ValueType>
300 std::vector<ValueType> const& exitRateVector,
301 storm::storage::BitVector const& nextStates) {
302 return SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, computeProbabilityMatrix(rateMatrix, exitRateVector), nextStates);
303}
304
305template<typename ValueType, typename RewardModelType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type>
308 std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
309 double timeBound) {
310 // Only compute the result if the model has a state-based reward model.
311 STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
312 "Computing instantaneous rewards for a reward model that does not define any state-rewards. The result is trivially 0.");
313
314 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
315
316 // Initialize result to state rewards of the this->getModel().
317 std::vector<ValueType> result(rewardModel.getStateRewardVector());
318
319 // If the time-bound is zero, just return the current reward vector
320 if (storm::utility::isZero(timeBound)) {
321 return result;
322 }
323 ValueType maxValue = storm::utility::vector::maximumElementAbs(result);
324
325 // If all entries are zero, we return the zero-vector
326 if (storm::utility::isZero(maxValue)) {
327 return result;
328 }
329
330 ValueType uniformizationRate = 0;
331 for (auto const& rate : exitRateVector) {
332 uniformizationRate = std::max(uniformizationRate, rate);
333 }
334 uniformizationRate *= 1.02;
335 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
336
338 computeUniformizedMatrix(rateMatrix, storm::storage::BitVector(numberOfStates, true), uniformizationRate, exitRateVector);
339
340 // Set the possible error allowed for truncation (epsilon for fox-glynn)
341 ValueType epsilon = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision());
343 // Be more precise, if the maximum value is very small (precision can/has to be refined later)
344 epsilon *= std::min(storm::utility::one<ValueType>(), maxValue);
345 } else {
346 // Be more precise, if the maximal possible value is very large
347 epsilon /= std::max(storm::utility::one<ValueType>(), maxValue);
348 }
349
350 storm::storage::BitVector relevantValues;
351 if (goal.hasRelevantValues()) {
352 relevantValues = std::move(goal.relevantValues());
353 } else {
354 relevantValues = storm::storage::BitVector(result.size(), true);
355 }
356
357 // Loop until the desired precision is reached.
358 do {
359 result = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, result, epsilon);
360 } while (checkAndUpdateTransientProbabilityEpsilon(env, epsilon, result, relevantValues));
361
362 return result;
363}
364
365template<typename ValueType, typename RewardModelType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type>
367 storm::storage::SparseMatrix<ValueType> const&, std::vector<ValueType> const&,
368 RewardModelType const&, double) {
369 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing instantaneous rewards is unsupported for this value type.");
370}
371
372template<typename ValueType, typename RewardModelType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type>
375 std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
376 double timeBound) {
377 STORM_LOG_THROW(!env.solver().isForceExact(), storm::exceptions::InvalidOperationException,
378 "Exact computations not possible for cumulative expected rewards.");
379
380 // Only compute the result if the model has a state-based reward model.
381 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
382
383 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
384
385 // If the time bound is zero, the result is the constant zero vector.
386 if (timeBound == 0) {
387 return std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
388 }
389
390 // Otherwise, we need to perform some computations.
391
392 // Start with the uniformization.
393 ValueType uniformizationRate = 0;
394 for (auto const& rate : exitRateVector) {
395 uniformizationRate = std::max(uniformizationRate, rate);
396 }
397 uniformizationRate *= 1.02;
398 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
399
401 computeUniformizedMatrix(rateMatrix, storm::storage::BitVector(numberOfStates, true), uniformizationRate, exitRateVector);
402
403 // Compute the total state reward vector.
404 std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(rateMatrix, exitRateVector);
405 ValueType maxReward = storm::utility::vector::maximumElementAbs(totalRewardVector);
406
407 // If all rewards are zero, the result is the constant zero vector.
408 if (storm::utility::isZero(maxReward)) {
409 return std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
410 }
411
412 // Set the possible (absolute) error allowed for truncation (epsilon for fox-glynn)
413 ValueType epsilon = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision());
415 // Be more precise, if the value is very small (precision can/has to be refined later)
416 epsilon *= std::min(storm::utility::one<ValueType>(), maxReward);
417 } else {
418 // Be more precise, if the maximal possible value is very large
419 epsilon /= std::max(storm::utility::one<ValueType>(), maxReward * timeBound);
420 }
421
422 storm::storage::BitVector relevantValues;
423 if (goal.hasRelevantValues()) {
424 relevantValues = std::move(goal.relevantValues());
425 } else {
426 relevantValues = storm::storage::BitVector(totalRewardVector.size(), true);
427 }
428
429 // Loop until the desired precision is reached.
430 std::vector<ValueType> result;
431 do {
432 result = computeTransientProbabilities<ValueType, true>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, totalRewardVector, epsilon);
433 } while (checkAndUpdateTransientProbabilityEpsilon(env, epsilon, result, relevantValues));
434
435 return result;
436}
437
438template<typename ValueType, typename RewardModelType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type>
440 storm::storage::SparseMatrix<ValueType> const&, std::vector<ValueType> const&,
441 RewardModelType const&, double) {
442 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing cumulative rewards is unsupported for this value type.");
443}
444
445template<typename ValueType>
448 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
449 std::vector<ValueType> const& exitRateVector,
450 storm::storage::BitVector const& targetStates, bool qualitative) {
451 // Compute expected time on CTMC by reduction to DTMC with rewards.
452 storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector);
453
454 // Initialize rewards.
455 std::vector<ValueType> totalRewardVector;
456 for (size_t i = 0; i < exitRateVector.size(); ++i) {
457 if (targetStates[i] || storm::utility::isZero(exitRateVector[i])) {
458 // Set reward for target states or states without outgoing transitions to 0.
459 totalRewardVector.push_back(storm::utility::zero<ValueType>());
460 } else {
461 // Reward is (1 / exitRate).
462 totalRewardVector.push_back(storm::utility::one<ValueType>() / exitRateVector[i]);
463 }
464 }
465
467 env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative);
468}
469
470template<typename ValueType, typename RewardModelType>
473 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
474 std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
475 storm::storage::BitVector const& targetStates, bool qualitative) {
476 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
477
478 storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector);
479
480 std::vector<ValueType> totalRewardVector;
481 if (rewardModel.hasStateRewards()) {
482 totalRewardVector = rewardModel.getStateRewardVector();
483 typename std::vector<ValueType>::const_iterator it2 = exitRateVector.begin();
484 for (typename std::vector<ValueType>::iterator it1 = totalRewardVector.begin(), ite1 = totalRewardVector.end(); it1 != ite1; ++it1, ++it2) {
485 *it1 /= *it2;
486 }
487 if (rewardModel.hasStateActionRewards()) {
488 storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
489 }
490 if (rewardModel.hasTransitionRewards()) {
491 storm::utility::vector::addVectors(totalRewardVector, probabilityMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix()),
492 totalRewardVector);
493 }
494 } else if (rewardModel.hasTransitionRewards()) {
495 totalRewardVector = probabilityMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix());
496 if (rewardModel.hasStateActionRewards()) {
497 storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
498 }
499 } else {
500 totalRewardVector = rewardModel.getStateActionRewardVector();
501 }
502
504 env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative);
505}
506
507template<typename ValueType, typename RewardModelType>
510 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
511 std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
512 bool qualitative) {
513 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
514
515 storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector);
516
517 std::vector<ValueType> totalRewardVector;
518 if (rewardModel.hasStateRewards()) {
519 totalRewardVector = rewardModel.getStateRewardVector();
520 typename std::vector<ValueType>::const_iterator it2 = exitRateVector.begin();
521 for (typename std::vector<ValueType>::iterator it1 = totalRewardVector.begin(), ite1 = totalRewardVector.end(); it1 != ite1; ++it1, ++it2) {
522 *it1 /= *it2;
523 }
524 if (rewardModel.hasStateActionRewards()) {
525 storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
526 }
527 if (rewardModel.hasTransitionRewards()) {
528 storm::utility::vector::addVectors(totalRewardVector, probabilityMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix()),
529 totalRewardVector);
530 }
531 } else if (rewardModel.hasTransitionRewards()) {
532 totalRewardVector = probabilityMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix());
533 if (rewardModel.hasStateActionRewards()) {
534 storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
535 }
536 } else {
537 totalRewardVector = rewardModel.getStateActionRewardVector();
538 }
539
540 RewardModelType dtmcRewardModel(std::move(totalRewardVector));
541 return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeTotalRewards(env, std::move(goal), probabilityMatrix, backwardTransitions,
542 dtmcRewardModel, qualitative);
543}
544
545template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type>
547 storm::storage::BitVector const& initialStates,
548 storm::storage::BitVector const& phiStates,
549 storm::storage::BitVector const& psiStates,
550 std::vector<ValueType> const& exitRates, double timeBound) {
551 // Compute transient probabilities going from initial state
552 // Instead of y=Px we now compute y=xP <=> y^T=P^Tx^T via transposition
553 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
554
555 // Create the result vector.
556 std::vector<ValueType> result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
557
558 storm::storage::SparseMatrix<ValueType> transposedMatrix(rateMatrix);
559 transposedMatrix.makeRowsAbsorbing(psiStates);
560 std::vector<ValueType> newRates = exitRates;
561 for (auto state : psiStates) {
562 newRates[state] = storm::utility::one<ValueType>();
563 }
564
565 // Identify all maybe states which have a probability greater than 0 to be reached from the initial state.
566 // storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(transposedMatrix, phiStates, initialStates);
567 // STORM_LOG_INFO("Found " << statesWithProbabilityGreater0.getNumberOfSetBits() << " states with probability greater 0.");
568
569 // storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & ~initialStates;//phiStates | psiStates;
570 storm::storage::BitVector relevantStates(numberOfStates, true);
571 STORM_LOG_DEBUG(relevantStates.getNumberOfSetBits() << " relevant states.");
572
573 if (!relevantStates.empty()) {
574 // Find the maximal rate of all relevant states to take it as the uniformization rate.
575 ValueType uniformizationRate = 0;
576 for (auto state : relevantStates) {
577 uniformizationRate = std::max(uniformizationRate, newRates[state]);
578 }
579 uniformizationRate *= 1.02;
580 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
581
582 transposedMatrix = transposedMatrix.transpose();
583
584 // Compute the uniformized matrix.
585 storm::storage::SparseMatrix<ValueType> uniformizedMatrix = computeUniformizedMatrix(transposedMatrix, relevantStates, uniformizationRate, newRates);
586
587 // Compute the vector that is to be added as a compensation for removing the absorbing states.
588 /*std::vector<ValueType> b = transposedMatrix.getConstrainedRowSumVector(relevantStates, initialStates);
589 for (auto& element : b) {
590 element /= uniformizationRate;
591 std::cout << element << '\n';
592 }*/
593
594 ValueType epsilon = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision()) / 8.0;
596 "Computation of transient probabilities with relative precision not supported. Using absolute precision instead.");
597 std::vector<ValueType> values(relevantStates.getNumberOfSetBits(), storm::utility::zero<ValueType>());
598 // Set initial states
599 size_t i = 0;
600 ValueType initDist = storm::utility::one<ValueType>() / initialStates.getNumberOfSetBits();
601 for (auto state : relevantStates) {
602 if (initialStates.get(state)) {
603 values[i] = initDist;
604 }
605 ++i;
606 }
607 // Finally compute the transient probabilities.
608 std::vector<ValueType> subresult =
609 computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, values, epsilon);
610
611 storm::utility::vector::setVectorValues(result, relevantStates, subresult);
612 }
613
614 return result;
615}
616
617template<typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type>
620 storm::storage::BitVector const&, std::vector<ValueType> const&, double) {
621 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded until probabilities is unsupported for this value type.");
622}
623
624template<typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type>
626 storm::storage::BitVector const& maybeStates,
627 ValueType uniformizationRate, std::vector<ValueType> const& exitRates) {
628 STORM_LOG_DEBUG("Computing uniformized matrix using uniformization rate " << uniformizationRate << ".");
629 STORM_LOG_DEBUG("Keeping " << maybeStates.getNumberOfSetBits() << " rows.");
630
631 // Create the submatrix that only contains the states with a positive probability (including the
632 // psi states) and reserve space for elements on the diagonal.
633 storm::storage::SparseMatrix<ValueType> uniformizedMatrix = rateMatrix.getSubmatrix(false, maybeStates, maybeStates, true);
634
635 // Now we need to perform the actual uniformization. That is, all entries need to be divided by
636 // the uniformization rate, and the diagonal needs to be set to the negative exit rate of the
637 // state plus the self-loop rate and then increased by one.
638 uint_fast64_t currentRow = 0;
639 for (auto state : maybeStates) {
640 for (auto& element : uniformizedMatrix.getRow(currentRow)) {
641 if (element.getColumn() == currentRow) {
642 element.setValue((element.getValue() - exitRates[state]) / uniformizationRate + storm::utility::one<ValueType>());
643 } else {
644 element.setValue(element.getValue() / uniformizationRate);
645 }
646 }
647 ++currentRow;
648 }
649
650 return uniformizedMatrix;
651}
652
653template<typename ValueType, bool useMixedPoissonProbabilities, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type>
655 storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix,
656 std::vector<ValueType> const* addVector, ValueType timeBound,
657 ValueType uniformizationRate, std::vector<ValueType> values, ValueType epsilon) {
658 STORM_LOG_WARN_COND(epsilon > storm::utility::convertNumber<ValueType>(1e-20),
659 "Very low truncation error " << epsilon << " requested. Numerical inaccuracies are possible.");
660 ValueType lambda = timeBound * uniformizationRate;
661
662 // If no time can pass, the current values are the result.
663 if (storm::utility::isZero(lambda)) {
664 return values;
665 }
666
667 // Use Fox-Glynn to get the truncation points and the weights.
669 STORM_LOG_DEBUG("Fox-Glynn cutoff points: left=" << foxGlynnResult.left << ", right=" << foxGlynnResult.right);
670 // foxGlynnResult.weights do not sum up to one. This is to enhance numerical stability.
671
672 // If the cumulative reward is to be computed, we need to adjust the weights.
673 if (useMixedPoissonProbabilities) {
674 // The following computes a vector v such that
675 // v[i] = foxGlynnResult.totalWeight - sum_{j=0}^{i} foxGlynnResult.weights[j]
676 // = sum_{j=i+1}^{n} foxGlynnResult.weights[j] for i=0,...,n-1
677 // and then sets foxGlynnResult.totalWeight = v / uniformizationRate.
678 // We do this in place and with numerical stability in mind. Note that the weights commonly range to values from 1e-200 to 1e+200
679 uint64_t l{0ull}, r{foxGlynnResult.weights.size()};
680 ValueType sumLeft{storm::utility::zero<ValueType>()}, sumRight{storm::utility::zero<ValueType>()};
681 while (l < r) {
682 if (foxGlynnResult.weights[l] < foxGlynnResult.weights[r]) {
683 sumLeft += foxGlynnResult.weights[l];
684 foxGlynnResult.weights[l] = (foxGlynnResult.totalWeight - sumLeft) / uniformizationRate;
685 ++l;
686 } else {
687 --r;
688 auto const tmp = foxGlynnResult.weights[r];
689 foxGlynnResult.weights[r] = sumRight / uniformizationRate;
690 sumRight += tmp;
691 }
692 }
693 auto const relDiff = storm::utility::abs<ValueType>(foxGlynnResult.totalWeight - (sumLeft + sumRight)) / foxGlynnResult.totalWeight;
694 STORM_LOG_WARN_COND(relDiff < storm::utility::convertNumber<ValueType>(1e-8),
695 "Numerical instability when adjusting the FoxGlynn weights. Relative Difference: " << relDiff << ".");
696 }
697
698 STORM_LOG_DEBUG("Starting iterations with " << uniformizedMatrix.getRowCount() << " x " << uniformizedMatrix.getColumnCount() << " matrix.");
699
700 // Initialize result.
701 std::vector<ValueType> result;
702 uint_fast64_t startingIteration = foxGlynnResult.left;
703 if (startingIteration == 0) {
704 result = values;
705 storm::utility::vector::scaleVectorInPlace(result, foxGlynnResult.weights.front());
706 ++startingIteration;
707 } else {
708 if (useMixedPoissonProbabilities) {
709 result = std::vector<ValueType>(values.size());
710 std::function<ValueType(ValueType const&)> scaleWithUniformizationRate = [&uniformizationRate](ValueType const& a) -> ValueType {
711 return a / uniformizationRate;
712 };
713 storm::utility::vector::applyPointwise(values, result, scaleWithUniformizationRate);
714 } else {
715 result = std::vector<ValueType>(values.size());
716 }
717 }
718
719 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, uniformizedMatrix);
720 if (!useMixedPoissonProbabilities && foxGlynnResult.left > 1) {
721 // Perform the matrix-vector multiplications (without adding).
722 multiplier->repeatedMultiply(env, values, addVector, foxGlynnResult.left - 1);
723 } else if (useMixedPoissonProbabilities) {
724 std::function<ValueType(ValueType const&, ValueType const&)> addAndScale = [&uniformizationRate](ValueType const& a, ValueType const& b) {
725 return a + b / uniformizationRate;
726 };
727
728 // For the iterations below the left truncation point, we need to add and scale the result with the uniformization rate.
729 for (uint_fast64_t index = 1; index < startingIteration; ++index) {
730 multiplier->multiply(env, values, nullptr, values);
731 storm::utility::vector::applyPointwise(result, values, result, addAndScale);
732 }
733 // To make sure that the values obtained before the left truncation point have the same 'impact' on the total result as the values obtained
734 // between the left and right truncation point, we scale them here with the total sum of the weights.
735 // Note that we divide with this value afterwards. This is to improve numerical stability.
736 if (foxGlynnResult.left > 0) {
737 storm::utility::vector::scaleVectorInPlace<ValueType, ValueType>(result, foxGlynnResult.totalWeight);
738 }
739 }
740
741 // For the indices that fall in between the truncation points, we need to perform the matrix-vector
742 // multiplication, scale and add the result.
743 ValueType weight = 0;
744 std::function<ValueType(ValueType const&, ValueType const&)> addAndScale = [&weight](ValueType const& a, ValueType const& b) { return a + weight * b; };
745 for (uint_fast64_t index = startingIteration; index <= foxGlynnResult.right; ++index) {
746 multiplier->multiply(env, values, addVector, values);
747
748 weight = foxGlynnResult.weights[index - foxGlynnResult.left];
749 storm::utility::vector::applyPointwise(result, values, result, addAndScale);
750 }
751
752 // Finally, divide the result by the total weight
753 storm::utility::vector::scaleVectorInPlace<ValueType, ValueType>(result, storm::utility::one<ValueType>() / foxGlynnResult.totalWeight);
754 return result;
755}
756
757template<typename ValueType>
759 std::vector<ValueType> const& exitRates) {
760 // Turn the rates into probabilities by scaling each row with the exit rate of the state.
762 for (uint_fast64_t row = 0; row < result.getRowCount(); ++row) {
763 for (auto& entry : result.getRow(row)) {
764 entry.setValue(entry.getValue() / exitRates[row]);
765 }
766 }
767 return result;
768}
769
770template<typename ValueType>
772 std::vector<ValueType> const& exitRates) {
773 storm::storage::SparseMatrix<ValueType> generatorMatrix(rateMatrix, true);
774
775 // Place the negative exit rate on the diagonal.
776 for (uint_fast64_t row = 0; row < generatorMatrix.getRowCount(); ++row) {
777 for (auto& entry : generatorMatrix.getRow(row)) {
778 if (entry.getColumn() == row) {
779 entry.setValue(-exitRates[row] + entry.getValue());
780 }
781 }
782 }
783
784 return generatorMatrix;
785}
786
789 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
790 std::vector<double> const& exitRates, bool qualitative, double lowerBound, double upperBound);
791
793 storm::storage::SparseMatrix<double> const& rateMatrix,
794 storm::storage::SparseMatrix<double> const& backwardTransitions,
795 std::vector<double> const& exitRateVector,
796 storm::storage::BitVector const& phiStates,
797 storm::storage::BitVector const& psiStates, bool qualitative);
798
800 storm::storage::SparseMatrix<double> const& rateMatrix,
801 std::vector<double> const& exitRateVector,
802 storm::storage::BitVector const& initialStates,
803 storm::storage::BitVector const& phiStates,
804 storm::storage::BitVector const& psiStates);
805
806template std::vector<double> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& rateMatrix,
807 std::vector<double> const& exitRateVector,
808 storm::storage::BitVector const& nextStates);
809
811 storm::storage::SparseMatrix<double> const& rateMatrix,
812 std::vector<double> const& exitRateVector,
814 double timeBound);
815
817 storm::storage::SparseMatrix<double> const& rateMatrix,
818 storm::storage::SparseMatrix<double> const& backwardTransitions,
819 std::vector<double> const& exitRateVector,
820 storm::storage::BitVector const& targetStates, bool qualitative);
821
823 storm::storage::SparseMatrix<double> const& rateMatrix,
824 storm::storage::SparseMatrix<double> const& backwardTransitions,
825 std::vector<double> const& exitRateVector,
827 storm::storage::BitVector const& targetStates, bool qualitative);
828
830 storm::storage::SparseMatrix<double> const& rateMatrix,
831 storm::storage::SparseMatrix<double> const& backwardTransitions,
832 std::vector<double> const& exitRateVector,
833 storm::models::sparse::StandardRewardModel<double> const& rewardModel, bool qualitative);
834
836 storm::storage::SparseMatrix<double> const& rateMatrix,
837 std::vector<double> const& exitRateVector,
839 double timeBound);
840
842 Environment const& env, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::BitVector const& initialStates,
843 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<double> const& exitRates, double timeBound);
844
846 storm::storage::BitVector const& maybeStates,
847 double uniformizationRate, std::vector<double> const& exitRates);
848
849template std::vector<double> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env,
850 storm::storage::SparseMatrix<double> const& uniformizedMatrix,
851 std::vector<double> const* addVector, double timeBound,
852 double uniformizationRate, std::vector<double> values, double epsilon);
853
854#ifdef STORM_HAVE_CARL
855template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeBoundedUntilProbabilities(
857 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
858 storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const& exitRates, bool qualitative, double lowerBound, double upperBound);
859template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeBoundedUntilProbabilities(
861 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates,
862 storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const& exitRates, bool qualitative, double lowerBound, double upperBound);
863
864template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeUntilProbabilities(
866 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
867 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative);
868template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeUntilProbabilities(
870 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
871 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative);
872
873template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeAllUntilProbabilities(
875 std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& phiStates,
876 storm::storage::BitVector const& psiStates);
877template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeAllUntilProbabilities(
879 std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& phiStates,
880 storm::storage::BitVector const& psiStates);
881
882template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env,
884 std::vector<storm::RationalNumber> const& exitRateVector,
885 storm::storage::BitVector const& nextStates);
886template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeNextProbabilities(
887 Environment const& env, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector,
888 storm::storage::BitVector const& nextStates);
889
890template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeInstantaneousRewards(
892 std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel,
893 double timeBound);
894template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeInstantaneousRewards(
896 std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel,
897 double timeBound);
898
899template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityTimes(
901 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
902 storm::storage::BitVector const& targetStates, bool qualitative);
903template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityTimes(
905 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
906 storm::storage::BitVector const& targetStates, bool qualitative);
907
908template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityRewards(
910 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
911 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative);
912template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityRewards(
914 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
915 storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative);
916
917template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeTotalRewards(
919 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
920 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, bool qualitative);
921template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeTotalRewards(
923 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
925
926template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeCumulativeRewards(
928 std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel,
929 double timeBound);
930template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeCumulativeRewards(
932 std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel,
933 double timeBound);
934
935template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeAllTransientProbabilities(
936 Environment const& env, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::BitVector const& initialStates,
937 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const& exitRates,
938 double timeBound);
939template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeAllTransientProbabilities(
940 Environment const& env, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::BitVector const& initialStates,
941 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const& exitRates,
942 double timeBound);
943
945 std::vector<double> const& exitRates);
947 storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRates);
949 storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRates);
950
951#endif
952} // namespace helper
953} // namespace modelchecker
954} // namespace storm
SolverEnvironment & solver()
TimeBoundedSolverEnvironment & timeBounded()
storm::RationalNumber const & getPrecision() const
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, double timeBound)
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 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 > 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, double timeBound)
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 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 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< 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 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, double lowerBound, double upperBound)
static std::vector< 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 > 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 > computeInstantaneousRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &rateMatrix, std::vector< ValueType > const &exitRateVector, RewardModelType const &rewardModel, double timeBound)
static std::vector< 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 > computeNextProbabilities(Environment const &env, storm::storage::SparseMatrix< ValueType > const &rateMatrix, std::vector< ValueType > const &exitRateVector, storm::storage::BitVector const &nextStates)
static std::vector< ValueType > computeNextProbabilities(Environment const &env, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &nextStates)
static std::vector< ValueType > computeReachabilityRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&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 std::vector< ValueType > computeUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&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())
static std::vector< ValueType > computeAllUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&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< ValueType > computeTotalRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
std::unique_ptr< Multiplier< ValueType > > create(Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix)
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:18
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
uint_fast64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
bool get(uint_fast64_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.
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...
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.
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)
Definition logging.h:29
#define STORM_LOG_DEBUG(message)
Definition logging.h:23
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:38
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
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...
Definition graph.cpp:322
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.
Definition vector.h:443
void setVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< T > const &values)
Sets the provided values at the provided positions in the given vector.
Definition vector.h:83
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...
Definition vector.h:189
T maximumElementAbs(std::vector< T > const &vector)
Definition vector.h:998
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...
Definition vector.h:398
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...
Definition vector.h:491
bool isZero(ValueType const &a)
Definition constants.cpp:41
LabParser.cpp.
Definition cli.cpp:18
std::vector< ValueType > weights
Definition numerical.h:15