You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
9.7 KiB
191 lines
9.7 KiB
#include "src/solver/EliminationLinearEquationSolver.h"
|
|
|
|
#include <numeric>
|
|
|
|
#include "src/settings/SettingsManager.h"
|
|
|
|
#include "src/solver/stateelimination/StatePriorityQueue.h"
|
|
#include "src/solver/stateelimination/PrioritizedStateEliminator.h"
|
|
|
|
#include "src/utility/graph.h"
|
|
#include "src/utility/macros.h"
|
|
#include "src/utility/vector.h"
|
|
#include "src/utility/stateelimination.h"
|
|
|
|
namespace storm {
|
|
namespace solver {
|
|
|
|
using namespace stateelimination;
|
|
using namespace storm::utility::stateelimination;
|
|
|
|
template<typename ValueType>
|
|
EliminationLinearEquationSolverSettings<ValueType>::EliminationLinearEquationSolverSettings() {
|
|
order = storm::settings::getModule<storm::settings::modules::EliminationSettings>().getEliminationOrder();
|
|
}
|
|
|
|
template<typename ValueType>
|
|
void EliminationLinearEquationSolverSettings<ValueType>::setEliminationOrder(storm::settings::modules::EliminationSettings::EliminationOrder const& order) {
|
|
this->order = order;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
storm::settings::modules::EliminationSettings::EliminationOrder EliminationLinearEquationSolverSettings<ValueType>::getEliminationOrder() const {
|
|
return order;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
EliminationLinearEquationSolver<ValueType>::EliminationLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, EliminationLinearEquationSolverSettings<ValueType> const& settings) : localA(nullptr), A(nullptr), settings(settings) {
|
|
this->setMatrix(A);
|
|
}
|
|
|
|
template<typename ValueType>
|
|
EliminationLinearEquationSolver<ValueType>::EliminationLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, EliminationLinearEquationSolverSettings<ValueType> const& settings) : localA(nullptr), A(nullptr), settings(settings) {
|
|
this->setMatrix(std::move(A));
|
|
}
|
|
|
|
template<typename ValueType>
|
|
void EliminationLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& A) {
|
|
this->A = &A;
|
|
localA.reset();
|
|
}
|
|
|
|
template<typename ValueType>
|
|
void EliminationLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& A) {
|
|
localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A));
|
|
this->A = localA.get();
|
|
}
|
|
|
|
template<typename ValueType>
|
|
void EliminationLinearEquationSolver<ValueType>::solveEquations(std::vector<ValueType>& x, std::vector<ValueType> 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 0 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_DEBUG("Solving equation system using elimination.");
|
|
|
|
// We need to revert the transformation into an equation system matrix, because the elimination procedure
|
|
// and the distance computation is based on the probability matrix instead.
|
|
storm::storage::SparseMatrix<ValueType> locallyConvertedMatrix;
|
|
if (localA) {
|
|
localA->convertToEquationSystem();
|
|
} else {
|
|
locallyConvertedMatrix = *A;
|
|
locallyConvertedMatrix.convertToEquationSystem();
|
|
}
|
|
|
|
storm::storage::SparseMatrix<ValueType> const& transitionMatrix = localA ? *localA : locallyConvertedMatrix;
|
|
storm::storage::SparseMatrix<ValueType> 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<ValueType> flexibleMatrix(transitionMatrix, false);
|
|
storm::storage::FlexibleSparseMatrix<ValueType> flexibleBackwardTransitions(backwardTransitions, true);
|
|
|
|
boost::optional<std::vector<uint_fast64_t>> distanceBasedPriorities;
|
|
auto order = this->getSettings().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<StatePriorityQueue> priorityQueue = createStatePriorityQueue<ValueType>(distanceBasedPriorities, flexibleMatrix, flexibleBackwardTransitions, b, storm::storage::BitVector(x.size(), true));
|
|
|
|
// Create a state eliminator to perform the actual elimination.
|
|
PrioritizedStateEliminator<ValueType> eliminator(flexibleMatrix, flexibleBackwardTransitions, priorityQueue, x);
|
|
|
|
// Eliminate all states.
|
|
while (priorityQueue->hasNext()) {
|
|
auto state = priorityQueue->pop();
|
|
eliminator.eliminateState(state, false);
|
|
}
|
|
|
|
// After having solved the system, we need to revert the transition system if we kept it local.
|
|
if (localA) {
|
|
localA->convertToEquationSystem();
|
|
};
|
|
}
|
|
|
|
template<typename ValueType>
|
|
void EliminationLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const {
|
|
if (&x != &result) {
|
|
A->multiplyWithVector(x, result);
|
|
if (b != nullptr) {
|
|
storm::utility::vector::addVectors(result, *b, result);
|
|
}
|
|
} else {
|
|
// If the two vectors are aliases, we need to create a temporary.
|
|
std::vector<ValueType> tmp(result.size());
|
|
A->multiplyWithVector(x, tmp);
|
|
if (b != nullptr) {
|
|
storm::utility::vector::addVectors(tmp, *b, result);
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename ValueType>
|
|
EliminationLinearEquationSolverSettings<ValueType>& EliminationLinearEquationSolver<ValueType>::getSettings() {
|
|
return settings;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
EliminationLinearEquationSolverSettings<ValueType> const& EliminationLinearEquationSolver<ValueType>::getSettings() const {
|
|
return settings;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
uint64_t EliminationLinearEquationSolver<ValueType>::getMatrixRowCount() const {
|
|
return this->A->getRowCount();
|
|
}
|
|
|
|
template<typename ValueType>
|
|
uint64_t EliminationLinearEquationSolver<ValueType>::getMatrixColumnCount() const {
|
|
return this->A->getColumnCount();
|
|
}
|
|
|
|
template<typename ValueType>
|
|
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> EliminationLinearEquationSolverFactory<ValueType>::create(storm::storage::SparseMatrix<ValueType> const& matrix) const {
|
|
return std::make_unique<storm::solver::EliminationLinearEquationSolver<ValueType>>(matrix, settings);
|
|
}
|
|
|
|
template<typename ValueType>
|
|
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> EliminationLinearEquationSolverFactory<ValueType>::create(storm::storage::SparseMatrix<ValueType>&& matrix) const {
|
|
return std::make_unique<storm::solver::EliminationLinearEquationSolver<ValueType>>(std::move(matrix), settings);
|
|
}
|
|
|
|
template<typename ValueType>
|
|
EliminationLinearEquationSolverSettings<ValueType>& EliminationLinearEquationSolverFactory<ValueType>::getSettings() {
|
|
return settings;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
EliminationLinearEquationSolverSettings<ValueType> const& EliminationLinearEquationSolverFactory<ValueType>::getSettings() const {
|
|
return settings;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
std::unique_ptr<LinearEquationSolverFactory<ValueType>> EliminationLinearEquationSolverFactory<ValueType>::clone() const {
|
|
return std::make_unique<EliminationLinearEquationSolverFactory<ValueType>>(*this);
|
|
}
|
|
|
|
template class EliminationLinearEquationSolverSettings<double>;
|
|
template class EliminationLinearEquationSolver<double>;
|
|
template class EliminationLinearEquationSolverFactory<double>;
|
|
|
|
#ifdef STORM_HAVE_CARL
|
|
template class EliminationLinearEquationSolverSettings<storm::RationalNumber>;
|
|
template class EliminationLinearEquationSolverSettings<storm::RationalFunction>;
|
|
|
|
template class EliminationLinearEquationSolver<storm::RationalNumber>;
|
|
template class EliminationLinearEquationSolver<storm::RationalFunction>;
|
|
|
|
template class EliminationLinearEquationSolverFactory<storm::RationalNumber>;
|
|
template class EliminationLinearEquationSolverFactory<storm::RationalFunction>;
|
|
#endif
|
|
}
|
|
}
|
|
|