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.
143 lines
5.1 KiB
143 lines
5.1 KiB
/*
|
|
* EigenDtmcPrctlModelChecker.h
|
|
*
|
|
* Created on: 07.12.2012
|
|
* Author:
|
|
*/
|
|
|
|
#ifndef STORM_MODELCHECKER_EIGENDTMCPRCTLMODELCHECKER_H_
|
|
#define STORM_MODELCHECKER_EIGENDTMCPRCTLMODELCHECKER_H_
|
|
|
|
#include "src/utility/Vector.h"
|
|
|
|
#include "src/models/Dtmc.h"
|
|
#include "src/modelchecker/DtmcPrctlModelChecker.h"
|
|
#include "src/utility/GraphAnalyzer.h"
|
|
#include "src/utility/ConstTemplates.h"
|
|
#include "src/exceptions/NoConvergenceException.h"
|
|
|
|
#include "Eigen/Sparse"
|
|
#include "Eigen/src/IterativeLinearSolvers/BiCGSTAB.h"
|
|
#include "src/adapters/EigenAdapter.h"
|
|
|
|
#include "gmm/gmm_matrix.h"
|
|
#include "gmm/gmm_iter_solvers.h"
|
|
|
|
#include "log4cplus/logger.h"
|
|
#include "log4cplus/loggingmacros.h"
|
|
|
|
extern log4cplus::Logger logger;
|
|
|
|
namespace storm {
|
|
|
|
namespace modelChecker {
|
|
|
|
/*
|
|
* A model checking engine that makes use of the eigen backend.
|
|
*/
|
|
template <class Type>
|
|
class EigenDtmcPrctlModelChecker : public DtmcPrctlModelChecker<Type> {
|
|
|
|
typedef Eigen::Matrix<Type, -1, 1, 0, -1, 1> VectorType;
|
|
typedef Eigen::Map<VectorType> MapType;
|
|
|
|
public:
|
|
explicit EigenDtmcPrctlModelChecker(storm::models::Dtmc<Type>& dtmc) : DtmcPrctlModelChecker<Type>(dtmc) {
|
|
// Intentionally left empty.
|
|
}
|
|
|
|
virtual ~EigenDtmcPrctlModelChecker() {
|
|
// Intentionally left empty.
|
|
}
|
|
|
|
private:
|
|
virtual void performMatrixVectorMultiplication(storm::storage::SparseMatrix<Type> const& matrix, std::vector<Type>** vector, std::vector<Type>* summand, uint_fast64_t repetitions = 1) const {
|
|
// Transform the transition probability matrix to the eigen format to use its arithmetic.
|
|
Eigen::SparseMatrix<Type, 1, int_fast32_t>* eigenMatrix = storm::adapters::EigenAdapter::toEigenSparseMatrix(matrix);
|
|
|
|
Type* p = &((**vector)[0]); // get the address storing the data for result
|
|
MapType vectorMap(p, (*vector)->size()); // vectorMap shares data
|
|
|
|
p = &((*summand)[0]);
|
|
MapType summandMap(p, summand->size());
|
|
|
|
// Now perform matrix-vector multiplication as long as we meet the bound.
|
|
std::vector<Type>* swap = nullptr;
|
|
std::vector<Type>* tmpResult = new std::vector<Type>(this->getModel().getNumberOfStates());
|
|
for (uint_fast64_t i = 0; i < repetitions; ++i) {
|
|
vectorMap = (*eigenMatrix) * (vectorMap);
|
|
|
|
// If requested, add an offset to the current result vector.
|
|
if (summand != nullptr) {
|
|
vectorMap = vectorMap + summandMap;
|
|
}
|
|
}
|
|
delete eigenMatrix;
|
|
}
|
|
|
|
/*!
|
|
* Solves the linear equation system Ax=b with the given parameters.
|
|
*
|
|
* @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.
|
|
*/
|
|
virtual void solveEquationSystem(storm::storage::SparseMatrix<Type> const& matrix, std::vector<Type>** vector, std::vector<Type>& b) const {
|
|
// Get the settings object to customize linear solving.
|
|
storm::settings::Settings* s = storm::settings::instance();
|
|
|
|
// Transform the submatric matrix to the eigen format to use its solvers
|
|
Eigen::SparseMatrix<Type, 1, int_fast32_t>* eigenMatrix = storm::adapters::EigenAdapter::toEigenSparseMatrix<Type>(matrix);
|
|
|
|
Eigen::BiCGSTAB<Eigen::SparseMatrix<Type, 1, int_fast32_t>> solver;
|
|
solver.compute(*eigenMatrix);
|
|
if(solver.info()!= Eigen::ComputationInfo::Success) {
|
|
// decomposition failed
|
|
LOG4CPLUS_ERROR(logger, "Decomposition of matrix failed!");
|
|
}
|
|
solver.setMaxIterations(s->get<unsigned>("maxiter"));
|
|
solver.setTolerance(s->get<double>("precision"));
|
|
|
|
std::cout << matrix.toString(nullptr) << std::endl;
|
|
std::cout << **vector << std::endl;
|
|
std::cout << b << std::endl;
|
|
|
|
std::cout << *eigenMatrix << std::endl;
|
|
|
|
// Map for x
|
|
Type *px = &((**vector)[0]); // get the address storing the data for x
|
|
MapType vectorX(px, (*vector)->size()); // vectorX shares data
|
|
|
|
Type *pb = &(b[0]); // get the address storing the data for b
|
|
MapType vectorB(pb, b.size()); // vectorB shares data
|
|
|
|
vectorX = solver.solveWithGuess(vectorB, vectorX);
|
|
|
|
std::cout << **vector << std::endl;
|
|
|
|
if(solver.info() == Eigen::ComputationInfo::InvalidInput) {
|
|
// solving failed
|
|
LOG4CPLUS_ERROR(logger, "Solving of Submatrix failed: InvalidInput");
|
|
} else if(solver.info() == Eigen::ComputationInfo::NoConvergence) {
|
|
// NoConvergence
|
|
throw storm::exceptions::NoConvergenceException() << "Failed to converge within " << solver.iterations() << " out of a maximum of " << solver.maxIterations() << " iterations.";
|
|
} else if(solver.info() == Eigen::ComputationInfo::NumericalIssue) {
|
|
// NumericalIssue
|
|
LOG4CPLUS_ERROR(logger, "Solving of Submatrix failed: NumericalIssue");
|
|
} else if(solver.info() == Eigen::ComputationInfo::Success) {
|
|
// solving Success
|
|
LOG4CPLUS_INFO(logger, "Solving of Submatrix succeeded: Success");
|
|
}
|
|
|
|
delete eigenMatrix;
|
|
}
|
|
};
|
|
|
|
} //namespace modelChecker
|
|
|
|
} //namespace storm
|
|
|
|
#endif /* STORM_MODELCHECKER_EIGENDTMCPRCTLMODELCHECKER_H_ */
|