Browse Source
First steps toward exact linear equation solver
First steps toward exact linear equation solver
Former-commit-id: 669af13b84
tempestpy_adaptions
dehnert
9 years ago
8 changed files with 260 additions and 6 deletions
-
9src/adapters/CarlAdapter.h
-
62src/solver/EliminationLinearEquationSolver.cpp
-
34src/solver/EliminationLinearEquationSolver.h
-
2src/solver/NativeLinearEquationSolver.h
-
88src/storage/FlexibleSparseMatrix.cpp
-
65src/storage/FlexibleSparseMatrix.h
-
4src/storage/expressions/ToRationalFunctionVisitor.cpp
-
2src/utility/vector.h
@ -0,0 +1,62 @@ |
|||||
|
#include "src/solver/EliminationLinearEquationSolver.h"
|
||||
|
|
||||
|
#include "src/utility/vector.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace solver { |
||||
|
template<typename ValueType> |
||||
|
EliminationLinearEquationSolver<ValueType>::EliminationLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : A(A) { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void EliminationLinearEquationSolver<ValueType>::solveEquationSystem(std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult) const { |
||||
|
// TODO: implement state-elimination here.
|
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void EliminationLinearEquationSolver<ValueType>::performMatrixVectorMultiplication(std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n, std::vector<ValueType>* multiplyResult) const { |
||||
|
// Set up some temporary variables so that we can just swap pointers instead of copying the result after
|
||||
|
// each iteration.
|
||||
|
std::vector<ValueType>* currentX = &x; |
||||
|
|
||||
|
bool multiplyResultProvided = true; |
||||
|
std::vector<ValueType>* nextX = multiplyResult; |
||||
|
if (nextX == nullptr) { |
||||
|
nextX = new std::vector<ValueType>(x.size()); |
||||
|
multiplyResultProvided = false; |
||||
|
} |
||||
|
std::vector<ValueType> const* copyX = nextX; |
||||
|
|
||||
|
// Now perform matrix-vector multiplication as long as we meet the bound.
|
||||
|
for (uint_fast64_t i = 0; i < n; ++i) { |
||||
|
A.multiplyWithVector(*currentX, *nextX); |
||||
|
std::swap(nextX, currentX); |
||||
|
|
||||
|
// If requested, add an offset to the current result vector.
|
||||
|
if (b != nullptr) { |
||||
|
storm::utility::vector::addVectors(*currentX, *b, *currentX); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// If we performed an odd number of repetitions, we need to swap the contents of currentVector and x,
|
||||
|
// because the output is supposed to be stored in the input vector x.
|
||||
|
if (currentX == copyX) { |
||||
|
std::swap(x, *currentX); |
||||
|
} |
||||
|
|
||||
|
// If the vector for the temporary multiplication result was not provided, we need to delete it.
|
||||
|
if (!multiplyResultProvided) { |
||||
|
delete copyX; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template class EliminationLinearEquationSolver<double>; |
||||
|
|
||||
|
// TODO: make this work with the proper implementation of solveEquationSystem.
|
||||
|
template class EliminationLinearEquationSolver<storm::RationalNumber>; |
||||
|
template class EliminationLinearEquationSolver<storm::RationalFunction>; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,34 @@ |
|||||
|
#ifndef STORM_SOLVER_ELIMINATIONLINEAREQUATIONSOLVER_H_ |
||||
|
#define STORM_SOLVER_ELIMINATIONLINEAREQUATIONSOLVER_H_ |
||||
|
|
||||
|
#include "src/solver/LinearEquationSolver.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace solver { |
||||
|
/*! |
||||
|
* A class that uses gaussian elimination to implement the LinearEquationSolver interface. In particular |
||||
|
*/ |
||||
|
template<typename ValueType> |
||||
|
class EliminationLinearEquationSolver : public LinearEquationSolver<ValueType> { |
||||
|
public: |
||||
|
|
||||
|
/*! |
||||
|
* Constructs a linear equation solver. |
||||
|
* |
||||
|
* @param A The matrix defining the coefficients of the linear equation system. |
||||
|
*/ |
||||
|
EliminationLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); |
||||
|
|
||||
|
virtual void solveEquationSystem(std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult = nullptr) const override; |
||||
|
|
||||
|
virtual void performMatrixVectorMultiplication(std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n = 1, std::vector<ValueType>* multiplyResult = nullptr) const override; |
||||
|
|
||||
|
private: |
||||
|
// A reference to the original matrix used for this equation solver. |
||||
|
storm::storage::SparseMatrix<ValueType> const& A; |
||||
|
|
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif /* STORM_SOLVER_ELIMINATIONLINEAREQUATIONSOLVER_H_ */ |
@ -0,0 +1,88 @@ |
|||||
|
#include "src/storage/FlexibleSparseMatrix.h"
|
||||
|
|
||||
|
#include "src/storage/SparseMatrix.h"
|
||||
|
#include "src/storage/BitVector.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace storage { |
||||
|
template<typename ValueType> |
||||
|
FlexibleSparseMatrix<ValueType>::FlexibleSparseMatrix(index_type rows) : data(rows) { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void FlexibleSparseMatrix<ValueType>::reserveInRow(index_type row, index_type numberOfElements) { |
||||
|
this->data[row].reserve(numberOfElements); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
typename FlexibleSparseMatrix<ValueType>::row_type& FlexibleSparseMatrix<ValueType>::getRow(index_type index) { |
||||
|
return this->data[index]; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
typename FlexibleSparseMatrix<ValueType>::row_type const& FlexibleSparseMatrix<ValueType>::getRow(index_type index) const { |
||||
|
return this->data[index]; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
typename FlexibleSparseMatrix<ValueType>::index_type FlexibleSparseMatrix<ValueType>::getNumberOfRows() const { |
||||
|
return this->data.size(); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
bool FlexibleSparseMatrix<ValueType>::hasSelfLoop(storm::storage::sparse::state_type state) { |
||||
|
for (auto const& entry : this->getRow(state)) { |
||||
|
if (entry.getColumn() < state) { |
||||
|
continue; |
||||
|
} else if (entry.getColumn() > state) { |
||||
|
return false; |
||||
|
} else if (entry.getColumn() == state) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void FlexibleSparseMatrix<ValueType>::print() const { |
||||
|
for (uint_fast64_t index = 0; index < this->data.size(); ++index) { |
||||
|
std::cout << index << " - "; |
||||
|
for (auto const& element : this->getRow(index)) { |
||||
|
std::cout << "(" << element.getColumn() << ", " << element.getValue() << ") "; |
||||
|
} |
||||
|
std::cout << std::endl; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
bool FlexibleSparseMatrix<ValueType>::empty() const { |
||||
|
for (auto const& row : this->data) { |
||||
|
if (!row.empty()) { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void FlexibleSparseMatrix<ValueType>::filter(storm::storage::BitVector const& rowFilter, storm::storage::BitVector const& columnFilter) { |
||||
|
for (uint_fast64_t rowIndex = 0; rowIndex < this->data.size(); ++rowIndex) { |
||||
|
auto& row = this->data[rowIndex]; |
||||
|
if (!rowFilter.get(rowIndex)) { |
||||
|
row.clear(); |
||||
|
row.shrink_to_fit(); |
||||
|
continue; |
||||
|
} |
||||
|
row_type newRow; |
||||
|
for (auto const& element : row) { |
||||
|
if (columnFilter.get(element.getColumn())) { |
||||
|
newRow.push_back(element); |
||||
|
} |
||||
|
} |
||||
|
row = std::move(newRow); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,65 @@ |
|||||
|
#ifndef STORM_STORAGE_FLEXIBLESPARSEMATRIX_H_ |
||||
|
#define STORM_STORAGE_FLEXIBLESPARSEMATRIX_H_ |
||||
|
|
||||
|
#include <cstdint> |
||||
|
#include <vector> |
||||
|
|
||||
|
#include "src/storage/sparse/StateType.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace storage { |
||||
|
template <typename IndexType, typename ValueType> |
||||
|
class MatrixEntry; |
||||
|
|
||||
|
class BitVector; |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
class FlexibleSparseMatrix { |
||||
|
public: |
||||
|
// TODO: make this class a bit more consistent with the big sparse matrix and improve it: |
||||
|
// * rename getNumberOfRows -> getRowCount |
||||
|
// * store number of columns to also provide getColumnCount |
||||
|
// * rename hasSelfLoop -> rowHasDiagonalElement |
||||
|
// * add output iterator and improve the way the matrix is printed |
||||
|
// * add conversion functionality from/to sparse matrix |
||||
|
// * add documentation |
||||
|
// * rename filter to something more appropriate (getSubmatrix?) |
||||
|
// * add stuff like clearRow, multiplyRowWithScalar |
||||
|
|
||||
|
typedef uint_fast64_t index_type; |
||||
|
typedef ValueType value_type; |
||||
|
typedef std::vector<storm::storage::MatrixEntry<index_type, value_type>> row_type; |
||||
|
typedef typename row_type::iterator iterator; |
||||
|
typedef typename row_type::const_iterator const_iterator; |
||||
|
|
||||
|
FlexibleSparseMatrix() = default; |
||||
|
FlexibleSparseMatrix(index_type rows); |
||||
|
|
||||
|
void reserveInRow(index_type row, index_type numberOfElements); |
||||
|
|
||||
|
row_type& getRow(index_type); |
||||
|
row_type const& getRow(index_type) const; |
||||
|
|
||||
|
index_type getNumberOfRows() const; |
||||
|
|
||||
|
void print() const; |
||||
|
|
||||
|
bool empty() const; |
||||
|
|
||||
|
void filter(storm::storage::BitVector const& rowFilter, storm::storage::BitVector const& columnFilter); |
||||
|
|
||||
|
/*! |
||||
|
* Checks whether the given state has a self-loop with an arbitrary probability in the probability matrix. |
||||
|
* |
||||
|
* @param state The state for which to check whether it possesses a self-loop. |
||||
|
* @return True iff the given state has a self-loop with an arbitrary probability in the probability matrix. |
||||
|
*/ |
||||
|
bool hasSelfLoop(storm::storage::sparse::state_type state); |
||||
|
|
||||
|
private: |
||||
|
std::vector<row_type> data; |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif /* STORM_STORAGE_FLEXIBLESPARSEMATRIX_H_ */ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue