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