29template<
typename ValueType>
32 std::vector<ValueType>& rowValues1,
storm::OptionalRef<std::vector<ValueType>> rowValues2 = {}) {
40 matrix, ecs, allRowGroups, addRowAtRepresentativeState ? allRowGroups : ~allRowGroups, representativeRowEntry.has_value());
43 matrix = std::move(ecElimResult.matrix);
44 if (addRowAtRepresentativeState && representativeRowEntry) {
45 auto const columnIndex = ecElimResult.oldToNewStateMapping[*representativeRowEntry];
46 for (
auto representativeRowIndex : ecElimResult.sinkRows) {
47 auto row = matrix.
getRow(representativeRowIndex);
48 STORM_LOG_ASSERT(row.getNumberOfEntries() == 1,
"unexpected number of entries in representative row.");
49 auto& entry = *row.begin();
50 entry.setColumn(columnIndex);
55 auto updateRowValue = [&ecElimResult](std::vector<ValueType>& rowValues) {
56 std::vector<ValueType> newRowValues;
57 newRowValues.reserve(ecElimResult.newToOldRowMapping.size());
58 for (
auto oldRowIndex : ecElimResult.newToOldRowMapping) {
59 newRowValues.push_back(rowValues[oldRowIndex]);
61 rowValues = std::move(newRowValues);
63 std::all_of(ecElimResult.sinkRows.begin(), ecElimResult.sinkRows.end(), [&rowValues](
auto i) { return storm::utility::isZero(rowValues[i]); }),
64 "Sink rows are expected to have zero value");
66 updateRowValue(rowValues1);
68 updateRowValue(*rowValues2);
72 initialState = ecElimResult.oldToNewStateMapping[initialState];
76 uint64_t newRowIndex = 0;
77 for (
auto oldRowIndex : ecElimResult.newToOldRowMapping) {
78 if ((addRowAtRepresentativeState && !representativeRowEntry.has_value() && ecElimResult.sinkRows.get(newRowIndex)) || !rowsWithSum1.
get(oldRowIndex)) {
79 newRowsWithSum1.set(newRowIndex,
false);
83 rowsWithSum1 = std::move(newRowsWithSum1);
86template<
typename ValueType,
typename SolutionType = ValueType>
91 std::vector<SolutionType> x(matrix.
getRowGroupCount(), storm::utility::zero<ValueType>());
95 solver->setOptimizationDirection(dir);
96 solver->setRequirementsChecked();
97 solver->setHasUniqueSolution(
true);
98 solver->setHasNoEndComponents(
true);
99 solver->setLowerBound(storm::utility::zero<ValueType>());
100 solver->setUpperBound(storm::utility::one<ValueType>());
103 solver->solveEquations(env, x, rowValues);
104 return x[initialState];
111template<
typename ValueType>
115 if (initialStates.
empty()) {
119 auto const subTargets = targetStates % reachableStates;
121 if (subTargets.empty()) {
124 auto const subInits = initialStates % reachableStates;
125 auto const submatrix = transitionMatrix.
getSubmatrix(
true, reachableStates, reachableStates);
128 subTargets,
false,
false);
129 auto origInitIt = initialStates.
begin();
130 for (
auto subInit : subInits) {
131 auto const& val = subResult.values[subInit];
133 nonZeroResults.emplace(*origInitIt, val);
139template<
typename ValueType>
171template<
typename ValueType>
177 auto extendedConditionStates =
180 std::map<uint64_t, ValueType> nonZeroTargetStateValues;
181 auto const extendedTargetStates =
184 auto const targetAndNotCondFailStates = extendedTargetStates & ~(extendedConditionStates | universalObservationFailureStates);
188 auto terminalStatesThatReachCondition = extendedConditionStates;
189 for (
auto state : targetAndNotCondFailStates) {
190 if (nonZeroTargetStateValues.contains(state)) {
191 terminalStatesThatReachCondition.set(state,
true);
196 auto terminalStates = extendedConditionStates | extendedTargetStates | universalObservationFailureStates;
205 auto nonTerminalStates = ~terminalStates;
208 backwardTransitions, nonTerminalStates, terminalStatesThatReachCondition);
214 .terminalStates = std::move(terminalStates),
215 .conditionStates = std::move(extendedConditionStates),
216 .universalObservationFailureStates = std::move(universalObservationFailureStates),
217 .existentialObservationFailureStates = std::move(existentialObservationFailureStates),
218 .nonZeroTargetStateValues = std::move(nonZeroTargetStateValues)};
225template<
typename ValueType,
typename SolutionType = ValueType>
230 auto const numMaybeStates = maybeStates.getNumberOfSetBits();
235 std::vector<ValueType> rowValues;
237 rowValues.reserve(numMaybeChoices);
238 uint64_t currentRow = 0;
239 for (
auto state : maybeStates) {
245 ValueType targetProbability = storm::utility::zero<ValueType>();
246 ValueType restartProbability = storm::utility::zero<ValueType>();
247 bool rowSumIsLess1 =
false;
248 for (
auto const& entry : transitionMatrix.
getRow(origRowIndex)) {
250 ValueType
const targetValue = normalForm.
getTargetValue(entry.getColumn());
251 targetProbability += targetValue * entry.getValue();
253 rowSumIsLess1 =
true;
256 rowSumIsLess1 =
true;
258 restartProbability += entry.getValue() * normalForm.
failProbability(entry.getColumn());
263 rowsWithSum1.
set(currentRow,
false);
265 rowValues.push_back(targetProbability);
267 for (
auto const& entry : transitionMatrix.
getRow(origRowIndex)) {
270 if (addRestartTransition && entry.getColumn() > initialState) {
271 matrixBuilder.
addNextValue(currentRow, stateToMatrixIndexMap[initialState], restartProbability);
272 addRestartTransition =
false;
274 if (maybeStates.get(entry.getColumn())) {
275 matrixBuilder.
addNextValue(currentRow, stateToMatrixIndexMap[entry.getColumn()], entry.getValue());
279 if (addRestartTransition) {
280 matrixBuilder.
addNextValue(currentRow, stateToMatrixIndexMap[initialState], restartProbability);
286 auto matrix = matrixBuilder.
build();
287 auto initStateInMatrix = stateToMatrixIndexMap[initialState];
293 selectedStatesInMatrix.
set(initStateInMatrix,
false);
294 eliminateEndComponents(selectedStatesInMatrix,
true, initStateInMatrix, matrix, initStateInMatrix, rowsWithSum1, rowValues);
297 selectedStatesInMatrix.
set(initStateInMatrix,
true);
298 eliminateEndComponents(selectedStatesInMatrix,
false, std::nullopt, matrix, initStateInMatrix, rowsWithSum1, rowValues);
311template<
typename ValueType,
typename SolutionType = ValueType>
327 subMatrixRowGroups.set(initialState,
false);
328 std::vector<uint64_t> dfsStack = {initialState};
329 while (!dfsStack.empty()) {
330 auto const state = dfsStack.back();
333 auto const row = transitionMatrix.
getRow(rowIndex);
334 if (std::all_of(row.begin(), row.end(),
335 [&normalForm](
auto const& entry) { return normalForm.existentialObservationFailureStates.get(entry.getColumn()); })) {
336 for (
auto const& entry : row) {
337 auto const& successor = entry.getColumn();
338 if (subMatrixRowGroups.get(successor)) {
339 subMatrixRowGroups.set(successor,
false);
340 dfsStack.push_back(successor);
344 initialComponentExitRows.
set(rowIndex,
true);
349 subMatrixRowGroups.set(initialState,
true);
350 auto const numSubmatrixRowGroups = subMatrixRowGroups.getNumberOfSetBits();
353 auto stateToMatrixIndexMap = subMatrixRowGroups.getNumberOfSetBitsBeforeIndices();
354 initialStateInSubmatrix = stateToMatrixIndexMap[initialState];
355 auto const eliminatedInitialComponentStates = normalForm.
maybeStates & ~subMatrixRowGroups;
356 for (
auto state : eliminatedInitialComponentStates) {
357 stateToMatrixIndexMap[state] = initialStateInSubmatrix;
363 targetRowValues.reserve(numSubmatrixRows);
364 conditionRowValues.reserve(numSubmatrixRows);
365 uint64_t currentRow = 0;
366 for (
auto state : subMatrixRowGroups) {
370 auto processRow = [&](uint64_t origRowIndex) {
372 ValueType
const eliminatedInitialComponentProbability = transitionMatrix.
getConstrainedRowSum(origRowIndex, eliminatedInitialComponentStates);
374 ValueType targetProbability = storm::utility::zero<ValueType>();
375 ValueType conditionProbability = storm::utility::zero<ValueType>();
376 bool rowSumIsLess1 =
false;
377 bool initialStateEntryInserted =
false;
378 for (
auto const& entry : transitionMatrix.
getRow(origRowIndex)) {
381 rowSumIsLess1 =
true;
382 ValueType
const scaledTargetValue = normalForm.
getTargetValue(entry.getColumn()) * entry.getValue();
383 targetProbability += scaledTargetValue;
385 conditionProbability += entry.getValue();
387 conditionProbability += scaledTargetValue;
389 }
else if (!eliminatedInitialComponentStates.get(entry.getColumn())) {
390 auto const columnIndex = stateToMatrixIndexMap[entry.getColumn()];
391 if (!initialStateEntryInserted && columnIndex >= initialStateInSubmatrix) {
392 if (columnIndex == initialStateInSubmatrix) {
393 matrixBuilder.
addNextValue(currentRow, initialStateInSubmatrix, eliminatedInitialComponentProbability + entry.getValue());
395 matrixBuilder.
addNextValue(currentRow, initialStateInSubmatrix, eliminatedInitialComponentProbability);
396 matrixBuilder.
addNextValue(currentRow, columnIndex, entry.getValue());
398 initialStateEntryInserted =
true;
400 matrixBuilder.
addNextValue(currentRow, columnIndex, entry.getValue());
405 rowsWithSum1.
set(currentRow,
false);
407 targetRowValues.push_back(targetProbability);
408 conditionRowValues.push_back(conditionProbability);
412 if (state == initialState) {
413 for (
auto origRowIndex : initialComponentExitRows) {
414 processRow(origRowIndex);
418 processRow(origRowIndex);
422 submatrix = matrixBuilder.
build();
427 allExceptInit.
set(initialStateInSubmatrix,
false);
428 eliminateEndComponents<ValueType>(allExceptInit,
true, std::nullopt, submatrix, initialStateInSubmatrix, rowsWithSum1, targetRowValues,
430 STORM_LOG_INFO(
"Processed model has " << submatrix.getRowGroupCount() <<
" states and " << submatrix.getRowGroupCount() <<
" choices and "
431 << submatrix.getEntryCount() <<
" transitions.");
435 ValueType
const& conditionWeight)
const {
436 auto rowValues = createScaledVector(targetWeight, targetRowValues, conditionWeight, conditionRowValues);
439 std::vector<SolutionType> x(submatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
443 solver->setOptimizationDirection(dir);
444 solver->setRequirementsChecked();
445 solver->setHasUniqueSolution(
true);
446 solver->setHasNoEndComponents(
true);
447 solver->setLowerBound(-storm::utility::one<ValueType>());
448 solver->setUpperBound(storm::utility::one<ValueType>());
450 solver->solveEquations(env, x, rowValues);
451 return x[initialStateInSubmatrix];
455 return initialStateInSubmatrix;
459 std::vector<SolutionType>& conditionResults)
const {
460 if (scheduler.empty()) {
461 scheduler.resize(submatrix.getRowGroupCount(), 0);
463 if (targetResults.empty()) {
464 targetResults.resize(submatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
466 if (conditionResults.empty()) {
467 conditionResults.resize(submatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
472 auto scheduledMatrix = submatrix.selectRowsFromRowGroups(scheduler, convertToEquationSystem);
473 if (convertToEquationSystem) {
474 scheduledMatrix.convertToEquationSystem();
476 auto solver = factory.
create(env, std::move(scheduledMatrix));
477 solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
478 solver->setCachingEnabled(
true);
480 std::vector<ValueType> subB(submatrix.getRowGroupCount());
481 storm::utility::vector::selectVectorValues<ValueType>(subB, scheduler, submatrix.getRowGroupIndices(), targetRowValues);
482 solver->solveEquations(env, targetResults, subB);
484 storm::utility::vector::selectVectorValues<ValueType>(subB, scheduler, submatrix.getRowGroupIndices(), conditionRowValues);
485 solver->solveEquations(env, conditionResults, subB);
488 template<OptimizationDirection Dir>
489 bool improveScheduler(std::vector<uint64_t>& scheduler, ValueType
const& lambda, std::vector<SolutionType>
const& targetResults,
490 std::vector<SolutionType>
const& conditionResults) {
491 bool improved =
false;
492 for (uint64_t rowGroupIndex = 0; rowGroupIndex < scheduler.size(); ++rowGroupIndex) {
494 uint64_t optimalRowIndex{0};
495 ValueType scheduledValue;
496 for (
auto rowIndex : submatrix.getRowGroupIndices(rowGroupIndex)) {
497 ValueType rowValue = targetRowValues[rowIndex] - lambda * conditionRowValues[rowIndex];
498 for (
auto const& entry : submatrix.getRow(rowIndex)) {
499 rowValue += entry.getValue() * (targetResults[entry.getColumn()] - lambda * conditionResults[entry.getColumn()]);
501 if (rowIndex == scheduler[rowGroupIndex] + submatrix.getRowGroupIndices()[rowGroupIndex]) {
502 scheduledValue = rowValue;
504 if (groupValue &= rowValue) {
505 optimalRowIndex = rowIndex;
508 if (scheduledValue != *groupValue) {
509 scheduler[rowGroupIndex] = optimalRowIndex - submatrix.getRowGroupIndices()[rowGroupIndex];
517 std::vector<ValueType> createScaledVector(ValueType
const& w1, std::vector<ValueType>
const& v1, ValueType
const& w2,
518 std::vector<ValueType>
const& v2)
const {
520 std::vector<ValueType> result;
521 result.reserve(v1.size());
522 for (
size_t i = 0; i < v1.size(); ++i) {
523 result.push_back(w1 * v1[i] + w2 * v2[i]);
530 std::vector<ValueType> targetRowValues;
531 std::vector<ValueType> conditionRowValues;
532 uint64_t initialStateInSubmatrix;
536template<
typename ValueType,
typename SolutionType = ValueType>
542 "Bisection method does not adequately handle propagation of errors. Result is not necessarily sound.");
543 SolutionType
const precision = [&env, boundOption]() {
546 "Selected bisection method with exact precision in a setting that might not terminate.");
547 return storm::utility::zero<SolutionType>();
555 SolutionType pMin{storm::utility::zero<SolutionType>()};
556 SolutionType pMax{storm::utility::one<SolutionType>()};
559 pMin = wrh.
computeWeightedDiff(env, storm::OptimizationDirection::Minimize, storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
560 pMax = wrh.
computeWeightedDiff(env, storm::OptimizationDirection::Maximize, storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
561 STORM_LOG_TRACE(
"Conditioning event bounds:\n\t Lower bound: " << storm::utility::convertNumber<double>(pMin)
562 <<
",\n\t Upper bound: " << storm::utility::convertNumber<double>(pMax));
566 SolutionType middle = (*lowerBound + *upperBound) / 2;
567 for (uint64_t iterationCount = 1;
true; ++iterationCount) {
569 SolutionType
const middleValue = wrh.
computeWeightedDiff(env, dir, storm::utility::one<ValueType>(), -middle);
572 if (middleValue >= storm::utility::zero<ValueType>()) {
573 lowerBound &= middle;
575 if (middleValue <= storm::utility::zero<ValueType>()) {
576 upperBound &= middle;
578 middle = (*lowerBound + *upperBound) / 2;
581 if (middleValue >= storm::utility::zero<ValueType>()) {
582 lowerBound &= middle + (middleValue / pMax);
583 upperBound &= middle + (middleValue / pMin);
585 if (middleValue <= storm::utility::zero<ValueType>()) {
586 lowerBound &= middle + (middleValue / pMin);
587 upperBound &= middle + (middleValue / pMax);
590 middle = *lowerBound + (storm::utility::one<SolutionType>() + middleValue) * (*upperBound - *lowerBound) / 2;
591 STORM_LOG_ASSERT(middle >= *lowerBound && middle <= *upperBound,
"Bisection method bounds are inconsistent.");
594 SolutionType
const boundDiff = *upperBound - *lowerBound;
595 STORM_LOG_TRACE(
"Iteration #" << iterationCount <<
":\n\t Lower bound: " << storm::utility::convertNumber<double>(*lowerBound)
596 <<
",\n\t Upper bound: " << storm::utility::convertNumber<double>(*upperBound)
597 <<
",\n\t Difference: " << storm::utility::convertNumber<double>(boundDiff)
598 <<
",\n\t Middle val: " << storm::utility::convertNumber<double>(middleValue) <<
".");
599 if (boundDiff <= (relative ? (precision * *lowerBound) : precision)) {
600 STORM_LOG_INFO(
"Bisection method converged after " << iterationCount <<
" iterations. Difference is "
601 << std::setprecision(std::numeric_limits<double>::digits10)
602 << storm::utility::convertNumber<double>(boundDiff) <<
".");
607 STORM_LOG_WARN(
"Bisection solver aborted after " << iterationCount <<
"iterations. Bound difference is "
608 << storm::utility::convertNumber<double>(boundDiff) <<
".");
614 auto const exactMiddle = middle;
615 auto numDigits = storm::utility::convertNumber<uint64_t>(
616 storm::utility::floor(storm::utility::log10<SolutionType>(storm::utility::one<SolutionType>() / (*upperBound - *lowerBound))));
619 middle = storm::utility::kwek_mehlhorn::sharpen<SolutionType, SolutionType>(numDigits, exactMiddle);
620 }
while (middle <= *lowerBound || middle >= *upperBound);
623 if (iterationCount == 8) {
625 middle = storm::utility::zero<SolutionType>();
627 middle = storm::utility::one<SolutionType>();
631 return (*lowerBound + *upperBound) / 2;
634template<
typename ValueType,
typename SolutionType = ValueType>
639 std::vector<uint64_t> scheduler;
640 std::vector<SolutionType> targetResults, conditionResults;
641 for (uint64_t iterationCount = 1;
true; ++iterationCount) {
645 "Potential numerical issues: the probability to reach the target is greater than the probability to reach the condition. Difference is "
650 ? storm::utility::zero<ValueType>()
652 bool schedulerChanged{
false};
654 schedulerChanged = wrh.template improveScheduler<storm::OptimizationDirection::Minimize>(scheduler, lambda, targetResults, conditionResults);
656 schedulerChanged = wrh.template improveScheduler<storm::OptimizationDirection::Maximize>(scheduler, lambda, targetResults, conditionResults);
658 if (!schedulerChanged) {
659 STORM_LOG_INFO(
"Policy iteration for conditional probabilities converged after " << iterationCount <<
" iterations.");
663 STORM_LOG_WARN(
"Policy iteration for conditional probabilities converged aborted after " << iterationCount <<
"iterations.");
669template<
typename ValueType,
typename SolutionType = ValueType>
677 "Trying to compute undefined conditional probability: the condition has probability 0 under all policies.");
680 return storm::utility::one<SolutionType>();
685 return storm::utility::zero<SolutionType>();
693template<
typename ValueType,
typename SolutionType>
699 auto normalFormConstructionEnv = env;
700 auto analysisEnv = env;
704 auto const normalFormPrecisionFactor = storm::utility::convertNumber<storm::RationalNumber, std::string>(
"1/10");
705 normalFormConstructionEnv.solver().minMax().setPrecision(env.
solver().
minMax().
getPrecision() * normalFormPrecisionFactor);
707 (storm::utility::one<storm::RationalNumber>() - normalFormPrecisionFactor));
712 STORM_LOG_THROW(goal.hasRelevantValues(), storm::exceptions::NotSupportedException,
713 "No initial state given. Conditional probabilities can only be computed for models with a single initial state.");
714 STORM_LOG_THROW(goal.relevantValues().hasUniqueSetBit(), storm::exceptions::NotSupportedException,
715 "Only one initial state is supported for conditional probabilities");
719 auto normalFormData =
internal::obtainNormalForm(normalFormConstructionEnv, goal.direction(), transitionMatrix, backwardTransitions, goal.relevantValues(),
720 targetStates, conditionStates);
724 auto const initialState = *goal.relevantValues().begin();
725 ValueType initialStateValue = -storm::utility::one<ValueType>();
726 if (
auto trivialValue = internal::handleTrivialCases<ValueType, SolutionType>(initialState, normalFormData); trivialValue.has_value()) {
727 initialStateValue = *trivialValue;
728 STORM_LOG_DEBUG(
"Initial state has trivial value " << initialStateValue);
730 STORM_LOG_ASSERT(normalFormData.maybeStates.get(initialState),
"Initial state must be a maybe state if it is not a terminal state");
731 auto alg = analysisEnv.modelchecker().getConditionalAlgorithmSetting();
735 STORM_LOG_INFO(
"Analyzing normal form with " << normalFormData.maybeStates.getNumberOfSetBits() <<
" maybe states using algorithm '" << alg <<
".");
743 transitionMatrix, normalFormData);
747 transitionMatrix, normalFormData);
753 STORM_LOG_THROW(
false, storm::exceptions::NotImplementedException,
"Unknown conditional probability algorithm: " << alg);
SolverEnvironment & solver()
storm::RationalNumber const & getPrecision() const
bool const & getRelativeTerminationCriterion() const
Helper class that optionally holds a reference to an object of type T.
MinMaxSolverEnvironment & minMax()
bool isForceExact() const
bool isForceSoundness() const
static MDPSparseModelCheckingHelperReturnType< SolutionType > computeUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool qualitative, bool produceScheduler, ModelCheckerHint const &hint=ModelCheckerHint())
A helper class that computes (weighted) reachability probabilities for a given MDP in normal form.
bool improveScheduler(std::vector< uint64_t > &scheduler, ValueType const &lambda, std::vector< SolutionType > const &targetResults, std::vector< SolutionType > const &conditionResults)
SolutionType computeWeightedDiff(storm::Environment const &env, storm::OptimizationDirection const dir, ValueType const &targetWeight, ValueType const &conditionWeight) const
WeightedReachabilityHelper(uint64_t const initialState, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, NormalFormData< ValueType > const &normalForm)
void evaluateScheduler(storm::Environment const &env, std::vector< uint64_t > &scheduler, std::vector< SolutionType > &targetResults, std::vector< SolutionType > &conditionResults) const
auto getInternalInitialState() const
virtual std::unique_ptr< LinearEquationSolver< ValueType > > create(Environment const &env) const override
Creates an equation solver with the current settings, but without a matrix.
virtual std::unique_ptr< MinMaxLinearEquationSolver< ValueType, SolutionType > > create(Environment const &env) const override
virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const &env) const
Retrieves the problem format that the solver expects if it was created with the current settings.
A bit vector that is internally represented as a vector of 64-bit values.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
uint_fast64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
std::vector< uint_fast64_t > getNumberOfSetBitsBeforeIndices() const
Retrieves a vector that holds at position i the number of bits set before index i.
bool get(uint_fast64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
This class represents the decomposition of a nondeterministic model into its maximal end components.
A class that can be used to build a sparse matrix by adding value by value.
void addNextValue(index_type row, index_type column, value_type const &value)
Sets the matrix entry at the given row and column to the given value.
void newRowGroup(index_type startingRow)
Starts a new row group in the matrix.
SparseMatrix< value_type > build(index_type overriddenRowCount=0, index_type overriddenColumnCount=0, index_type overriddenRowGroupCount=0)
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.
index_type getEntryCount() const
Returns the number of entries in the matrix.
index_type getNumRowsInRowGroups(storm::storage::BitVector const &groupConstraint) const
Returns the total number of rows that are in one of the specified row groups.
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 ...
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
value_type getConstrainedRowSum(index_type row, storm::storage::BitVector const &columns) const
Sums the entries in the given row and columns.
std::vector< index_type > const & getRowGroupIndices() const
Returns the grouping of rows of this 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.
Stores and manages an extremal (maximal or minimal) value.
#define STORM_LOG_INFO(message)
#define STORM_LOG_WARN(message)
#define STORM_LOG_DEBUG(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
void computeReachabilityProbabilities(Environment const &env, std::map< uint64_t, ValueType > &nonZeroResults, storm::solver::OptimizationDirection const dir, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &allowedStates, storm::storage::BitVector const &targetStates)
Computes the reachability probabilities for the given target states and inserts all non-zero values i...
void eliminateEndComponents(storm::storage::BitVector possibleEcStates, bool addRowAtRepresentativeState, std::optional< uint64_t > representativeRowEntry, storm::storage::SparseMatrix< ValueType > &matrix, uint64_t &initialState, storm::storage::BitVector &rowsWithSum1, std::vector< ValueType > &rowValues1, storm::OptionalRef< std::vector< ValueType > > rowValues2={})
SolutionType computeViaPolicyIteration(Environment const &env, uint64_t const initialState, storm::solver::OptimizationDirection const dir, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, NormalFormData< ValueType > const &normalForm)
NormalFormData< ValueType > obtainNormalForm(Environment const &env, storm::solver::OptimizationDirection const dir, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &relevantStates, storm::storage::BitVector const &targetStates, storm::storage::BitVector const &conditionStates)
std::optional< SolutionType > handleTrivialCases(uint64_t const initialState, NormalFormData< ValueType > const &normalForm)
SolutionType solveMinMaxEquationSystem(storm::Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix, std::vector< ValueType > const &rowValues, storm::storage::BitVector const &rowsWithSum1, storm::solver::OptimizationDirection const dir, uint64_t const initialState)
SolutionType computeViaBisection(Environment const &env, BisectionMethodBounds boundOption, uint64_t const initialState, storm::solver::OptimizationDirection const dir, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, NormalFormData< ValueType > const &normalForm)
SolutionType computeViaRestartMethod(Environment const &env, uint64_t const initialState, storm::solver::OptimizationDirection const dir, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, NormalFormData< ValueType > const &normalForm)
Uses the restart method by Baier et al.
std::unique_ptr< CheckResult > computeConditionalProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &targetStates, storm::storage::BitVector const &conditionStates)
bool constexpr minimize(OptimizationDirection d)
storm::storage::BitVector getReachableStates(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &constraintStates, storm::storage::BitVector const &targetStates, bool useStepBound, uint_fast64_t maximalSteps, boost::optional< storm::storage::BitVector > const &choiceFilter)
Performs a forward depth-first search through the underlying graph structure to identify the states t...
storm::storage::BitVector performProb1A(storm::models::sparse::NondeterministicModel< T, RM > const &model, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 1 of satisfying phi until psi under all possible re...
storm::storage::BitVector performProb0A(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
storm::storage::BitVector performProb0E(storm::models::sparse::NondeterministicModel< T, RM > const &model, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 0 of satisfying phi until psi under at least one po...
bool isTerminate()
Check whether the program should terminate (due to some abort signal).
bool isOne(ValueType const &a)
ValueType floor(ValueType const &number)
bool isZero(ValueType const &a)