18template<
typename ValueType>
23template<
typename ValueType>
28template<
typename ValueType>
33template<
typename ValueType>
40template<
typename ValueType>
42 localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A));
43 this->A = localA.get();
47template<
typename ValueType>
53 STORM_LOG_ASSERT(this->longestSccChainSize,
"Did not compute the longest SCC chain size although it is needed.");
54 auto subEnvPrec = subEnv.solver().getPrecisionOfLinearEquationSolver(subEnv.solver().getLinearEquationSolverType());
55 subEnv.solver().setLinearEquationSolverPrecision(
56 static_cast<storm::RationalNumber
>(subEnvPrec.first.get() / storm::utility::convertNumber<storm::RationalNumber>(this->longestSccChainSize.get())));
61template<
typename ValueType>
63 std::vector<ValueType>
const& b)
const {
65 bool needAdaptPrecision =
69 if (!this->sortedSccDecomposition || (needAdaptPrecision && !this->longestSccChainSize)) {
72 createSortedSccDecomposition(needAdaptPrecision);
75 << sccSw <<
". Found " << this->sortedSccDecomposition->size() <<
" SCC(s) containing a total of " << x.size()
76 <<
" states. Average SCC size is "
77 <<
static_cast<double>(this->getMatrixRowCount()) /
static_cast<double>(this->sortedSccDecomposition->size()) <<
".");
81 needAdaptPrecision = needAdaptPrecision && (this->sortedSccDecomposition->size() != this->getMatrixRowCount());
83 storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env, needAdaptPrecision);
85 if (this->longestSccChainSize) {
86 STORM_LOG_INFO(
"Longest SCC chain size is " << this->longestSccChainSize.get() <<
".");
90 bool returnValue =
true;
91 if (this->sortedSccDecomposition->size() == 1) {
92 if (
auto const& scc = *this->sortedSccDecomposition->begin(); scc.size() == 1) {
94 returnValue = solveTrivialScc(*scc.begin(), x, b);
96 returnValue = solveFullyConnectedEquationSystem(sccSolverEnvironment, x, b);
100 std::optional<storm::storage::BitVector> newRelevantValues;
102 this->sortedSccDecomposition->size() < this->A->getRowGroupCount()) {
103 newRelevantValues = this->getRelevantValues();
105 std::vector<uint64_t> rowGroupToScc = this->sortedSccDecomposition->computeStateToSccIndexMap(this->A->getRowGroupCount());
106 for (uint64_t rowGroup = 0; rowGroup < this->A->getRowGroupCount(); ++rowGroup) {
107 auto currScc = rowGroupToScc[rowGroup];
108 for (
auto const& successor : this->A->getRowGroup(rowGroup)) {
109 if (rowGroupToScc[successor.getColumn()] != currScc) {
110 newRelevantValues->set(successor.getColumn(),
true);
116 uint64_t sccIndex = 0;
120 for (
auto const& scc : *this->sortedSccDecomposition) {
121 if (scc.size() == 1) {
122 returnValue = solveTrivialScc(*scc.begin(), x, b) && returnValue;
124 sccAsBitVector.
clear();
125 for (
auto const& state : scc) {
126 sccAsBitVector.
set(state,
true);
128 returnValue = solveScc(sccSolverEnvironment, sccAsBitVector, x, b, newRelevantValues) && returnValue;
133 STORM_LOG_WARN(
"Topological solver aborted after analyzing " << sccIndex <<
"/" << this->sortedSccDecomposition->size() <<
" SCCs.");
139 if (!this->isCachingEnabled()) {
146template<
typename ValueType>
149 this->sortedSccDecomposition = std::make_unique<storm::storage::StronglyConnectedComponentDecomposition<ValueType>>(
151 if (needLongestChainSize) {
152 this->longestSccChainSize = this->sortedSccDecomposition->getMaxSccDepth() + 1;
156template<
typename ValueType>
157bool TopologicalLinearEquationSolver<ValueType>::solveTrivialScc(uint64_t
const& sccState, std::vector<ValueType>& globalX,
158 std::vector<ValueType>
const& globalB)
const {
159 ValueType& xi = globalX[sccState];
160 xi = globalB[sccState];
161 bool hasDiagonalEntry =
false;
162 ValueType denominator;
163 for (
auto const& entry : this->A->getRow(sccState)) {
164 if (entry.getColumn() == sccState) {
166 hasDiagonalEntry =
true;
167 denominator = storm::utility::one<ValueType>() - entry.getValue();
169 xi += entry.getValue() * globalX[entry.getColumn()];
173 if (hasDiagonalEntry) {
176 "State " << sccState <<
" has a selfloop with probability '1-(" << denominator <<
")'. This could be an indication for numerical issues.");
186template<
typename ValueType>
187bool TopologicalLinearEquationSolver<ValueType>::solveFullyConnectedEquationSystem(
storm::Environment const& sccSolverEnvironment, std::vector<ValueType>& x,
188 std::vector<ValueType>
const& b)
const {
189 if (!this->sccSolver) {
190 this->sccSolver = GeneralLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment);
191 this->sccSolver->setCachingEnabled(
true);
193 if (this->hasRelevantValues()) {
194 this->sccSolver->setRelevantValues(this->getRelevantValues());
196 this->sccSolver->setBoundsFromOtherSolver(*
this);
200 eqSysA.convertToEquationSystem();
201 this->sccSolver->setMatrix(std::move(eqSysA));
203 this->sccSolver->setMatrix(*this->A);
206 return this->sccSolver->solveEquations(sccSolverEnvironment, x, b);
209template<
typename ValueType>
211 std::vector<ValueType>& globalX, std::vector<ValueType>
const& globalB,
212 std::optional<storm::storage::BitVector>
const& globalRelevantValues)
const {
214 if (!this->sccSolver) {
215 this->sccSolver = GeneralLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment);
216 this->sccSolver->setCachingEnabled(
true);
218 if (globalRelevantValues) {
219 this->sccSolver->setRelevantValues((*globalRelevantValues) % scc);
225 if (asEquationSystem) {
228 this->sccSolver->setMatrix(std::move(sccA));
234 std::vector<ValueType> sccB;
236 for (
auto row : scc) {
238 for (
auto const& entry : this->A->getRow(row)) {
239 if (!scc.
get(entry.getColumn())) {
240 bi += entry.getValue() * globalX[entry.getColumn()];
243 sccB.push_back(std::move(bi));
248 this->sccSolver->setLowerBound(this->getLowerBound());
253 this->sccSolver->setUpperBound(this->getUpperBound());
261 bool returnvalue = this->sccSolver->solveEquations(sccSolverEnvironment, sccX, sccB);
266template<
typename ValueType>
271template<
typename ValueType>
277template<
typename ValueType>
279 sortedSccDecomposition.reset();
280 longestSccChainSize = boost::none;
285template<
typename ValueType>
287 return this->A->getRowCount();
290template<
typename ValueType>
291uint64_t TopologicalLinearEquationSolver<ValueType>::getMatrixColumnCount()
const {
292 return this->A->getColumnCount();
295template<
typename ValueType>
297 return std::make_unique<storm::solver::TopologicalLinearEquationSolver<ValueType>>();
300template<
typename ValueType>
302 return std::make_unique<TopologicalLinearEquationSolverFactory<ValueType>>(*this);
309#ifdef STORM_HAVE_CARL
SolverEnvironment & solver()
TopologicalSolverEnvironment & topological()
bool isForceSoundness() const
std::pair< boost::optional< storm::RationalNumber >, boost::optional< bool > > getPrecisionOfLinearEquationSolver(storm::solver::EquationSolverType const &solverType) const
storm::solver::EquationSolverType const & getUnderlyingEquationSolverType() const
bool isExtendRelevantValues() const
bool const & isUnderlyingEquationSolverTypeSetFromDefault() const
LinearEquationSolverRequirements getRequirements(Environment const &env) const
Retrieves the requirements of the solver if it was created with the current settings.
virtual void clearCache() const
virtual std::unique_ptr< LinearEquationSolverFactory< ValueType > > clone() const override
Creates a copy of this factory.
virtual std::unique_ptr< storm::solver::LinearEquationSolver< ValueType > > create(Environment const &env) const override
Creates an equation solver with the current settings, but without a matrix.
virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const &env) const override
Retrieves the format in which this solver expects to solve equations.
virtual bool internalSolveEquations(storm::Environment const &env, std::vector< ValueType > &x, std::vector< ValueType > const &b) const override
virtual void setMatrix(storm::storage::SparseMatrix< ValueType > const &A) override
virtual LinearEquationSolverRequirements getRequirements(Environment const &env) const override
Retrieves the requirements of the solver under the current settings.
TopologicalLinearEquationSolver()
virtual void clearCache() const override
A bit vector that is internally represented as a vector of 64-bit values.
void clear()
Removes all set bits from 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.
bool get(uint_fast64_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.
void convertToEquationSystem()
Transforms the matrix into an equation system.
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 ...
A class that provides convenience operations to display run times.
bool updateProgress(uint64_t count)
Updates the progress to the current count and prints it if the delay passed.
void setMaxCount(uint64_t maxCount)
Sets the maximal possible count.
void startNewMeasurement(uint64_t startCount)
Starts a new measurement, dropping all progress information collected so far.
A class that provides convenience operations to display run times.
void stop()
Stop stopwatch and add measured time to total time.
#define STORM_LOG_INFO(message)
#define STORM_LOG_WARN(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
#define STORM_LOG_WARN_COND_DEBUG(cond, message)
SFTBDDChecker::ValueType ValueType
LinearEquationSolverProblemFormat
bool isTerminate()
Check whether the program should terminate (due to some abort signal).
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.
std::vector< Type > filterVector(std::vector< Type > const &in, storm::storage::BitVector const &filter)
bool isOne(ValueType const &a)
NumberTraits< RationalType >::IntegerType denominator(RationalType const &number)
bool isAlmostZero(ValueType const &a)
bool isZero(ValueType const &a)
StronglyConnectedComponentDecompositionOptions & computeSccDepths(bool value=true)
Sets if scc depths can be retrieved.
StronglyConnectedComponentDecompositionOptions & forceTopologicalSort(bool value=true)
Enforces that the returned SCCs are sorted in a topological order.