Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseCtmcCslHelper.cpp
Go to the documentation of this file.
2
12#include "storm/utility/graph.h"
16
17namespace storm {
18namespace modelchecker {
19namespace helper {
20
21template<typename ValueType>
23 std::vector<ValueType> const& resultVector,
24 storm::storage::BitVector const& relevantPositions) {
25 // Check if the check is necessary for the provided environment
27 // No need to update epsilon
28 return false;
29 }
30
32 // If we need to compute values with relative precision, it might be necessary to increase the precision requirements (epsilon)
33 ValueType newEpsilon = epsilon;
34 // 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
35 for (uint64_t state : relevantPositions) {
36 if (storm::utility::isZero(resultVector[state])) {
37 newEpsilon = std::min(epsilon * storm::utility::convertNumber<ValueType>(0.1), newEpsilon);
38 } else {
39 ValueType relativeError = epsilon / resultVector[state]; // epsilon is an upper bound for the absolute error we made
40 if (relativeError > precision) {
41 newEpsilon = std::min(resultVector[state] * precision, newEpsilon);
42 }
43 }
44 }
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.");
48 epsilon = newEpsilon;
49 return true;
50 } else {
51 return false;
52 }
53}
54
55template<typename ValueType>
59 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
60 std::vector<ValueType> const& exitRates, bool qualitative, ValueType lowerBound, std::optional<ValueType> const& upperBound) {
61 STORM_LOG_THROW(!env.solver().isForceExact(), storm::exceptions::InvalidOperationException,
62 "Exact computations not possible for bounded until probabilities.");
63
64 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
65
66 // If the time bounds are [0, inf], we rather call untimed reachability.
67 if (storm::utility::isZero(lowerBound) && !upperBound) {
68 return computeUntilProbabilities(env, std::move(goal), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative);
69 }
70
71 // From this point on, we know that we have to solve a more complicated problem [t, t'] with either t != 0
72 // or t' != inf.
73
74 // Create the result vector.
75 std::vector<ValueType> result;
76
77 // Set the possible (absolute) error allowed for truncation (epsilon for fox-glynn)
79
80 // If we identify the states that have probability 0 of reaching the target states, we can exclude them from the
81 // further computations.
82 storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(backwardTransitions, phiStates, psiStates);
83 STORM_LOG_INFO("Found " << statesWithProbabilityGreater0.getNumberOfSetBits() << " states with probability greater 0.");
84 storm::storage::BitVector statesWithProbabilityGreater0NonPsi = statesWithProbabilityGreater0 & ~psiStates;
85 STORM_LOG_INFO("Found " << statesWithProbabilityGreater0NonPsi.getNumberOfSetBits() << " 'maybe' states.");
86
87 // the positions within the result for which the precision needs to be checked
88 storm::storage::BitVector relevantValues;
89 if (goal.hasRelevantValues()) {
90 relevantValues = std::move(goal.relevantValues());
91 relevantValues &= statesWithProbabilityGreater0;
92 } else {
93 relevantValues = statesWithProbabilityGreater0;
94 }
95
96 do { // Iterate until the desired precision is reached (only relevant for relative precision criterion)
97 if (!statesWithProbabilityGreater0.empty()) {
98 if (upperBound && storm::utility::isZero(*upperBound)) {
99 // In this case, the interval is of the form [0, 0].
100 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
102 } else {
103 if (storm::utility::isZero(lowerBound)) {
104 // In this case, the interval is of the form [0, t].
105 // Note that this excludes [0, inf] since this is untimed reachability and we considered this case earlier.
106
107 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
109 if (!statesWithProbabilityGreater0NonPsi.empty()) {
110 // Find the maximal rate of all 'maybe' states to take it as the uniformization rate.
111 ValueType uniformizationRate = 0;
112 for (uint64_t state : statesWithProbabilityGreater0NonPsi) {
113 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
114 }
115 uniformizationRate *= 1.02;
116 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
117
118 // Compute the uniformized matrix.
120 computeUniformizedMatrix(rateMatrix, statesWithProbabilityGreater0NonPsi, uniformizationRate, exitRates);
121
122 // Compute the vector that is to be added as a compensation for removing the absorbing states.
123 std::vector<ValueType> b = rateMatrix.getConstrainedRowSumVector(statesWithProbabilityGreater0NonPsi, psiStates);
124 for (auto& element : b) {
125 element /= uniformizationRate;
126 }
127
128 // Finally compute the transient probabilities.
129 std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNumberOfSetBits(), storm::utility::zero<ValueType>());
130 std::vector<ValueType> subresult =
131 computeTransientProbabilities(env, uniformizedMatrix, &b, *upperBound, uniformizationRate, values, epsilon);
132 storm::utility::vector::setVectorValues(result, statesWithProbabilityGreater0NonPsi, subresult);
133 }
134 } else if (!upperBound) {
135 // In this case, the interval is of the form [t, inf] with t != 0.
136
137 // Start by computing the (unbounded) reachability probabilities of reaching psi states while
138 // staying in phi states.
139 result = computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), rateMatrix, backwardTransitions, exitRates, phiStates,
140 psiStates, qualitative);
141
142 // Determine the set of states that must be considered further.
143 storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & phiStates;
144 std::vector<ValueType> subResult(relevantStates.getNumberOfSetBits());
145 storm::utility::vector::selectVectorValues(subResult, relevantStates, result);
146
147 ValueType uniformizationRate = 0;
148 for (uint64_t state : relevantStates) {
149 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
150 }
151 uniformizationRate *= 1.02;
152 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
153
154 // Compute the uniformized matrix.
156 computeUniformizedMatrix(rateMatrix, relevantStates, uniformizationRate, exitRates);
157
158 // Compute the transient probabilities.
159 subResult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, subResult, epsilon);
160
161 // Fill in the correct values.
163 storm::utility::vector::setVectorValues(result, relevantStates, subResult);
164 } else {
165 // In this case, the interval is of the form [t, t'] with t != 0 and t' != inf.
166
167 if (lowerBound != *upperBound) {
168 // In this case, the interval is of the form [t, t'] with t != 0, t' != inf and t != t'.
169
170 storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & phiStates;
171 std::vector<ValueType> newSubresult(relevantStates.getNumberOfSetBits(), storm::utility::zero<ValueType>());
172 storm::utility::vector::setVectorValues(newSubresult, psiStates % relevantStates, storm::utility::one<ValueType>());
173 if (!statesWithProbabilityGreater0NonPsi.empty()) {
174 // Find the maximal rate of all 'maybe' states to take it as the uniformization rate.
175 ValueType uniformizationRate = storm::utility::zero<ValueType>();
176 for (uint64_t state : statesWithProbabilityGreater0NonPsi) {
177 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
178 }
179 uniformizationRate *= 1.02;
180 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
181
182 // Compute the (first) uniformized matrix.
184 computeUniformizedMatrix(rateMatrix, statesWithProbabilityGreater0NonPsi, uniformizationRate, exitRates);
185
186 // Compute the vector that is to be added as a compensation for removing the absorbing states.
187 std::vector<ValueType> b = rateMatrix.getConstrainedRowSumVector(statesWithProbabilityGreater0NonPsi, psiStates);
188 for (auto& element : b) {
189 element /= uniformizationRate;
190 }
191
192 // Start by computing the transient probabilities of reaching a psi state in time t' - t.
193 std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNumberOfSetBits(), storm::utility::zero<ValueType>());
194 // divide the possible error by two since we will make this error two times.
195 std::vector<ValueType> subresult =
196 computeTransientProbabilities(env, uniformizedMatrix, &b, *upperBound - lowerBound, uniformizationRate, values,
198 storm::utility::vector::setVectorValues(newSubresult, statesWithProbabilityGreater0NonPsi % relevantStates, subresult);
199 }
200
201 // Then compute the transient probabilities of being in such a state after t time units. For this,
202 // we must re-uniformize the CTMC, so we need to compute the second uniformized matrix.
203 ValueType uniformizationRate = storm::utility::zero<ValueType>();
204 for (uint64_t state : relevantStates) {
205 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
206 }
207 uniformizationRate *= 1.02;
208 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
209
210 // Finally, we compute the second set of transient probabilities.
212 computeUniformizedMatrix(rateMatrix, relevantStates, uniformizationRate, exitRates);
213 newSubresult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult,
215
216 // Fill in the correct values.
217 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
219 storm::utility::vector::setVectorValues(result, relevantStates, newSubresult);
220 } else {
221 // In this case, the interval is of the form [t, t] with t != 0, t != inf.
222
223 std::vector<ValueType> newSubresult = std::vector<ValueType>(statesWithProbabilityGreater0.getNumberOfSetBits());
224 storm::utility::vector::setVectorValues(newSubresult, psiStates % statesWithProbabilityGreater0, storm::utility::one<ValueType>());
225
226 // Then compute the transient probabilities of being in such a state after t time units. For this,
227 // we must re-uniformize the CTMC, so we need to compute the second uniformized matrix.
228 ValueType uniformizationRate = storm::utility::zero<ValueType>();
229 for (uint64_t state : statesWithProbabilityGreater0) {
230 uniformizationRate = std::max(uniformizationRate, exitRates[state]);
231 }
232 uniformizationRate *= 1.02;
233 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
234
235 // Finally, we compute the second set of transient probabilities.
237 computeUniformizedMatrix(rateMatrix, statesWithProbabilityGreater0, uniformizationRate, exitRates);
238 newSubresult =
239 computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult, epsilon);
240
241 // Fill in the correct values.
242 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
243 storm::utility::vector::setVectorValues(result, ~statesWithProbabilityGreater0, storm::utility::zero<ValueType>());
244 storm::utility::vector::setVectorValues(result, statesWithProbabilityGreater0, newSubresult);
245 }
246 }
247 }
248 } else {
249 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
250 }
251 } while (checkAndUpdateTransientProbabilityEpsilon(env, epsilon, result, relevantValues));
252 return result;
253}
254
255template<typename ValueType>
258 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
259 std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates,
260 storm::storage::BitVector const& psiStates, bool qualitative) {
261 return SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(env, std::move(goal), computeProbabilityMatrix(rateMatrix, exitRateVector),
262 backwardTransitions, phiStates, psiStates, qualitative)
263 .values;
264}
265
266template<typename ValueType>
269 std::vector<ValueType> const& exitRateVector,
270 storm::storage::BitVector const& initialStates,
271 storm::storage::BitVector const& phiStates,
272 storm::storage::BitVector const& psiStates) {
273 return SparseDtmcPrctlHelper<ValueType>::computeAllUntilProbabilities(env, std::move(goal), computeProbabilityMatrix(rateMatrix, exitRateVector),
274 initialStates, phiStates, psiStates);
275}
276
277template<typename ValueType>
279 std::vector<ValueType> const& exitRateVector,
280 storm::storage::BitVector const& nextStates) {
281 return SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, computeProbabilityMatrix(rateMatrix, exitRateVector), nextStates);
282}
283
284template<typename ValueType, typename RewardModelType>
288 std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
289 ValueType timeBound) {
290 // Only compute the result if the model has a state-based reward model.
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.");
293
294 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
295
296 // Initialize result to state rewards of the this->getModel().
297 std::vector<ValueType> result(rewardModel.getStateRewardVector());
298
299 // If the time-bound is zero, just return the current reward vector
300 if (storm::utility::isZero(timeBound)) {
301 return result;
302 }
303 ValueType maxValue = storm::utility::vector::maximumElementAbs(result);
304
305 // If all entries are zero, we return the zero-vector
306 if (storm::utility::isZero(maxValue)) {
307 return result;
308 }
309
310 ValueType uniformizationRate = 0;
311 for (auto const& rate : exitRateVector) {
312 uniformizationRate = std::max(uniformizationRate, rate);
313 }
314 uniformizationRate *= 1.02;
315 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
316
318 computeUniformizedMatrix(rateMatrix, storm::storage::BitVector(numberOfStates, true), uniformizationRate, exitRateVector);
319
320 // Set the possible error allowed for truncation (epsilon for fox-glynn)
323 // Be more precise, if the maximum value is very small (precision can/has to be refined later)
324 epsilon *= std::min(storm::utility::one<ValueType>(), maxValue);
325 } else {
326 // Be more precise, if the maximal possible value is very large
327 epsilon /= std::max(storm::utility::one<ValueType>(), maxValue);
328 }
329
330 storm::storage::BitVector relevantValues;
331 if (goal.hasRelevantValues()) {
332 relevantValues = std::move(goal.relevantValues());
333 } else {
334 relevantValues = storm::storage::BitVector(result.size(), true);
335 }
336
337 // Loop until the desired precision is reached.
338 do {
339 result = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, result, epsilon);
340 } while (checkAndUpdateTransientProbabilityEpsilon(env, epsilon, result, relevantValues));
341
342 return result;
343}
344
345template<typename ValueType, typename RewardModelType>
349 std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
350 ValueType timeBound) {
351 STORM_LOG_THROW(!env.solver().isForceExact(), storm::exceptions::InvalidOperationException,
352 "Exact computations not possible for cumulative expected rewards.");
353
354 // Only compute the result if the model has a state-based reward model.
355 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
356
357 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
358
359 // If the time bound is zero, the result is the constant zero vector.
360 if (timeBound == 0) {
361 return std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
362 }
363
364 // Otherwise, we need to perform some computations.
365
366 // Start with the uniformization.
367 ValueType uniformizationRate = 0;
368 for (auto const& rate : exitRateVector) {
369 uniformizationRate = std::max(uniformizationRate, rate);
370 }
371 uniformizationRate *= 1.02;
372 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
373
375 computeUniformizedMatrix(rateMatrix, storm::storage::BitVector(numberOfStates, true), uniformizationRate, exitRateVector);
376
377 // Compute the total state reward vector.
378 std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(rateMatrix, exitRateVector);
379 ValueType maxReward = storm::utility::vector::maximumElementAbs(totalRewardVector);
380
381 // If all rewards are zero, the result is the constant zero vector.
382 if (storm::utility::isZero(maxReward)) {
383 return std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
384 }
385
386 // Set the possible (absolute) error allowed for truncation (epsilon for fox-glynn)
389 // Be more precise, if the value is very small (precision can/has to be refined later)
390 epsilon *= std::min(storm::utility::one<ValueType>(), maxReward);
391 } else {
392 // Be more precise, if the maximal possible value is very large
393 epsilon /= std::max(storm::utility::one<ValueType>(), maxReward * timeBound);
394 }
395
396 storm::storage::BitVector relevantValues;
397 if (goal.hasRelevantValues()) {
398 relevantValues = std::move(goal.relevantValues());
399 } else {
400 relevantValues = storm::storage::BitVector(totalRewardVector.size(), true);
401 }
402
403 // Loop until the desired precision is reached.
404 std::vector<ValueType> result;
405 do {
406 result = computeTransientProbabilities<ValueType, true>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, totalRewardVector, epsilon);
407 } while (checkAndUpdateTransientProbabilityEpsilon(env, epsilon, result, relevantValues));
408
409 return result;
410}
411
412template<typename ValueType>
413std::vector<storm::utility::ExtendedValueType<ValueType>> SparseCtmcCslHelper::computeReachabilityTimes(
415 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector,
416 storm::storage::BitVector const& targetStates, bool qualitative) {
417 // Compute expected time on CTMC by reduction to DTMC with rewards.
418 storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector);
419
420 // Initialize rewards.
421 std::vector<ValueType> totalRewardVector;
422 for (size_t i = 0; i < exitRateVector.size(); ++i) {
423 if (targetStates[i] || storm::utility::isZero(exitRateVector[i])) {
424 // Set reward for target states or states without outgoing transitions to 0.
425 totalRewardVector.push_back(storm::utility::zero<ValueType>());
426 } else {
427 // Reward is (1 / exitRate).
428 totalRewardVector.push_back(storm::utility::one<ValueType>() / exitRateVector[i]);
429 }
430 }
431
433 env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative)
434 .values;
435}
436
437template<typename ValueType, typename RewardModelType>
438std::vector<storm::utility::ExtendedValueType<ValueType>> SparseCtmcCslHelper::computeReachabilityRewards(
440 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
441 storm::storage::BitVector const& targetStates, bool qualitative) {
442 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
443
444 storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector);
445
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) {
451 *it1 /= *it2;
452 }
453 if (rewardModel.hasStateActionRewards()) {
454 storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
455 }
456 if (rewardModel.hasTransitionRewards()) {
457 storm::utility::vector::addVectors(totalRewardVector, probabilityMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix()),
458 totalRewardVector);
459 }
460 } else if (rewardModel.hasTransitionRewards()) {
461 totalRewardVector = probabilityMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix());
462 if (rewardModel.hasStateActionRewards()) {
463 storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
464 }
465 } else {
466 totalRewardVector = rewardModel.getStateActionRewardVector();
467 }
468
469 // TODO: the DTMC helper also reports sound bounds on these values; carrying them through the CTMC helpers
470 // would let reward queries on CTMCs report an enclosure as well.
472 env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative)
473 .values;
474}
475
476template<typename ValueType, typename RewardModelType>
477std::vector<storm::utility::ExtendedValueType<ValueType>> SparseCtmcCslHelper::computeTotalRewards(
479 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
480 bool qualitative) {
481 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
482
483 storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector);
484
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) {
490 *it1 /= *it2;
491 }
492 if (rewardModel.hasStateActionRewards()) {
493 storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
494 }
495 if (rewardModel.hasTransitionRewards()) {
496 storm::utility::vector::addVectors(totalRewardVector, probabilityMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix()),
497 totalRewardVector);
498 }
499 } else if (rewardModel.hasTransitionRewards()) {
500 totalRewardVector = probabilityMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix());
501 if (rewardModel.hasStateActionRewards()) {
502 storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
503 }
504 } else {
505 totalRewardVector = rewardModel.getStateActionRewardVector();
506 }
507
508 RewardModelType dtmcRewardModel(std::move(totalRewardVector));
509 return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeTotalRewards(env, std::move(goal), probabilityMatrix, backwardTransitions,
510 dtmcRewardModel, qualitative)
511 .values;
512}
513
514template<typename ValueType>
517 storm::storage::BitVector const& initialStates,
518 storm::storage::BitVector const& phiStates,
519 storm::storage::BitVector const& psiStates,
520 std::vector<ValueType> const& exitRates, ValueType timeBound) {
521 // Compute transient probabilities going from initial state
522 // Instead of y=Px we now compute y=xP <=> y^T=P^Tx^T via transposition
523 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
524
525 // Create the result vector.
526 std::vector<ValueType> result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
527
528 storm::storage::SparseMatrix<ValueType> transposedMatrix(rateMatrix);
529 transposedMatrix.makeRowsAbsorbing(psiStates);
530 std::vector<ValueType> newRates = exitRates;
531 for (uint64_t state : psiStates) {
532 newRates[state] = storm::utility::one<ValueType>();
533 }
534
535 // Identify all maybe states which have a probability greater than 0 to be reached from the initial state.
536 // storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(transposedMatrix, phiStates, initialStates);
537 // STORM_LOG_INFO("Found " << statesWithProbabilityGreater0.getNumberOfSetBits() << " states with probability greater 0.");
538
539 // storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & ~initialStates;//phiStates | psiStates;
540 storm::storage::BitVector relevantStates(numberOfStates, true);
541 STORM_LOG_DEBUG(relevantStates.getNumberOfSetBits() << " relevant states.");
542
543 if (!relevantStates.empty()) {
544 // Find the maximal rate of all relevant states to take it as the uniformization rate.
545 ValueType uniformizationRate = 0;
546 for (uint64_t state : relevantStates) {
547 uniformizationRate = std::max(uniformizationRate, newRates[state]);
548 }
549 uniformizationRate *= 1.02;
550 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
551
552 transposedMatrix = transposedMatrix.transpose();
553
554 // Compute the uniformized matrix.
555 storm::storage::SparseMatrix<ValueType> uniformizedMatrix = computeUniformizedMatrix(transposedMatrix, relevantStates, uniformizationRate, newRates);
556
557 // Compute the vector that is to be added as a compensation for removing the absorbing states.
558 /*std::vector<ValueType> b = transposedMatrix.getConstrainedRowSumVector(relevantStates, initialStates);
559 for (auto& element : b) {
560 element /= uniformizationRate;
561 std::cout << element << '\n';
562 }*/
563
564 ValueType epsilon = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision()) / 8.0;
566 "Computation of transient probabilities with relative precision not supported. Using absolute precision instead.");
567 std::vector<ValueType> values(relevantStates.getNumberOfSetBits(), storm::utility::zero<ValueType>());
568 // Set initial states
569 size_t i = 0;
570 ValueType initDist = storm::utility::one<ValueType>() / initialStates.getNumberOfSetBits();
571 for (uint64_t state : relevantStates) {
572 if (initialStates.get(state)) {
573 values[i] = initDist;
574 }
575 ++i;
576 }
577 // Finally compute the transient probabilities.
578 std::vector<ValueType> subresult =
579 computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, values, epsilon);
580
581 storm::utility::vector::setVectorValues(result, relevantStates, subresult);
582 }
583
584 return result;
585}
586
587template<typename ValueType>
590 storm::storage::BitVector const& maybeStates,
591 ValueType uniformizationRate, std::vector<ValueType> const& exitRates) {
592 STORM_LOG_DEBUG("Computing uniformized matrix using uniformization rate " << uniformizationRate << ".");
593 STORM_LOG_DEBUG("Keeping " << maybeStates.getNumberOfSetBits() << " rows.");
594
595 // Create the submatrix that only contains the states with a positive probability (including the
596 // psi states) and reserve space for elements on the diagonal.
597 storm::storage::SparseMatrix<ValueType> uniformizedMatrix = rateMatrix.getSubmatrix(false, maybeStates, maybeStates, true);
598
599 // Now we need to perform the actual uniformization. That is, all entries need to be divided by
600 // the uniformization rate, and the diagonal needs to be set to the negative exit rate of the
601 // state plus the self-loop rate and then increased by one.
602 uint_fast64_t currentRow = 0;
603 for (uint64_t state : maybeStates) {
604 for (auto& element : uniformizedMatrix.getRow(currentRow)) {
605 if (element.getColumn() == currentRow) {
606 element.setValue((element.getValue() - exitRates[state]) / uniformizationRate + storm::utility::one<ValueType>());
607 } else {
608 element.setValue(element.getValue() / uniformizationRate);
609 }
610 }
611 ++currentRow;
612 }
613
614 return uniformizedMatrix;
615}
616
617template<typename ValueType, bool useMixedPoissonProbabilities>
620 storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix,
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;
626
627 // If no time can pass, the current values are the result.
628 if (storm::utility::isZero(lambda)) {
629 return values;
630 }
631
632 // Use Fox-Glynn to get the truncation points and the weights.
634 STORM_LOG_DEBUG("Fox-Glynn cutoff points: left=" << foxGlynnResult.left << ", right=" << foxGlynnResult.right);
635 // foxGlynnResult.weights do not sum up to one. This is to enhance numerical stability.
636
637 // If the cumulative reward is to be computed, we need to adjust the weights.
638 if (useMixedPoissonProbabilities) {
639 // The following computes a vector v such that
640 // v[i] = foxGlynnResult.totalWeight - sum_{j=0}^{i} foxGlynnResult.weights[j]
641 // = sum_{j=i+1}^{n-1} foxGlynnResult.weights[j] for i=0,...,n-1
642 // and then sets foxGlynnResult.weights = v / uniformizationRate.
643 // 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
644 uint64_t l{0ull}, r{foxGlynnResult.weights.size() - 1};
646 while (l <= r) {
647 if (foxGlynnResult.weights[l] < foxGlynnResult.weights[r]) {
648 sumLeft += foxGlynnResult.weights[l];
649 foxGlynnResult.weights[l] = (foxGlynnResult.totalWeight - sumLeft) / uniformizationRate;
650 ++l;
651 } else {
652 auto const tmp = foxGlynnResult.weights[r];
653 foxGlynnResult.weights[r] = sumRight / uniformizationRate;
654 sumRight += tmp;
655 if (r == 0) {
656 // Avoid underflow for unsigned int
657 break;
658 }
659 --r;
660 }
661 }
662 auto const relDiff = storm::utility::abs<ValueType>(foxGlynnResult.totalWeight - (sumLeft + sumRight)) / foxGlynnResult.totalWeight;
664 "Numerical instability when adjusting the FoxGlynn weights. Relative Difference: " << relDiff << ".");
665 }
666
667 STORM_LOG_DEBUG("Starting iterations with " << uniformizedMatrix.getRowCount() << " x " << uniformizedMatrix.getColumnCount() << " matrix.");
668
669 // Initialize result.
670 std::vector<ValueType> result;
671 uint_fast64_t startingIteration = foxGlynnResult.left;
672 if (startingIteration == 0) {
673 result = values;
674 storm::utility::vector::scaleVectorInPlace(result, foxGlynnResult.weights.front());
675 ++startingIteration;
676 } else {
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;
681 };
682 storm::utility::vector::applyPointwise(values, result, scaleWithUniformizationRate);
683 } else {
684 result = std::vector<ValueType>(values.size());
685 }
686 }
687
688 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, uniformizedMatrix);
689 if (!useMixedPoissonProbabilities && foxGlynnResult.left > 1) {
690 // Perform the matrix-vector multiplications (without adding).
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;
695 };
696
697 // For the iterations below the left truncation point, we need to add and scale the result with the uniformization rate.
698 for (uint_fast64_t index = 1; index < startingIteration; ++index) {
699 multiplier->multiply(env, values, nullptr, values);
700 storm::utility::vector::applyPointwise(result, values, result, addAndScale);
701 }
702 // To make sure that the values obtained before the left truncation point have the same 'impact' on the total result as the values obtained
703 // between the left and right truncation point, we scale them here with the total sum of the weights.
704 // Note that we divide with this value afterwards. This is to improve numerical stability.
705 if (foxGlynnResult.left > 0) {
707 }
708 }
709
710 // For the indices that fall in between the truncation points, we need to perform the matrix-vector
711 // multiplication, scale and add the result.
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);
716
717 weight = foxGlynnResult.weights[index - foxGlynnResult.left];
718 storm::utility::vector::applyPointwise(result, values, result, addAndScale);
719 }
720
721 // Finally, divide the result by the total weight
723 return result;
724}
725
726template<typename ValueType>
728 std::vector<ValueType> const& exitRates) {
729 // Turn the rates into probabilities by scaling each row with the exit rate of the state.
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]);
734 }
735 }
736 return result;
737}
738
739template<typename ValueType>
741 std::vector<ValueType> const& exitRates) {
742 storm::storage::SparseMatrix<ValueType> generatorMatrix(rateMatrix, true);
743
744 // Place the negative exit rate on the diagonal.
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());
749 }
750 }
751 }
752
753 return generatorMatrix;
754}
755
758 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
759 std::vector<double> const& exitRates, bool qualitative, double lowerBound, std::optional<double> const& upperBound);
760
762 storm::storage::SparseMatrix<double> const& rateMatrix,
763 storm::storage::SparseMatrix<double> const& backwardTransitions,
764 std::vector<double> const& exitRateVector,
765 storm::storage::BitVector const& phiStates,
766 storm::storage::BitVector const& psiStates, bool qualitative);
767
769 storm::storage::SparseMatrix<double> const& rateMatrix,
770 std::vector<double> const& exitRateVector,
771 storm::storage::BitVector const& initialStates,
772 storm::storage::BitVector const& phiStates,
773 storm::storage::BitVector const& psiStates);
774
775template std::vector<double> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& rateMatrix,
776 std::vector<double> const& exitRateVector,
777 storm::storage::BitVector const& nextStates);
778
780 storm::storage::SparseMatrix<double> const& rateMatrix,
781 std::vector<double> const& exitRateVector,
783 double timeBound);
784
785template std::vector<storm::utility::ExtendedValueType<double>> SparseCtmcCslHelper::computeReachabilityTimes(
787 storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& targetStates,
788 bool qualitative);
789
790template std::vector<storm::utility::ExtendedValueType<double>> SparseCtmcCslHelper::computeReachabilityRewards(
792 storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector,
793 storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative);
794
795template std::vector<storm::utility::ExtendedValueType<double>> SparseCtmcCslHelper::computeTotalRewards(
797 storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector,
798 storm::models::sparse::StandardRewardModel<double> const& rewardModel, bool qualitative);
799
801 storm::storage::SparseMatrix<double> const& rateMatrix,
802 std::vector<double> const& exitRateVector,
804 double timeBound);
805
807 Environment const& env, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::BitVector const& initialStates,
808 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<double> const& exitRates, double timeBound);
809
811 storm::storage::BitVector const& maybeStates,
812 double uniformizationRate, std::vector<double> const& exitRates);
813
814template std::vector<double> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env,
815 storm::storage::SparseMatrix<double> const& uniformizedMatrix,
816 std::vector<double> const* addVector, double timeBound,
817 double uniformizationRate, std::vector<double> values, double epsilon);
818
819template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeUntilProbabilities(
821 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
822 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative);
823template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeUntilProbabilities(
825 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
826 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative);
827
828template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeAllUntilProbabilities(
830 std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& phiStates,
831 storm::storage::BitVector const& psiStates);
832template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeAllUntilProbabilities(
834 std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& phiStates,
835 storm::storage::BitVector const& psiStates);
836
837template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env,
839 std::vector<storm::RationalNumber> const& exitRateVector,
840 storm::storage::BitVector const& nextStates);
841template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeNextProbabilities(
842 Environment const& env, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector,
843 storm::storage::BitVector const& nextStates);
844
845template std::vector<storm::ExtendedRationalNumber> SparseCtmcCslHelper::computeReachabilityTimes(
847 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
848 storm::storage::BitVector const& targetStates, bool qualitative);
849template std::vector<storm::ExtendedRationalFunction> SparseCtmcCslHelper::computeReachabilityTimes(
851 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
852 storm::storage::BitVector const& targetStates, bool qualitative);
853
854template std::vector<storm::ExtendedRationalNumber> SparseCtmcCslHelper::computeReachabilityRewards(
856 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
857 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative);
858template std::vector<storm::ExtendedRationalFunction> SparseCtmcCslHelper::computeReachabilityRewards(
860 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
861 storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative);
862
863template std::vector<storm::ExtendedRationalNumber> SparseCtmcCslHelper::computeTotalRewards(
865 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
866 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, bool qualitative);
867template std::vector<storm::ExtendedRationalFunction> SparseCtmcCslHelper::computeTotalRewards(
869 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
871
873 std::vector<double> const& exitRates);
875 storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRates);
877 storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRates);
878
879} // namespace helper
880} // namespace modelchecker
881} // namespace storm
SolverEnvironment & solver()
TimeBoundedSolverEnvironment & timeBounded()
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.
Definition BitVector.h:16
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)
Definition logging.h:34
#define STORM_LOG_DEBUG(message)
Definition logging.h:28
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:54
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
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:316
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:400
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.
Definition vector.h:79
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:185
T maximumElementAbs(std::vector< T > const &vector)
Definition vector.h:849
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:375
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:448
bool isZero(ValueType const &a)
Definition constants.cpp:44
ValueType abs(ValueType const &number)
ValueType zero()
Definition constants.cpp:26
ValueType one()
Definition constants.cpp:21
TargetType convertNumber(SourceType const &number)
static const bool SupportsExponential
std::vector< ValueType > weights
Definition numerical.h:17