Storm 1.11.1.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
31 ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision());
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 (auto 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, ValueType 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 == storm::utility::infinity<ValueType>()) {
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)
78 ValueType epsilon = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision()) / 8.0;
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 (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>());
101 storm::utility::vector::setVectorValues<ValueType>(result, psiStates, storm::utility::one<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>());
108 storm::utility::vector::setVectorValues<ValueType>(result, psiStates, storm::utility::one<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 (auto 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 == storm::utility::infinity<ValueType>()) {
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 (auto 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.
162 storm::utility::vector::setVectorValues(result, ~relevantStates, storm::utility::zero<ValueType>());
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 (auto 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,
197 epsilon / storm::utility::convertNumber<ValueType>(2.0));
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 (auto 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,
214 epsilon / storm::utility::convertNumber<ValueType>(2.0));
215
216 // Fill in the correct values.
217 result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
218 storm::utility::vector::setVectorValues(result, ~relevantStates, 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 (auto 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}
264
265template<typename ValueType>
268 std::vector<ValueType> const& exitRateVector,
269 storm::storage::BitVector const& initialStates,
270 storm::storage::BitVector const& phiStates,
271 storm::storage::BitVector const& psiStates) {
272 return SparseDtmcPrctlHelper<ValueType>::computeAllUntilProbabilities(env, std::move(goal), computeProbabilityMatrix(rateMatrix, exitRateVector),
273 initialStates, phiStates, psiStates);
274}
275
276template<typename ValueType>
278 std::vector<ValueType> const& exitRateVector,
279 storm::storage::BitVector const& nextStates) {
280 return SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, computeProbabilityMatrix(rateMatrix, exitRateVector), nextStates);
281}
282
283template<typename ValueType, typename RewardModelType>
287 std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
288 ValueType timeBound) {
289 // Only compute the result if the model has a state-based reward model.
290 STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
291 "Computing instantaneous rewards for a reward model that does not define any state-rewards. The result is trivially 0.");
292
293 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
294
295 // Initialize result to state rewards of the this->getModel().
296 std::vector<ValueType> result(rewardModel.getStateRewardVector());
297
298 // If the time-bound is zero, just return the current reward vector
299 if (storm::utility::isZero(timeBound)) {
300 return result;
301 }
302 ValueType maxValue = storm::utility::vector::maximumElementAbs(result);
303
304 // If all entries are zero, we return the zero-vector
305 if (storm::utility::isZero(maxValue)) {
306 return result;
307 }
308
309 ValueType uniformizationRate = 0;
310 for (auto const& rate : exitRateVector) {
311 uniformizationRate = std::max(uniformizationRate, rate);
312 }
313 uniformizationRate *= 1.02;
314 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
315
317 computeUniformizedMatrix(rateMatrix, storm::storage::BitVector(numberOfStates, true), uniformizationRate, exitRateVector);
318
319 // Set the possible error allowed for truncation (epsilon for fox-glynn)
320 ValueType epsilon = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision());
322 // Be more precise, if the maximum value is very small (precision can/has to be refined later)
323 epsilon *= std::min(storm::utility::one<ValueType>(), maxValue);
324 } else {
325 // Be more precise, if the maximal possible value is very large
326 epsilon /= std::max(storm::utility::one<ValueType>(), maxValue);
327 }
328
329 storm::storage::BitVector relevantValues;
330 if (goal.hasRelevantValues()) {
331 relevantValues = std::move(goal.relevantValues());
332 } else {
333 relevantValues = storm::storage::BitVector(result.size(), true);
334 }
335
336 // Loop until the desired precision is reached.
337 do {
338 result = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, result, epsilon);
339 } while (checkAndUpdateTransientProbabilityEpsilon(env, epsilon, result, relevantValues));
340
341 return result;
342}
343
344template<typename ValueType, typename RewardModelType>
348 std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
349 ValueType timeBound) {
350 STORM_LOG_THROW(!env.solver().isForceExact(), storm::exceptions::InvalidOperationException,
351 "Exact computations not possible for cumulative expected rewards.");
352
353 // Only compute the result if the model has a state-based reward model.
354 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
355
356 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
357
358 // If the time bound is zero, the result is the constant zero vector.
359 if (timeBound == 0) {
360 return std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
361 }
362
363 // Otherwise, we need to perform some computations.
364
365 // Start with the uniformization.
366 ValueType uniformizationRate = 0;
367 for (auto const& rate : exitRateVector) {
368 uniformizationRate = std::max(uniformizationRate, rate);
369 }
370 uniformizationRate *= 1.02;
371 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
372
374 computeUniformizedMatrix(rateMatrix, storm::storage::BitVector(numberOfStates, true), uniformizationRate, exitRateVector);
375
376 // Compute the total state reward vector.
377 std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(rateMatrix, exitRateVector);
378 ValueType maxReward = storm::utility::vector::maximumElementAbs(totalRewardVector);
379
380 // If all rewards are zero, the result is the constant zero vector.
381 if (storm::utility::isZero(maxReward)) {
382 return std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
383 }
384
385 // Set the possible (absolute) error allowed for truncation (epsilon for fox-glynn)
386 ValueType epsilon = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision());
388 // Be more precise, if the value is very small (precision can/has to be refined later)
389 epsilon *= std::min(storm::utility::one<ValueType>(), maxReward);
390 } else {
391 // Be more precise, if the maximal possible value is very large
392 epsilon /= std::max(storm::utility::one<ValueType>(), maxReward * timeBound);
393 }
394
395 storm::storage::BitVector relevantValues;
396 if (goal.hasRelevantValues()) {
397 relevantValues = std::move(goal.relevantValues());
398 } else {
399 relevantValues = storm::storage::BitVector(totalRewardVector.size(), true);
400 }
401
402 // Loop until the desired precision is reached.
403 std::vector<ValueType> result;
404 do {
405 result = computeTransientProbabilities<ValueType, true>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, totalRewardVector, epsilon);
406 } while (checkAndUpdateTransientProbabilityEpsilon(env, epsilon, result, relevantValues));
407
408 return result;
409}
410
411template<typename ValueType>
414 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
415 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}
435
436template<typename ValueType, typename RewardModelType>
439 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
440 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
470 env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative);
471}
472
473template<typename ValueType, typename RewardModelType>
476 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
477 std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel,
478 bool qualitative) {
479 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
480
481 storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector);
482
483 std::vector<ValueType> totalRewardVector;
484 if (rewardModel.hasStateRewards()) {
485 totalRewardVector = rewardModel.getStateRewardVector();
486 typename std::vector<ValueType>::const_iterator it2 = exitRateVector.begin();
487 for (typename std::vector<ValueType>::iterator it1 = totalRewardVector.begin(), ite1 = totalRewardVector.end(); it1 != ite1; ++it1, ++it2) {
488 *it1 /= *it2;
489 }
490 if (rewardModel.hasStateActionRewards()) {
491 storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
492 }
493 if (rewardModel.hasTransitionRewards()) {
494 storm::utility::vector::addVectors(totalRewardVector, probabilityMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix()),
495 totalRewardVector);
496 }
497 } else if (rewardModel.hasTransitionRewards()) {
498 totalRewardVector = probabilityMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix());
499 if (rewardModel.hasStateActionRewards()) {
500 storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
501 }
502 } else {
503 totalRewardVector = rewardModel.getStateActionRewardVector();
504 }
505
506 RewardModelType dtmcRewardModel(std::move(totalRewardVector));
507 return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeTotalRewards(env, std::move(goal), probabilityMatrix, backwardTransitions,
508 dtmcRewardModel, qualitative);
509}
510
511template<typename ValueType>
514 storm::storage::BitVector const& initialStates,
515 storm::storage::BitVector const& phiStates,
516 storm::storage::BitVector const& psiStates,
517 std::vector<ValueType> const& exitRates, ValueType timeBound) {
518 // Compute transient probabilities going from initial state
519 // Instead of y=Px we now compute y=xP <=> y^T=P^Tx^T via transposition
520 uint_fast64_t numberOfStates = rateMatrix.getRowCount();
521
522 // Create the result vector.
523 std::vector<ValueType> result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>());
524
525 storm::storage::SparseMatrix<ValueType> transposedMatrix(rateMatrix);
526 transposedMatrix.makeRowsAbsorbing(psiStates);
527 std::vector<ValueType> newRates = exitRates;
528 for (auto state : psiStates) {
529 newRates[state] = storm::utility::one<ValueType>();
530 }
531
532 // Identify all maybe states which have a probability greater than 0 to be reached from the initial state.
533 // storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(transposedMatrix, phiStates, initialStates);
534 // STORM_LOG_INFO("Found " << statesWithProbabilityGreater0.getNumberOfSetBits() << " states with probability greater 0.");
535
536 // storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & ~initialStates;//phiStates | psiStates;
537 storm::storage::BitVector relevantStates(numberOfStates, true);
538 STORM_LOG_DEBUG(relevantStates.getNumberOfSetBits() << " relevant states.");
539
540 if (!relevantStates.empty()) {
541 // Find the maximal rate of all relevant states to take it as the uniformization rate.
542 ValueType uniformizationRate = 0;
543 for (auto state : relevantStates) {
544 uniformizationRate = std::max(uniformizationRate, newRates[state]);
545 }
546 uniformizationRate *= 1.02;
547 STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive.");
548
549 transposedMatrix = transposedMatrix.transpose();
550
551 // Compute the uniformized matrix.
552 storm::storage::SparseMatrix<ValueType> uniformizedMatrix = computeUniformizedMatrix(transposedMatrix, relevantStates, uniformizationRate, newRates);
553
554 // Compute the vector that is to be added as a compensation for removing the absorbing states.
555 /*std::vector<ValueType> b = transposedMatrix.getConstrainedRowSumVector(relevantStates, initialStates);
556 for (auto& element : b) {
557 element /= uniformizationRate;
558 std::cout << element << '\n';
559 }*/
560
561 ValueType epsilon = storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision()) / 8.0;
563 "Computation of transient probabilities with relative precision not supported. Using absolute precision instead.");
564 std::vector<ValueType> values(relevantStates.getNumberOfSetBits(), storm::utility::zero<ValueType>());
565 // Set initial states
566 size_t i = 0;
567 ValueType initDist = storm::utility::one<ValueType>() / initialStates.getNumberOfSetBits();
568 for (auto state : relevantStates) {
569 if (initialStates.get(state)) {
570 values[i] = initDist;
571 }
572 ++i;
573 }
574 // Finally compute the transient probabilities.
575 std::vector<ValueType> subresult =
576 computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, values, epsilon);
577
578 storm::utility::vector::setVectorValues(result, relevantStates, subresult);
579 }
580
581 return result;
582}
583
584template<typename ValueType>
587 storm::storage::BitVector const& maybeStates,
588 ValueType uniformizationRate, std::vector<ValueType> const& exitRates) {
589 STORM_LOG_DEBUG("Computing uniformized matrix using uniformization rate " << uniformizationRate << ".");
590 STORM_LOG_DEBUG("Keeping " << maybeStates.getNumberOfSetBits() << " rows.");
591
592 // Create the submatrix that only contains the states with a positive probability (including the
593 // psi states) and reserve space for elements on the diagonal.
594 storm::storage::SparseMatrix<ValueType> uniformizedMatrix = rateMatrix.getSubmatrix(false, maybeStates, maybeStates, true);
595
596 // Now we need to perform the actual uniformization. That is, all entries need to be divided by
597 // the uniformization rate, and the diagonal needs to be set to the negative exit rate of the
598 // state plus the self-loop rate and then increased by one.
599 uint_fast64_t currentRow = 0;
600 for (auto state : maybeStates) {
601 for (auto& element : uniformizedMatrix.getRow(currentRow)) {
602 if (element.getColumn() == currentRow) {
603 element.setValue((element.getValue() - exitRates[state]) / uniformizationRate + storm::utility::one<ValueType>());
604 } else {
605 element.setValue(element.getValue() / uniformizationRate);
606 }
607 }
608 ++currentRow;
609 }
610
611 return uniformizedMatrix;
612}
613
614template<typename ValueType, bool useMixedPoissonProbabilities>
617 storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix,
618 std::vector<ValueType> const* addVector, ValueType timeBound,
619 ValueType uniformizationRate, std::vector<ValueType> values, ValueType epsilon) {
620 STORM_LOG_WARN_COND(epsilon > storm::utility::convertNumber<ValueType>(1e-20),
621 "Very low truncation error " << epsilon << " requested. Numerical inaccuracies are possible.");
622 ValueType lambda = timeBound * uniformizationRate;
623
624 // If no time can pass, the current values are the result.
625 if (storm::utility::isZero(lambda)) {
626 return values;
627 }
628
629 // Use Fox-Glynn to get the truncation points and the weights.
631 STORM_LOG_DEBUG("Fox-Glynn cutoff points: left=" << foxGlynnResult.left << ", right=" << foxGlynnResult.right);
632 // foxGlynnResult.weights do not sum up to one. This is to enhance numerical stability.
633
634 // If the cumulative reward is to be computed, we need to adjust the weights.
635 if (useMixedPoissonProbabilities) {
636 // The following computes a vector v such that
637 // v[i] = foxGlynnResult.totalWeight - sum_{j=0}^{i} foxGlynnResult.weights[j]
638 // = sum_{j=i+1}^{n-1} foxGlynnResult.weights[j] for i=0,...,n-1
639 // and then sets foxGlynnResult.weights = v / uniformizationRate.
640 // 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
641 uint64_t l{0ull}, r{foxGlynnResult.weights.size() - 1};
642 ValueType sumLeft{storm::utility::zero<ValueType>()}, sumRight{storm::utility::zero<ValueType>()};
643 while (l <= r) {
644 if (foxGlynnResult.weights[l] < foxGlynnResult.weights[r]) {
645 sumLeft += foxGlynnResult.weights[l];
646 foxGlynnResult.weights[l] = (foxGlynnResult.totalWeight - sumLeft) / uniformizationRate;
647 ++l;
648 } else {
649 auto const tmp = foxGlynnResult.weights[r];
650 foxGlynnResult.weights[r] = sumRight / uniformizationRate;
651 sumRight += tmp;
652 if (r == 0) {
653 // Avoid underflow for unsigned int
654 break;
655 }
656 --r;
657 }
658 }
659 auto const relDiff = storm::utility::abs<ValueType>(foxGlynnResult.totalWeight - (sumLeft + sumRight)) / foxGlynnResult.totalWeight;
660 STORM_LOG_WARN_COND(relDiff < storm::utility::convertNumber<ValueType>(1e-8),
661 "Numerical instability when adjusting the FoxGlynn weights. Relative Difference: " << relDiff << ".");
662 }
663
664 STORM_LOG_DEBUG("Starting iterations with " << uniformizedMatrix.getRowCount() << " x " << uniformizedMatrix.getColumnCount() << " matrix.");
665
666 // Initialize result.
667 std::vector<ValueType> result;
668 uint_fast64_t startingIteration = foxGlynnResult.left;
669 if (startingIteration == 0) {
670 result = values;
671 storm::utility::vector::scaleVectorInPlace(result, foxGlynnResult.weights.front());
672 ++startingIteration;
673 } else {
674 if (useMixedPoissonProbabilities) {
675 result = std::vector<ValueType>(values.size());
676 std::function<ValueType(ValueType const&)> scaleWithUniformizationRate = [&uniformizationRate](ValueType const& a) -> ValueType {
677 return a / uniformizationRate;
678 };
679 storm::utility::vector::applyPointwise(values, result, scaleWithUniformizationRate);
680 } else {
681 result = std::vector<ValueType>(values.size());
682 }
683 }
684
685 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, uniformizedMatrix);
686 if (!useMixedPoissonProbabilities && foxGlynnResult.left > 1) {
687 // Perform the matrix-vector multiplications (without adding).
688 multiplier->repeatedMultiply(env, values, addVector, foxGlynnResult.left - 1);
689 } else if (useMixedPoissonProbabilities) {
690 std::function<ValueType(ValueType const&, ValueType const&)> addAndScale = [&uniformizationRate](ValueType const& a, ValueType const& b) {
691 return a + b / uniformizationRate;
692 };
693
694 // For the iterations below the left truncation point, we need to add and scale the result with the uniformization rate.
695 for (uint_fast64_t index = 1; index < startingIteration; ++index) {
696 multiplier->multiply(env, values, nullptr, values);
697 storm::utility::vector::applyPointwise(result, values, result, addAndScale);
698 }
699 // To make sure that the values obtained before the left truncation point have the same 'impact' on the total result as the values obtained
700 // between the left and right truncation point, we scale them here with the total sum of the weights.
701 // Note that we divide with this value afterwards. This is to improve numerical stability.
702 if (foxGlynnResult.left > 0) {
703 storm::utility::vector::scaleVectorInPlace<ValueType, ValueType>(result, foxGlynnResult.totalWeight);
704 }
705 }
706
707 // For the indices that fall in between the truncation points, we need to perform the matrix-vector
708 // multiplication, scale and add the result.
709 ValueType weight = 0;
710 std::function<ValueType(ValueType const&, ValueType const&)> addAndScale = [&weight](ValueType const& a, ValueType const& b) { return a + weight * b; };
711 for (uint_fast64_t index = startingIteration; index <= foxGlynnResult.right; ++index) {
712 multiplier->multiply(env, values, addVector, values);
713
714 weight = foxGlynnResult.weights[index - foxGlynnResult.left];
715 storm::utility::vector::applyPointwise(result, values, result, addAndScale);
716 }
717
718 // Finally, divide the result by the total weight
719 storm::utility::vector::scaleVectorInPlace<ValueType, ValueType>(result, storm::utility::one<ValueType>() / foxGlynnResult.totalWeight);
720 return result;
721}
722
723template<typename ValueType>
725 std::vector<ValueType> const& exitRates) {
726 // Turn the rates into probabilities by scaling each row with the exit rate of the state.
728 for (uint_fast64_t row = 0; row < result.getRowCount(); ++row) {
729 for (auto& entry : result.getRow(row)) {
730 entry.setValue(entry.getValue() / exitRates[row]);
731 }
732 }
733 return result;
734}
735
736template<typename ValueType>
738 std::vector<ValueType> const& exitRates) {
739 storm::storage::SparseMatrix<ValueType> generatorMatrix(rateMatrix, true);
740
741 // Place the negative exit rate on the diagonal.
742 for (uint_fast64_t row = 0; row < generatorMatrix.getRowCount(); ++row) {
743 for (auto& entry : generatorMatrix.getRow(row)) {
744 if (entry.getColumn() == row) {
745 entry.setValue(-exitRates[row] + entry.getValue());
746 }
747 }
748 }
749
750 return generatorMatrix;
751}
752
755 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
756 std::vector<double> const& exitRates, bool qualitative, double lowerBound, double upperBound);
757
759 storm::storage::SparseMatrix<double> const& rateMatrix,
760 storm::storage::SparseMatrix<double> const& backwardTransitions,
761 std::vector<double> const& exitRateVector,
762 storm::storage::BitVector const& phiStates,
763 storm::storage::BitVector const& psiStates, bool qualitative);
764
766 storm::storage::SparseMatrix<double> const& rateMatrix,
767 std::vector<double> const& exitRateVector,
768 storm::storage::BitVector const& initialStates,
769 storm::storage::BitVector const& phiStates,
770 storm::storage::BitVector const& psiStates);
771
772template std::vector<double> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& rateMatrix,
773 std::vector<double> const& exitRateVector,
774 storm::storage::BitVector const& nextStates);
775
777 storm::storage::SparseMatrix<double> const& rateMatrix,
778 std::vector<double> const& exitRateVector,
780 double timeBound);
781
783 storm::storage::SparseMatrix<double> const& rateMatrix,
784 storm::storage::SparseMatrix<double> const& backwardTransitions,
785 std::vector<double> const& exitRateVector,
786 storm::storage::BitVector const& targetStates, bool qualitative);
787
789 storm::storage::SparseMatrix<double> const& rateMatrix,
790 storm::storage::SparseMatrix<double> const& backwardTransitions,
791 std::vector<double> const& exitRateVector,
793 storm::storage::BitVector const& targetStates, bool qualitative);
794
796 storm::storage::SparseMatrix<double> const& rateMatrix,
797 storm::storage::SparseMatrix<double> const& backwardTransitions,
798 std::vector<double> const& exitRateVector,
799 storm::models::sparse::StandardRewardModel<double> const& rewardModel, bool qualitative);
800
802 storm::storage::SparseMatrix<double> const& rateMatrix,
803 std::vector<double> const& exitRateVector,
805 double timeBound);
806
808 Environment const& env, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::BitVector const& initialStates,
809 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<double> const& exitRates, double timeBound);
810
812 storm::storage::BitVector const& maybeStates,
813 double uniformizationRate, std::vector<double> const& exitRates);
814
815template std::vector<double> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env,
816 storm::storage::SparseMatrix<double> const& uniformizedMatrix,
817 std::vector<double> const* addVector, double timeBound,
818 double uniformizationRate, std::vector<double> values, double epsilon);
819
820template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeUntilProbabilities(
822 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
823 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative);
824template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeUntilProbabilities(
826 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
827 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative);
828
829template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeAllUntilProbabilities(
831 std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& phiStates,
832 storm::storage::BitVector const& psiStates);
833template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeAllUntilProbabilities(
835 std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& phiStates,
836 storm::storage::BitVector const& psiStates);
837
838template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env,
840 std::vector<storm::RationalNumber> const& exitRateVector,
841 storm::storage::BitVector const& nextStates);
842template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeNextProbabilities(
843 Environment const& env, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector,
844 storm::storage::BitVector const& nextStates);
845
846template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityTimes(
848 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
849 storm::storage::BitVector const& targetStates, bool qualitative);
850template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityTimes(
852 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
853 storm::storage::BitVector const& targetStates, bool qualitative);
854
855template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityRewards(
857 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
858 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative);
859template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityRewards(
861 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
862 storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative);
863
864template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeTotalRewards(
866 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector,
867 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, bool qualitative);
868template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeTotalRewards(
870 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector,
872
874 std::vector<double> const& exitRates);
876 storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRates);
878 storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRates);
879
880} // namespace helper
881} // namespace modelchecker
882} // namespace storm
SolverEnvironment & solver()
TimeBoundedSolverEnvironment & timeBounded()
storm::RationalNumber const & getPrecision() const
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 > 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 ::SupportsExponential 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, ValueType upperBound)
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 ::SupportsExponential 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 > 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 ::SupportsExponential 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 ::SupportsExponential 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 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 ::SupportsExponential 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 ::SupportsExponential 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 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 > 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 &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: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< 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...
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:24
#define STORM_LOG_DEBUG(message)
Definition logging.h:18
#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:315
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:399
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:78
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:184
T maximumElementAbs(std::vector< T > const &vector)
Definition vector.h:845
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:374
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:447
bool isZero(ValueType const &a)
Definition constants.cpp:39
std::vector< ValueType > weights
Definition numerical.h:15