27template<
typename ValueType>
30 std::vector<ValueType>& rowValues1,
storm::OptionalRef<std::vector<ValueType>> rowValues2 = {}) {
38 matrix, ecs, allRowGroups, addRowAtRepresentativeState ? allRowGroups : ~allRowGroups, representativeRowEntry.has_value());
41 matrix = std::move(ecElimResult.matrix);
42 if (addRowAtRepresentativeState && representativeRowEntry) {
43 auto const columnIndex = ecElimResult.oldToNewStateMapping[*representativeRowEntry];
44 for (
auto representativeRowIndex : ecElimResult.sinkRows) {
45 auto row = matrix.
getRow(representativeRowIndex);
46 STORM_LOG_ASSERT(row.getNumberOfEntries() == 1,
"unexpected number of entries in representative row.");
47 auto& entry = *row.begin();
48 entry.setColumn(columnIndex);
53 auto updateRowValue = [&ecElimResult](std::vector<ValueType>& rowValues) {
54 std::vector<ValueType> newRowValues;
55 newRowValues.reserve(ecElimResult.newToOldRowMapping.size());
56 for (
auto oldRowIndex : ecElimResult.newToOldRowMapping) {
57 newRowValues.push_back(rowValues[oldRowIndex]);
59 rowValues = std::move(newRowValues);
61 std::all_of(ecElimResult.sinkRows.begin(), ecElimResult.sinkRows.end(), [&rowValues](
auto i) { return storm::utility::isZero(rowValues[i]); }),
62 "Sink rows are expected to have zero value");
64 updateRowValue(rowValues1);
66 updateRowValue(*rowValues2);
70 initialState = ecElimResult.oldToNewStateMapping[initialState];
74 uint64_t newRowIndex = 0;
75 for (
auto oldRowIndex : ecElimResult.newToOldRowMapping) {
76 if ((addRowAtRepresentativeState && !representativeRowEntry.has_value() && ecElimResult.sinkRows.get(newRowIndex)) || !rowsWithSum1.
get(oldRowIndex)) {
77 newRowsWithSum1.set(newRowIndex,
false);
81 rowsWithSum1 = std::move(newRowsWithSum1);
84template<
typename ValueType,
typename SolutionType = ValueType>
89 std::vector<SolutionType> x(matrix.
getRowGroupCount(), storm::utility::zero<ValueType>());
93 solver->setOptimizationDirection(dir);
94 solver->setRequirementsChecked();
95 solver->setHasUniqueSolution(
true);
96 solver->setHasNoEndComponents(
true);
97 solver->setLowerBound(storm::utility::zero<ValueType>());
98 solver->setUpperBound(storm::utility::one<ValueType>());
101 solver->solveEquations(env, x, rowValues);
102 return x[initialState];
109template<
typename ValueType>
113 if (initialStates.
empty()) {
117 auto const subTargets = targetStates % reachableStates;
119 if (subTargets.empty()) {
122 auto const subInits = initialStates % reachableStates;
123 auto const submatrix = transitionMatrix.
getSubmatrix(
true, reachableStates, reachableStates);
126 subTargets,
false,
false);
127 auto origInitIt = initialStates.
begin();
128 for (
auto subInit : subInits) {
129 auto const& val = subResult.values[subInit];
131 nonZeroResults.emplace(*origInitIt, val);
137template<
typename ValueType>
169template<
typename ValueType>
175 auto extendedConditionStates =
178 std::map<uint64_t, ValueType> nonZeroTargetStateValues;
179 auto const extendedTargetStates =
182 auto const targetAndNotCondFailStates = extendedTargetStates & ~(extendedConditionStates | universalObservationFailureStates);
186 auto terminalStatesThatReachCondition = extendedConditionStates;
187 for (
auto state : targetAndNotCondFailStates) {
188 if (nonZeroTargetStateValues.contains(state)) {
189 terminalStatesThatReachCondition.set(state,
true);
194 auto terminalStates = extendedConditionStates | extendedTargetStates | universalObservationFailureStates;
203 auto nonTerminalStates = ~terminalStates;
206 backwardTransitions, nonTerminalStates, terminalStatesThatReachCondition);
212 .terminalStates = std::move(terminalStates),
213 .conditionStates = std::move(extendedConditionStates),
214 .universalObservationFailureStates = std::move(universalObservationFailureStates),
215 .existentialObservationFailureStates = std::move(existentialObservationFailureStates),
216 .nonZeroTargetStateValues = std::move(nonZeroTargetStateValues)};
223template<
typename ValueType,
typename SolutionType = ValueType>
228 auto const numMaybeStates = maybeStates.getNumberOfSetBits();
233 std::vector<ValueType> rowValues;
235 rowValues.reserve(numMaybeChoices);
236 uint64_t currentRow = 0;
237 for (
auto state : maybeStates) {
243 ValueType targetProbability = storm::utility::zero<ValueType>();
244 ValueType restartProbability = storm::utility::zero<ValueType>();
245 bool rowSumIsLess1 =
false;
246 for (
auto const& entry : transitionMatrix.
getRow(origRowIndex)) {
248 ValueType
const targetValue = normalForm.
getTargetValue(entry.getColumn());
249 targetProbability += targetValue * entry.getValue();
251 rowSumIsLess1 =
true;
254 rowSumIsLess1 =
true;
256 restartProbability += entry.getValue() * normalForm.
failProbability(entry.getColumn());
261 rowsWithSum1.
set(currentRow,
false);
263 rowValues.push_back(targetProbability);
265 for (
auto const& entry : transitionMatrix.
getRow(origRowIndex)) {
268 if (addRestartTransition && entry.getColumn() > initialState) {
269 matrixBuilder.
addNextValue(currentRow, stateToMatrixIndexMap[initialState], restartProbability);
270 addRestartTransition =
false;
272 if (maybeStates.get(entry.getColumn())) {
273 matrixBuilder.
addNextValue(currentRow, stateToMatrixIndexMap[entry.getColumn()], entry.getValue());
277 if (addRestartTransition) {
278 matrixBuilder.
addNextValue(currentRow, stateToMatrixIndexMap[initialState], restartProbability);
284 auto matrix = matrixBuilder.
build();
285 auto initStateInMatrix = stateToMatrixIndexMap[initialState];
291 selectedStatesInMatrix.
set(initStateInMatrix,
false);
292 eliminateEndComponents(selectedStatesInMatrix,
true, initStateInMatrix, matrix, initStateInMatrix, rowsWithSum1, rowValues);
295 selectedStatesInMatrix.
set(initStateInMatrix,
true);
296 eliminateEndComponents(selectedStatesInMatrix,
false, std::nullopt, matrix, initStateInMatrix, rowsWithSum1, rowValues);
309template<
typename ValueType,
typename SolutionType = ValueType>
325 subMatrixRowGroups.set(initialState,
false);
326 std::vector<uint64_t> dfsStack = {initialState};
327 while (!dfsStack.empty()) {
328 auto const state = dfsStack.back();
331 auto const row = transitionMatrix.
getRow(rowIndex);
332 if (std::all_of(row.begin(), row.end(),
333 [&normalForm](
auto const& entry) { return normalForm.existentialObservationFailureStates.get(entry.getColumn()); })) {
334 for (
auto const& entry : row) {
335 auto const& successor = entry.getColumn();
336 if (subMatrixRowGroups.get(successor)) {
337 subMatrixRowGroups.set(successor,
false);
338 dfsStack.push_back(successor);
342 initialComponentExitRows.
set(rowIndex,
true);
347 subMatrixRowGroups.set(initialState,
true);
348 auto const numSubmatrixRowGroups = subMatrixRowGroups.getNumberOfSetBits();
351 auto stateToMatrixIndexMap = subMatrixRowGroups.getNumberOfSetBitsBeforeIndices();
352 initialStateInSubmatrix = stateToMatrixIndexMap[initialState];
353 auto const eliminatedInitialComponentStates = normalForm.
maybeStates & ~subMatrixRowGroups;
354 for (
auto state : eliminatedInitialComponentStates) {
355 stateToMatrixIndexMap[state] = initialStateInSubmatrix;
361 targetRowValues.reserve(numSubmatrixRows);
362 conditionRowValues.reserve(numSubmatrixRows);
363 uint64_t currentRow = 0;
364 for (
auto state : subMatrixRowGroups) {
368 auto processRow = [&](uint64_t origRowIndex) {
370 ValueType
const eliminatedInitialComponentProbability = transitionMatrix.
getConstrainedRowSum(origRowIndex, eliminatedInitialComponentStates);
372 ValueType targetProbability = storm::utility::zero<ValueType>();
373 ValueType conditionProbability = storm::utility::zero<ValueType>();
374 bool rowSumIsLess1 =
false;
375 bool initialStateEntryInserted =
false;
376 for (
auto const& entry : transitionMatrix.
getRow(origRowIndex)) {
379 rowSumIsLess1 =
true;
380 ValueType
const scaledTargetValue = normalForm.
getTargetValue(entry.getColumn()) * entry.getValue();
381 targetProbability += scaledTargetValue;
383 conditionProbability += entry.getValue();
385 conditionProbability += scaledTargetValue;
387 }
else if (!eliminatedInitialComponentStates.get(entry.getColumn())) {
388 auto const columnIndex = stateToMatrixIndexMap[entry.getColumn()];
389 if (!initialStateEntryInserted && columnIndex >= initialStateInSubmatrix) {
390 if (columnIndex == initialStateInSubmatrix) {
391 matrixBuilder.
addNextValue(currentRow, initialStateInSubmatrix, eliminatedInitialComponentProbability + entry.getValue());
393 matrixBuilder.
addNextValue(currentRow, initialStateInSubmatrix, eliminatedInitialComponentProbability);
394 matrixBuilder.
addNextValue(currentRow, columnIndex, entry.getValue());
396 initialStateEntryInserted =
true;
398 matrixBuilder.
addNextValue(currentRow, columnIndex, entry.getValue());
403 rowsWithSum1.
set(currentRow,
false);
405 targetRowValues.push_back(targetProbability);
406 conditionRowValues.push_back(conditionProbability);
410 if (state == initialState) {
411 for (
auto origRowIndex : initialComponentExitRows) {
412 processRow(origRowIndex);
416 processRow(origRowIndex);
420 submatrix = matrixBuilder.
build();
425 allExceptInit.
set(initialStateInSubmatrix,
false);
426 eliminateEndComponents<ValueType>(allExceptInit,
true, std::nullopt, submatrix, initialStateInSubmatrix, rowsWithSum1, targetRowValues,
428 STORM_LOG_INFO(
"Processed model has " << submatrix.getRowGroupCount() <<
" states and " << submatrix.getRowGroupCount() <<
" choices and "
429 << submatrix.getEntryCount() <<
" transitions.");
433 ValueType
const& conditionWeight)
const {
434 auto rowValues = createScaledVector(targetWeight, targetRowValues, conditionWeight, conditionRowValues);
437 std::vector<SolutionType> x(submatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
441 solver->setOptimizationDirection(dir);
442 solver->setRequirementsChecked();
443 solver->setHasUniqueSolution(
true);
444 solver->setHasNoEndComponents(
true);
445 solver->setLowerBound(-storm::utility::one<ValueType>());
446 solver->setUpperBound(storm::utility::one<ValueType>());
448 solver->solveEquations(env, x, rowValues);
449 return x[initialStateInSubmatrix];
453 return initialStateInSubmatrix;
457 std::vector<SolutionType>& conditionResults)
const {
458 if (scheduler.empty()) {
459 scheduler.resize(submatrix.getRowGroupCount(), 0);
461 if (targetResults.empty()) {
462 targetResults.resize(submatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
464 if (conditionResults.empty()) {
465 conditionResults.resize(submatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
470 auto scheduledMatrix = submatrix.selectRowsFromRowGroups(scheduler, convertToEquationSystem);
471 if (convertToEquationSystem) {
472 scheduledMatrix.convertToEquationSystem();
474 auto solver = factory.
create(env, std::move(scheduledMatrix));
475 solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
476 solver->setCachingEnabled(
true);
478 std::vector<ValueType> subB(submatrix.getRowGroupCount());
479 storm::utility::vector::selectVectorValues<ValueType>(subB, scheduler, submatrix.getRowGroupIndices(), targetRowValues);
480 solver->solveEquations(env, targetResults, subB);
482 storm::utility::vector::selectVectorValues<ValueType>(subB, scheduler, submatrix.getRowGroupIndices(), conditionRowValues);
483 solver->solveEquations(env, conditionResults, subB);
486 template<OptimizationDirection Dir>
487 bool improveScheduler(std::vector<uint64_t>& scheduler, ValueType
const& lambda, std::vector<SolutionType>
const& targetResults,
488 std::vector<SolutionType>
const& conditionResults) {
489 bool improved =
false;
490 for (uint64_t rowGroupIndex = 0; rowGroupIndex < scheduler.size(); ++rowGroupIndex) {
492 uint64_t optimalRowIndex{0};
493 ValueType scheduledValue;
494 for (
auto rowIndex : submatrix.getRowGroupIndices(rowGroupIndex)) {
495 ValueType rowValue = targetRowValues[rowIndex] - lambda * conditionRowValues[rowIndex];
496 for (
auto const& entry : submatrix.getRow(rowIndex)) {
497 rowValue += entry.getValue() * (targetResults[entry.getColumn()] - lambda * conditionResults[entry.getColumn()]);
499 if (rowIndex == scheduler[rowGroupIndex] + submatrix.getRowGroupIndices()[rowGroupIndex]) {
500 scheduledValue = rowValue;
502 if (groupValue &= rowValue) {
503 optimalRowIndex = rowIndex;
506 if (scheduledValue != *groupValue) {
507 scheduler[rowGroupIndex] = optimalRowIndex - submatrix.getRowGroupIndices()[rowGroupIndex];
515 std::vector<ValueType> createScaledVector(ValueType
const& w1, std::vector<ValueType>
const& v1, ValueType
const& w2,
516 std::vector<ValueType>
const& v2)
const {
518 std::vector<ValueType> result;
519 result.reserve(v1.size());
520 for (
size_t i = 0; i < v1.size(); ++i) {
521 result.push_back(w1 * v1[i] + w2 * v2[i]);
528 std::vector<ValueType> targetRowValues;
529 std::vector<ValueType> conditionRowValues;
530 uint64_t initialStateInSubmatrix;
534template<
typename ValueType,
typename SolutionType = ValueType>
540 "Bisection method does not adequately handle propagation of errors. Result is not necessarily sound.");
541 SolutionType
const precision = [&env, boundOption]() {
544 "Selected bisection method with exact precision in a setting that might not terminate.");
545 return storm::utility::zero<SolutionType>();
553 SolutionType pMin{storm::utility::zero<SolutionType>()};
554 SolutionType pMax{storm::utility::one<SolutionType>()};
557 pMin = wrh.
computeWeightedDiff(env, storm::OptimizationDirection::Minimize, storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
558 pMax = wrh.
computeWeightedDiff(env, storm::OptimizationDirection::Maximize, storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
559 STORM_LOG_TRACE(
"Conditioning event bounds:\n\t Lower bound: " << storm::utility::convertNumber<double>(pMin)
560 <<
",\n\t Upper bound: " << storm::utility::convertNumber<double>(pMax));
564 SolutionType middle = (*lowerBound + *upperBound) / 2;
565 for (uint64_t iterationCount = 1;
true; ++iterationCount) {
567 SolutionType
const middleValue = wrh.
computeWeightedDiff(env, dir, storm::utility::one<ValueType>(), -middle);
570 if (middleValue >= storm::utility::zero<ValueType>()) {
571 lowerBound &= middle;
573 if (middleValue <= storm::utility::zero<ValueType>()) {
574 upperBound &= middle;
576 middle = (*lowerBound + *upperBound) / 2;
579 if (middleValue >= storm::utility::zero<ValueType>()) {
580 lowerBound &= middle + (middleValue / pMax);
581 upperBound &= middle + (middleValue / pMin);
583 if (middleValue <= storm::utility::zero<ValueType>()) {
584 lowerBound &= middle + (middleValue / pMin);
585 upperBound &= middle + (middleValue / pMax);
588 middle = *lowerBound + (storm::utility::one<SolutionType>() + middleValue) * (*upperBound - *lowerBound) / 2;
591 if (*lowerBound > *upperBound) {
592 std::swap(*lowerBound, *upperBound);
594 STORM_LOG_WARN(
"Precision of non-exact type reached during bisection method. Result might be inaccurate.");
596 STORM_LOG_ASSERT(middle >= *lowerBound && middle <= *upperBound,
"Bisection method bounds are inconsistent.");
600 SolutionType
const boundDiff = *upperBound - *lowerBound;
601 STORM_LOG_TRACE(
"Iteration #" << iterationCount <<
":\n\t Lower bound: " << storm::utility::convertNumber<double>(*lowerBound)
602 <<
",\n\t Upper bound: " << storm::utility::convertNumber<double>(*upperBound)
603 <<
",\n\t Difference: " << storm::utility::convertNumber<double>(boundDiff)
604 <<
",\n\t Middle val: " << storm::utility::convertNumber<double>(middleValue) <<
",\n\t Difference bound: "
605 << storm::utility::convertNumber<double>((relative ? (precision * *lowerBound) : precision)) <<
".");
606 if (boundDiff <= (relative ? (precision * *lowerBound) : precision)) {
607 STORM_LOG_INFO(
"Bisection method converged after " << iterationCount <<
" iterations. Difference is "
608 << std::setprecision(std::numeric_limits<double>::digits10)
609 << storm::utility::convertNumber<double>(boundDiff) <<
".");
614 STORM_LOG_WARN(
"Bisection solver aborted after " << iterationCount <<
"iterations. Bound difference is "
615 << storm::utility::convertNumber<double>(boundDiff) <<
".");
621 auto const exactMiddle = middle;
624 auto numDigits = storm::utility::numDigits<SolutionType>(*upperBound - *lowerBound) - 1;
628 middle = storm::utility::kwek_mehlhorn::sharpen<SolutionType, SolutionType>(numDigits, exactMiddle);
629 }
while (middle <= *lowerBound || middle >= *upperBound);
632 if (iterationCount == 8) {
634 middle = storm::utility::zero<SolutionType>();
636 middle = storm::utility::one<SolutionType>();
640 return (*lowerBound + *upperBound) / 2;
643template<
typename ValueType,
typename SolutionType = ValueType>
648 std::vector<uint64_t> scheduler;
649 std::vector<SolutionType> targetResults, conditionResults;
650 for (uint64_t iterationCount = 1;
true; ++iterationCount) {
654 "Potential numerical issues: the probability to reach the target is greater than the probability to reach the condition. Difference is "
659 ? storm::utility::zero<ValueType>()
661 bool schedulerChanged{
false};
663 schedulerChanged = wrh.template improveScheduler<storm::OptimizationDirection::Minimize>(scheduler, lambda, targetResults, conditionResults);
665 schedulerChanged = wrh.template improveScheduler<storm::OptimizationDirection::Maximize>(scheduler, lambda, targetResults, conditionResults);
667 if (!schedulerChanged) {
668 STORM_LOG_INFO(
"Policy iteration for conditional probabilities converged after " << iterationCount <<
" iterations.");
672 STORM_LOG_WARN(
"Policy iteration for conditional probabilities converged aborted after " << iterationCount <<
"iterations.");
678template<
typename ValueType,
typename SolutionType = ValueType>
686 "Trying to compute undefined conditional probability: the condition has probability 0 under all policies.");
689 return storm::utility::one<SolutionType>();
694 return storm::utility::zero<SolutionType>();
702template<
typename ValueType,
typename SolutionType>
708 auto normalFormConstructionEnv = env;
709 auto analysisEnv = env;
713 auto const normalFormPrecisionFactor = storm::utility::convertNumber<storm::RationalNumber, std::string>(
"1/10");
714 normalFormConstructionEnv.solver().minMax().setPrecision(env.
solver().
minMax().
getPrecision() * normalFormPrecisionFactor);
716 (storm::utility::one<storm::RationalNumber>() - normalFormPrecisionFactor));
721 STORM_LOG_THROW(goal.hasRelevantValues(), storm::exceptions::NotSupportedException,
722 "No initial state given. Conditional probabilities can only be computed for models with a single initial state.");
723 STORM_LOG_THROW(goal.relevantValues().hasUniqueSetBit(), storm::exceptions::NotSupportedException,
724 "Only one initial state is supported for conditional probabilities");
728 auto normalFormData =
internal::obtainNormalForm(normalFormConstructionEnv, goal.direction(), transitionMatrix, backwardTransitions, goal.relevantValues(),
729 targetStates, conditionStates);
733 auto const initialState = *goal.relevantValues().begin();
734 ValueType initialStateValue = -storm::utility::one<ValueType>();
735 if (
auto trivialValue = internal::handleTrivialCases<ValueType, SolutionType>(initialState, normalFormData); trivialValue.has_value()) {
736 initialStateValue = *trivialValue;
737 STORM_LOG_DEBUG(
"Initial state has trivial value " << initialStateValue);
739 STORM_LOG_ASSERT(normalFormData.maybeStates.get(initialState),
"Initial state must be a maybe state if it is not a terminal state");
740 auto alg = analysisEnv.modelchecker().getConditionalAlgorithmSetting();
744 STORM_LOG_INFO(
"Analyzing normal form with " << normalFormData.maybeStates.getNumberOfSetBits() <<
" maybe states using algorithm '" << alg <<
".");
752 transitionMatrix, normalFormData);
756 transitionMatrix, normalFormData);
762 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.
std::vector< uint64_t > getNumberOfSetBitsBeforeIndices() const
Retrieves a vector that holds at position i the number of bits set before index i.
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.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
bool get(uint64_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)
bool isAlmostZero(ValueType const &a)
bool isZero(ValueType const &a)