#include "storm/solver/EliminationLinearEquationSolver.h" #include #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/EliminationSettings.h" #include "storm/solver/stateelimination/StatePriorityQueue.h" #include "storm/solver/stateelimination/PrioritizedStateEliminator.h" #include "storm/utility/graph.h" #include "storm/utility/macros.h" #include "storm/utility/vector.h" #include "storm/utility/stateelimination.h" namespace storm { namespace solver { using namespace stateelimination; using namespace storm::utility::stateelimination; template EliminationLinearEquationSolver::EliminationLinearEquationSolver() { // Intentionally left empty. } template EliminationLinearEquationSolver::EliminationLinearEquationSolver(storm::storage::SparseMatrix const& A) : localA(nullptr), A(nullptr) { this->setMatrix(A); } template EliminationLinearEquationSolver::EliminationLinearEquationSolver(storm::storage::SparseMatrix&& A) : localA(nullptr), A(nullptr) { this->setMatrix(std::move(A)); } template void EliminationLinearEquationSolver::setMatrix(storm::storage::SparseMatrix const& A) { this->A = &A; localA.reset(); this->clearCache(); } template void EliminationLinearEquationSolver::setMatrix(storm::storage::SparseMatrix&& A) { localA = std::make_unique>(std::move(A)); this->A = localA.get(); this->clearCache(); } template bool EliminationLinearEquationSolver::internalSolveEquations(Environment const& env, std::vector& x, std::vector const& b) const { // FIXME: This solver will not work for all input systems. More concretely, the current implementation will // not work for systems that have a 1 on the diagonal. This is not a restriction of this technique in general // but arbitrary matrices require pivoting, which is not currently implemented. STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with elimination"); storm::storage::SparseMatrix const& transitionMatrix = localA ? *localA : *A; storm::storage::SparseMatrix backwardTransitions = transitionMatrix.transpose(); // Initialize the solution to the right-hand side of the equation system. x = b; // Translate the matrix and its transpose into the flexible format. storm::storage::FlexibleSparseMatrix flexibleMatrix(transitionMatrix, false); storm::storage::FlexibleSparseMatrix flexibleBackwardTransitions(backwardTransitions, true); boost::optional> distanceBasedPriorities; // TODO: get the order from the environment storm::settings::modules::EliminationSettings::EliminationOrder order = storm::settings::getModule().getEliminationOrder(); if (eliminationOrderNeedsDistances(order)) { // Since we have no initial states at this point, we determine a representative of every BSCC regarding // the backward transitions, because this means that every row is reachable from this set of rows, which // we require to make sure we cover every row. storm::storage::BitVector initialRows = storm::utility::graph::getBsccCover(backwardTransitions); distanceBasedPriorities = getDistanceBasedPriorities(transitionMatrix, backwardTransitions, initialRows, b, eliminationOrderNeedsForwardDistances(order), eliminationOrderNeedsReversedDistances(order)); } std::shared_ptr priorityQueue = createStatePriorityQueue(distanceBasedPriorities, flexibleMatrix, flexibleBackwardTransitions, b, storm::storage::BitVector(x.size(), true)); // Create a state eliminator to perform the actual elimination. PrioritizedStateEliminator eliminator(flexibleMatrix, flexibleBackwardTransitions, priorityQueue, x); // Eliminate all states. while (priorityQueue->hasNext()) { auto state = priorityQueue->pop(); eliminator.eliminateState(state, false); } return true; } template LinearEquationSolverProblemFormat EliminationLinearEquationSolver::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::FixedPointSystem; } template uint64_t EliminationLinearEquationSolver::getMatrixRowCount() const { return this->A->getRowCount(); } template uint64_t EliminationLinearEquationSolver::getMatrixColumnCount() const { return this->A->getColumnCount(); } template std::unique_ptr> EliminationLinearEquationSolverFactory::create(Environment const& env) const { return std::make_unique>(); } template std::unique_ptr> EliminationLinearEquationSolverFactory::clone() const { return std::make_unique>(*this); } template class EliminationLinearEquationSolver; template class EliminationLinearEquationSolverFactory; #ifdef STORM_HAVE_CARL template class EliminationLinearEquationSolver; template class EliminationLinearEquationSolver; template class EliminationLinearEquationSolverFactory; template class EliminationLinearEquationSolverFactory; #endif } }