Browse Source

Fixed the Jacobi Decomposition in the Matrix, Diagonal Matrix was not inverted.

Implemented solveLinearEquationSystemWithJacobi for GMM based Solver.
tempestpy_adaptions
PBerger 12 years ago
parent
commit
d4b5a24757
  1. 66
      src/modelChecker/GmmxxDtmcPrctlModelChecker.h
  2. 6
      src/storage/SparseMatrix.h

66
src/modelChecker/GmmxxDtmcPrctlModelChecker.h

@ -18,6 +18,7 @@
#include "src/utility/Settings.h"
#include "src/adapters/GmmxxAdapter.h"
#include "src/exceptions/InvalidPropertyException.h"
#include "src/storage/JacobiDecomposition.h"
#include "gmm/gmm_matrix.h"
#include "gmm/gmm_iter_solvers.h"
@ -260,7 +261,8 @@ public:
// Check whether there are states for which we have to compute the result.
storm::storage::BitVector maybeStates = ~(*targetStates) & ~infinityStates;
if (maybeStates.getNumberOfSetBits() > 0) {
const int maybeStatesSetBitCount = maybeStates.getNumberOfSetBits();
if (maybeStatesSetBitCount > 0) {
// Now we can eliminate the rows and columns from the original transition probability matrix.
storm::storage::SparseMatrix<Type>* submatrix = this->getModel().getTransitionProbabilityMatrix()->getSubmatrix(maybeStates);
// Converting the matrix from the fixpoint notation to the form needed for the equation
@ -273,10 +275,10 @@ public:
// Initialize the x vector with 1 for each element. This is the initial guess for
// the iterative solvers.
std::vector<Type> x(maybeStates.getNumberOfSetBits(), storm::utility::constGetOne<Type>());
std::vector<Type> x(maybeStatesSetBitCount, storm::utility::constGetOne<Type>());
// Prepare the right-hand side of the equation system.
std::vector<Type>* b = new std::vector<Type>(maybeStates.getNumberOfSetBits());
std::vector<Type>* b = new std::vector<Type>(maybeStatesSetBitCount);
if (this->getModel().hasTransitionRewards()) {
// If a transition-based reward model is available, we initialize the right-hand
// side to the vector resulting from summing the rows of the pointwise product
@ -290,7 +292,7 @@ public:
// as well. As the state reward vector contains entries not just for the states
// that we still consider (i.e. maybeStates), we need to extract these values
// first.
std::vector<Type>* subStateRewards = new std::vector<Type>(maybeStates.getNumberOfSetBits());
std::vector<Type>* subStateRewards = new std::vector<Type>(maybeStatesSetBitCount);
storm::utility::setVectorValues(subStateRewards, maybeStates, *this->getModel().getStateRewards());
gmm::add(*subStateRewards, *b);
delete subStateRewards;
@ -445,6 +447,62 @@ private:
LOG4CPLUS_WARN(logger, "Iterative solver did not converge.");
}
}
/*!
* Solves the linear equation system Ax=b with the given parameters
* using the Jacobi Method and therefor the Jacobi Decomposition of A.
*
* @param A The matrix A specifying the coefficients of the linear equations.
* @param x The vector x for which to solve the equations. The initial value of the elements of
* this vector are used as the initial guess and might thus influence performance and convergence.
* @param b The vector b specifying the values on the right-hand-sides of the equations.
* @return The solution of the system of linear equations in form of the elements of the vector
* x.
*/
void solveLinearEquationSystemWithJacobi(storm::storage::SparseMatrix<Type> const& A, std::vector<Type>& x, std::vector<Type> const& b) const {
double precision = s->get<double>("precision");
if (precision <= 0) {
LOG4CPLUS_ERROR(logger, "Precision is not greater Zero");
}
// Get a Jacobi Decomposition of the Input Matrix A
storm::storage::JacobiDecomposition<Type>* jacobiDecomposition = A.getJacobiDecomposition();
// Convert the Diagonal matrix to GMM format
gmm::csr_matrix<Type>* gmmxxDiagonalInverted = storm::adapters::GmmxxAdapter::toGmmxxSparseMatrix<Type>(jacobiDecomposition->getJacobiDInv());
// Convert the LU Matrix to GMM format
gmm::csr_matrix<Type>* gmmxxLU = storm::adapters::GmmxxAdapter::toGmmxxSparseMatrix<Type>(jacobiDecomposition->getJacobiLU());
delete jacobiDecomposition;
LOG4CPLUS_INFO(logger, "Starting iterative Jacobi Solver.");
// x_(k + 1) = D^-1 * (b - R * x_k)
std::vector<Type>* xNext = new std::vector<Type>(x.size());
const std::vector<Type>* xCopy = xNext;
std::vector<Type>* xCurrent = &x;
uint_fast64_t iterationCount = 0;
do {
// R * x_k -> xCurrent
gmm::mult(*gmmxxLU, *xCurrent, *xNext);
// b - R * x_k
gmm::add(b, gmm::scaled(*xNext, -1.0), *xNext);
// D^-1 * (b - R * x_k)
gmm::mult(*gmmxxDiagonalInverted, *xNext, *xNext);
std::vector<Type>* swap = xNext;
xNext = xCurrent;
xCurrent = swap;
++iterationCount;
} while (gmm::vect_norminf(*xCurrent) > precision);
delete xCopy;
LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterationCount << " iterations.");
}
};
} //namespace modelChecker

6
src/storage/SparseMatrix.h

@ -841,9 +841,13 @@ public:
SparseMatrix<T> *resultDinv = new SparseMatrix<T>(rowCount);
// no entries apart from those on the diagonal
resultDinv->initialize(0);
// constant 1 for diagonal inversion
T constOne = storm::utility::constGetOne<T>();
// copy diagonal entries to other matrix
for (int i = 0; i < rowCount; ++i) {
resultDinv->addNextValue(i, i, resultLU->getValue(i, i));
resultDinv->addNextValue(i, i, constOne / resultLU->getValue(i, i));
resultLU->getValue(i, i) = storm::utility::constGetZero<T>();
}
Loading…
Cancel
Save