From 54ab1c114eb245f39722f56b28dd4f3262e7d9b0 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Fri, 10 Nov 2017 19:46:15 +0100 Subject: [PATCH 01/46] first version of UnifPlus for MA --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 298 +++++++++++++++++- .../helper/SparseMarkovAutomatonCslHelper.h | 62 +++- 2 files changed, 357 insertions(+), 3 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 0bdc633f7..8fdfb3054 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -133,10 +133,304 @@ namespace storm { void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector& markovianNonGoalValues, std::vector& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } + + template ::SupportsExponential, int>::type=0> + void SparseMarkovAutomatonCslHelper::printTransitions(std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, std::vector>& vd, std::vector>& vu, std::vector>& wu){ + std::ofstream logfile("U+logfile.txt", std::ios::app); + + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); + + logfile << "number of states = num of row group count " << numberOfStates << "\n"; + for (int i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + logfile << " from node " << i << " "; + auto from = rowGroupIndices[i]; + auto to = rowGroupIndices[i+1]; + for (auto j = from ; j< to; j++){ + for (auto &v : fullTransitionMatrix.getRow(j)) { + if (markovianStates[i]){ + logfile << v.getValue() *exitRateVector[i] << " -> "<< v.getColumn() << "\t"; + } else { + logfile << v.getValue() << " -> "<< v.getColumn() << "\t"; + } + } + logfile << "\n"; + } + } + logfile << "\n"; + + logfile << "vd: \n"; + for (int i =0 ; i + ValueType SparseMarkovAutomatonCslHelper::poisson(ValueType lambda, uint64_t i) { + ValueType res = pow(lambda, i); + ValueType fac = 1; + for (long j = i ; j>0 ; j--){ + fac = fac *j; + } + res = res / fac ; + res = res * exp(-lambda); + return res; + } + + template ::SupportsExponential, int>::type=0> + void SparseMarkovAutomatonCslHelper::calculateVu(uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. + uint64_t N = vu.size()-1; + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + ValueType res =0; + for (long i = k ; i < N ; i++ ){ + if (wu[N-1-(i-k)][node]==-1){ + calculateWu((N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + } + res+=poisson(lambda, i)*wu[N-1-(i-k)][node]; + } + vu[k][node]=res; + } + + template ::SupportsExponential, int>::type=0> + void SparseMarkovAutomatonCslHelper::calculateWu(uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. + uint64_t N = wu.size()-1; + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + ValueType res; + if (k==N){ + wu[k][node]=0; + return; + } + + if (psiStates[node]){ + wu[k][node]=1; + return; + } + + if (markovianStates[node]){ + res = 0; + auto line = fullTransitionMatrix.getRow(rowGroupIndices[node]); + for (auto &element : line){ + uint64_t to = element.getColumn(); + if (wu[k+1][to]==-1){ + calculateWu(k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + } + res+=element.getValue()*wu[k+1][to]; + } + } else { + res = 0; + uint64_t rowStart = rowGroupIndices[node]; + uint64_t rowEnd = rowGroupIndices[node+1]; + for (uint64_t i = rowStart; i< rowEnd; i++){ + auto line = fullTransitionMatrix.getRow(i); + ValueType between = 0; + for (auto& element: line){ + uint64_t to = element.getColumn(); + if (to==node){ + continue; + } + if (wu[k][to]==-1){ + calculateWu(k,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + } + between+=element.getValue()*wu[k][to]; + } + if (between > res){ + res = between; + } + } + } // end no goal-prob state + wu[k][node]=res; + } + + template ::SupportsExponential, int>::type=0> + void SparseMarkovAutomatonCslHelper::calculateVd(uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + + std::ofstream logfile("U+logfile.txt", std::ios::app); + + if (vd[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. + logfile << "calculating vd for k = " << k << " node "<< node << " \t"; + uint64_t N = vd.size()-1; + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + ValueType res; + if (k==N){ + logfile << "k == N! res = 0\n"; + vd[k][node]=0; + return; + } + + //goal state + if (psiStates[node]){ + res = 0; + for (uint64_t i = k ; i res){ + res = between; + } + } + } + vd[k][node]=res; + logfile << " res = " << res << "\n"; + } + template ::SupportsExponential, int>::type> - std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { + std::vector SparseMarkovAutomatonCslHelper::unifPlus( std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + std::ofstream logfile("U+logfile.txt", std::ios::app); + ValueType maxNorm = 0; + + //bitvectors to identify different kind of states + storm::storage::BitVector const &markovianNonGoalStates = markovianStates & ~psiStates; + storm::storage::BitVector const &probabilisticNonGoalStates = ~markovianStates & ~psiStates; + storm::storage::BitVector const &allStates = markovianStates | ~markovianStates; + + //vectors to save calculation + std::vector> vd,vu,wu; + + //transition matrix with diagonal entries. The values can be changed during uniformisation + typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + std::vector exitRate{exitRateVector}; + + //(1) define horizon, epsilon, kappa , N, lambda, + double T = boundsPair.second; + ValueType kappa = storm::utility::one() /10; // would be better as option-parameter + uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); + ValueType epsilon = storm::settings::getModule().getPrecision(); + ValueType lambda = exitRateVector[0]; + for (ValueType act: exitRateVector) { + lambda = std::max(act, lambda); + } + uint64_t N; + + // while not close enough to precision: + do { + // (2) update parameter + N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); + + // (3) uniform - just applied to markovian states + for (int i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + if (!markovianStates[i]) { + continue; + } + uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row + + if (exitRate[i] == lambda) { + continue; //already unified + } + + auto line = fullTransitionMatrix.getRow(from); + ValueType exitOld = exitRate[i]; + ValueType exitNew = lambda; + for (auto &v : line) { + if (v.getColumn() == i) { //diagonal element + ValueType newSelfLoop = exitNew - exitOld + v.getValue(); + ValueType newRate = newSelfLoop / exitNew; + v.setValue(newRate); + } else { //modify probability + ValueType propOld = v.getValue(); + ValueType propNew = propOld * exitOld / exitNew; + v.setValue(propNew); + } + } + exitRate[i] = exitNew; + } + + // (4) define vectors/matrices + std::vector init(numberOfStates, -1); + vd = std::vector> (N + 1, init); + vu = std::vector> (N + 1, init); + wu = std::vector> (N + 1, init); + + printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when develepmont is finished + + // (5) calculate vectors and maxNorm + for (uint64_t i = 0; i < numberOfStates; i++) { + for (uint64_t k = N; k <= N; k--) { + calculateVd(k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates); + calculateWu(k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates); + calculateVu(k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates); + //also use iteration to keep maxNorm of vd and vu up to date, so the loop-condition is easy to prove + ValueType diff = std::abs(vd[k][i]-vu[k][i]); + maxNorm = std::max(maxNorm, diff); + } + } + printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when development is finished + + + // (6) double lambda + lambda=2*lambda; + + } while (maxNorm>epsilon*(1-kappa)); + return vd[0]; + } + + template ::SupportsExponential, int>::type> + std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { + return unifPlus(boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); + /* uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); // 'Unpack' the bounds to make them more easily accessible. @@ -195,7 +489,7 @@ namespace storm { storm::utility::vector::setVectorValues(result, probabilisticNonGoalStates, vProbabilistic); storm::utility::vector::setVectorValues(result, markovianNonGoalStates, vMarkovian); return result; - } + }*/ } template ::SupportsExponential, int>::type> diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index a90c3a0cf..1dc6dcec5 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -14,7 +14,22 @@ namespace storm { class SparseMarkovAutomatonCslHelper { public: - + + /*! + * Computes TBU according to the UnifPlus algorithm + * + * @param boundsPair With precondition that the first component is 0, the second one gives the time bound + * @param exitRateVector the exit-rates of the given MA + * @param transitionMatrix the transitions of the given MA + * @param markovianStates bitvector refering to the markovian states + * @param psiStates bitvector refering to the goal states + * + * @return the probability vector + * + */ + template ::SupportsExponential, int>::type=0> + static std::vector unifPlus( std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + template ::SupportsExponential, int>::type = 0> static std::vector computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); @@ -38,6 +53,51 @@ namespace storm { static std::vector computeReachabilityTimes(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& backwardTransitions, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); private: + + /*! + * Computes the poission-distribution + * + * + * @param parameter lambda to use + * @param point i + * TODO: replace with Fox-Lynn + * @return the probability + */ + template + static ValueType poisson(ValueType lambda, uint64_t i); + + + /*! + * Computes vd vector according to UnifPlus + * + */ + template ::SupportsExponential, int>::type=0> + static void calculateVd(uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + +/*! + * Computes vu vector according to UnifPlus + * + */ + template ::SupportsExponential, int>::type=0> + static void calculateVu(uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + + + /*! + * Computes wu vector according to UnifPlus + * + */ + template ::SupportsExponential, int>::type=0> + static void calculateWu(uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + + /*! + * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile + * TODO: delete when development is finished + * + */ + + template ::SupportsExponential, int>::type=0> + static void printTransitions(std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,std::vector>& vd, std::vector>& vu, std::vector>& wu); + template ::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector& markovianNonGoalValues, std::vector& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); From a6046ab0b31c12d571b003f764afb0ab2cbad5fd Mon Sep 17 00:00:00 2001 From: dehnert Date: Sat, 11 Nov 2017 12:51:51 +0100 Subject: [PATCH 02/46] fixed some warnings and issues and introduce cli switch to select IMCA or UnifPlus --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 69 ++++++++++++------- .../helper/SparseMarkovAutomatonCslHelper.h | 3 + src/storm/settings/SettingsManager.cpp | 2 + .../modules/MarkovAutomatonSettings.cpp | 32 +++++++++ .../modules/MarkovAutomatonSettings.h | 38 ++++++++++ src/storm/settings/modules/SylvanSettings.h | 2 +- 6 files changed, 119 insertions(+), 27 deletions(-) create mode 100644 src/storm/settings/modules/MarkovAutomatonSettings.cpp create mode 100644 src/storm/settings/modules/MarkovAutomatonSettings.h diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 8fdfb3054..20f15344b 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -10,6 +10,7 @@ #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" +#include "storm/settings/modules/MarkovAutomatonSettings.h" #include "storm/utility/macros.h" #include "storm/utility/vector.h" @@ -134,19 +135,19 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } - template ::SupportsExponential, int>::type=0> + template ::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::printTransitions(std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, std::vector>& vd, std::vector>& vu, std::vector>& wu){ std::ofstream logfile("U+logfile.txt", std::ios::app); - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); logfile << "number of states = num of row group count " << numberOfStates << "\n"; - for (int i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { logfile << " from node " << i << " "; auto from = rowGroupIndices[i]; auto to = rowGroupIndices[i+1]; - for (auto j = from ; j< to; j++){ + for (auto j = from ; j < to; j++){ for (auto &v : fullTransitionMatrix.getRow(j)) { if (markovianStates[i]){ logfile << v.getValue() *exitRateVector[i] << " -> "<< v.getColumn() << "\t"; @@ -160,24 +161,24 @@ namespace storm { logfile << "\n"; logfile << "vd: \n"; - for (int i =0 ; i::SupportsExponential, int>::type=0> + template ::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::calculateVu(uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = vu.size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res =0; - for (long i = k ; i < N ; i++ ){ + for (uint_fast64_t i = k ; i < N ; i++ ){ if (wu[N-1-(i-k)][node]==-1){ calculateWu((N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); } @@ -214,11 +215,11 @@ namespace storm { vu[k][node]=res; } - template ::SupportsExponential, int>::type=0> + template ::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::calculateWu(uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = wu.size()-1; - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res; if (k==N){ @@ -267,7 +268,7 @@ namespace storm { wu[k][node]=res; } - template ::SupportsExponential, int>::type=0> + template ::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::calculateVd(uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -275,7 +276,7 @@ namespace storm { if (vd[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. logfile << "calculating vd for k = " << k << " node "<< node << " \t"; uint64_t N = vd.size()-1; - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res; if (k==N){ @@ -337,13 +338,15 @@ namespace storm { template ::SupportsExponential, int>::type> std::vector SparseMarkovAutomatonCslHelper::unifPlus( std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = 0; //bitvectors to identify different kind of states - storm::storage::BitVector const &markovianNonGoalStates = markovianStates & ~psiStates; - storm::storage::BitVector const &probabilisticNonGoalStates = ~markovianStates & ~psiStates; - storm::storage::BitVector const &allStates = markovianStates | ~markovianStates; +// storm::storage::BitVector const &markovianNonGoalStates = markovianStates & ~psiStates; +// storm::storage::BitVector const &probabilisticNonGoalStates = ~markovianStates & ~psiStates; + storm::storage::BitVector allStates(markovianStates.size(), true); //vectors to save calculation std::vector> vd,vu,wu; @@ -371,7 +374,7 @@ namespace storm { N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); // (3) uniform - just applied to markovian states - for (int i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { if (!markovianStates[i]) { continue; } @@ -428,15 +431,15 @@ namespace storm { } template ::SupportsExponential, int>::type> - std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { - return unifPlus(boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); - /* + std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilitiesImca(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { + STORM_LOG_TRACE("Using IMCA's technique to compute bounded until probabilities."); + uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); - + // 'Unpack' the bounds to make them more easily accessible. double lowerBound = boundsPair.first; double upperBound = boundsPair.second; - + // (1) Compute the accuracy we need to achieve the required error bound. ValueType maxExitRate = 0; for (auto value : exitRateVector) { @@ -489,7 +492,21 @@ namespace storm { storm::utility::vector::setVectorValues(result, probabilisticNonGoalStates, vProbabilistic); storm::utility::vector::setVectorValues(result, markovianNonGoalStates, vMarkovian); return result; - }*/ + } + } + + template ::SupportsExponential, int>::type> + std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { + + auto const& markovAutomatonSettings = storm::settings::getModule(); + if (markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::Imca) { + return computeBoundedUntilProbabilitiesImca(dir, transitionMatrix, exitRateVector, markovianStates, psiStates, boundsPair, minMaxLinearEquationSolverFactory); + } else { + STORM_LOG_ASSERT(markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus, "Unknown solution technique."); + + // Why is optimization direction not passed? + return unifPlus(boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); + } } template ::SupportsExponential, int>::type> diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 1dc6dcec5..ff27180bd 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -33,6 +33,9 @@ namespace storm { template ::SupportsExponential, int>::type = 0> static std::vector computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); + template ::SupportsExponential, int>::type = 0> + static std::vector computeBoundedUntilProbabilitiesImca(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); + template ::SupportsExponential, int>::type = 0> static std::vector computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 188d1cba2..38e5ff10a 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -37,6 +37,7 @@ #include "storm/settings/modules/JaniExportSettings.h" #include "storm/settings/modules/JitBuilderSettings.h" #include "storm/settings/modules/MultiObjectiveSettings.h" +#include "storm/settings/modules/MarkovAutomatonSettings.h" #include "storm/utility/macros.h" #include "storm/utility/file.h" #include "storm/settings/Option.h" @@ -534,6 +535,7 @@ namespace storm { storm::settings::addModule(); storm::settings::addModule(); storm::settings::addModule(); + storm::settings::addModule(); } } diff --git a/src/storm/settings/modules/MarkovAutomatonSettings.cpp b/src/storm/settings/modules/MarkovAutomatonSettings.cpp new file mode 100644 index 000000000..470de708f --- /dev/null +++ b/src/storm/settings/modules/MarkovAutomatonSettings.cpp @@ -0,0 +1,32 @@ +#include "storm/settings/modules/MarkovAutomatonSettings.h" + +#include "storm/settings/Option.h" +#include "storm/settings/OptionBuilder.h" +#include "storm/settings/ArgumentBuilder.h" +#include "storm/settings/Argument.h" + +#include "storm/settings/SettingsManager.h" + +namespace storm { + namespace settings { + namespace modules { + + const std::string MarkovAutomatonSettings::moduleName = "ma"; + const std::string MarkovAutomatonSettings::techniqueOptionName = "technique"; + + MarkovAutomatonSettings::MarkovAutomatonSettings() : ModuleSettings(moduleName) { + std::vector techniques = {"imca", "unifplus"}; + this->addOption(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The technique to use to solve bounded reachability queries.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the technique to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(techniques)).setDefaultValueString("imca").build()).build()); + } + + MarkovAutomatonSettings::BoundedReachabilityTechnique MarkovAutomatonSettings::getTechnique() const { + std::string techniqueAsString = this->getOption(techniqueOptionName).getArgumentByName("name").getValueAsString(); + if (techniqueAsString == "imca") { + return MarkovAutomatonSettings::BoundedReachabilityTechnique::Imca; + } + return MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus; + } + + } + } +} diff --git a/src/storm/settings/modules/MarkovAutomatonSettings.h b/src/storm/settings/modules/MarkovAutomatonSettings.h new file mode 100644 index 000000000..60cdaa1b4 --- /dev/null +++ b/src/storm/settings/modules/MarkovAutomatonSettings.h @@ -0,0 +1,38 @@ +#pragma once + +#include "storm/settings/modules/ModuleSettings.h" + +namespace storm { + namespace settings { + namespace modules { + + /*! + * This class represents the settings for Sylvan. + */ + class MarkovAutomatonSettings : public ModuleSettings { + public: + enum class BoundedReachabilityTechnique { Imca, UnifPlus }; + + /*! + * Creates a new set of Markov automaton settings. + */ + MarkovAutomatonSettings(); + + /*! + * Retrieves the technique to use to solve bounded reachability properties. + * + * @return The selected technique. + */ + BoundedReachabilityTechnique getTechnique() const; + + // The name of the module. + static const std::string moduleName; + + private: + // Define the string names of the options as constants. + static const std::string techniqueOptionName; + }; + + } + } +} diff --git a/src/storm/settings/modules/SylvanSettings.h b/src/storm/settings/modules/SylvanSettings.h index b4eed806b..b218cbdfc 100644 --- a/src/storm/settings/modules/SylvanSettings.h +++ b/src/storm/settings/modules/SylvanSettings.h @@ -13,7 +13,7 @@ namespace storm { class SylvanSettings : public ModuleSettings { public: /*! - * Creates a new set of CUDD settings. + * Creates a new set of Sylvan settings. */ SylvanSettings(); From fc28fd16d3f755c44333a9d45a01183fb6cd65c6 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Mon, 13 Nov 2017 23:25:02 +0100 Subject: [PATCH 03/46] delete self loops for probabilistic states --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 8fdfb3054..85906f8bc 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -190,7 +190,7 @@ namespace storm { ValueType SparseMarkovAutomatonCslHelper::poisson(ValueType lambda, uint64_t i) { ValueType res = pow(lambda, i); ValueType fac = 1; - for (long j = i ; j>0 ; j--){ + for (uint64_t j = i ; j>0 ; j--){ fac = fac *j; } res = res / fac ; @@ -205,7 +205,7 @@ namespace storm { auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res =0; - for (long i = k ; i < N ; i++ ){ + for (uint64_t i = k ; i < N ; i++ ){ if (wu[N-1-(i-k)][node]==-1){ calculateWu((N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); } @@ -286,9 +286,10 @@ namespace storm { //goal state if (psiStates[node]){ - res = 0; + res = storm::utility::zero(); for (uint64_t i = k ; i> vd,vu,wu; //transition matrix with diagonal entries. The values can be changed during uniformisation + std::vector exitRate{exitRateVector}; typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - std::vector exitRate{exitRateVector}; + + //delete prob-diagonal entries + for (uint64_t i =0; i() /10; // would be better as option-parameter - uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); ValueType epsilon = storm::settings::getModule().getPrecision(); ValueType lambda = exitRateVector[0]; for (ValueType act: exitRateVector) { From 25a7b6c71a652b067af212cd2cecde7e1748e1ee Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sun, 19 Nov 2017 12:20:54 +0100 Subject: [PATCH 04/46] implemented trajans alg to identify prob Cycles --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 74 ++++++++++++++++++- .../helper/SparseMarkovAutomatonCslHelper.h | 15 ++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 8c3d33fc2..88d470dce 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -337,10 +337,82 @@ namespace storm { logfile << " res = " << res << "\n"; } + template ::SupportsExponential, int>::type=0> + int SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix const& transitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t* counter) { + auto const &rowGroupIndice = transitionMatrix.getRowGroupIndices(); + + disc[node] = *counter; + finish[node] = *counter; + (*counter)+=1; + + auto from = rowGroupIndice[node]; + auto to = rowGroupIndice[node+1]; + + for(uint64_t i =from; i::SupportsExponential, int>::type=0> + storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCycles(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + + storm::storage::BitVector const& probabilisticStates = ~markovianStates; + storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~psiStates; + + storm::storage::SparseMatrix const& probMatrix = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, probabilisticNonGoalStates); + uint64_t probSize = probMatrix.getRowGroupCount(); + std::vector disc(probSize, 0), finish(probSize, 0); + + uint64_t counter =1; + + for (uint64_t i =0; i::SupportsExponential, int>::type> std::vector SparseMarkovAutomatonCslHelper::unifPlus( std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - + + storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~psiStates; + auto cycleStates = identifyProbCycles(transitionMatrix, markovianStates, psiStates); + + for (int i=0 ; i < cycleStates.size() ; i++ ){ + std::cout << cycleStates[i] << "\t" << probabilisticNonGoalStates[i] <<"\n"; + } std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = 0; diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index ff27180bd..559912c2e 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -56,7 +56,20 @@ namespace storm { static std::vector computeReachabilityTimes(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& backwardTransitions, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); private: + static uint64_t transformIndice(storm::storage::BitVector const& subset, uint64_t fakeId){ + uint64_t id =0; + uint64_t counter =0; + while(counter<=fakeId){ + if(subset[id]){ + counter++; + } + id++; + } + return id-1; + } + template ::SupportsExponential, int>::type=0> + static storm::storage::BitVector identifyProbCycles(storm::storage::SparseMatrix const& TransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); /*! * Computes the poission-distribution * @@ -69,6 +82,8 @@ namespace storm { template static ValueType poisson(ValueType lambda, uint64_t i); + template ::SupportsExponential, int>::type=0> + static int trajans(storm::storage::SparseMatrix const& TransitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t * counter); /*! * Computes vd vector according to UnifPlus From 250fc89bc67b6d8f742e1b516fc84bfdb136793b Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sun, 19 Nov 2017 14:01:54 +0100 Subject: [PATCH 05/46] new also supporting Pmin --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 52 ++++++++++++------- .../helper/SparseMarkovAutomatonCslHelper.h | 8 +-- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 8c3d33fc2..b03b8cb39 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -200,15 +200,15 @@ namespace storm { } template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateVu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = vu.size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - + ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (wu[N-1-(i-k)][node]==-1){ - calculateWu((N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + calculateWu(dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); } res+=poisson(lambda, i)*wu[N-1-(i-k)][node]; } @@ -216,10 +216,10 @@ namespace storm { } template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateWu(uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateWu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = wu.size()-1; - auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices( ); ValueType res; if (k==N){ @@ -238,12 +238,12 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (wu[k+1][to]==-1){ - calculateWu(k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + calculateWu(dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); } res+=element.getValue()*wu[k+1][to]; } } else { - res = 0; + res = -1; uint64_t rowStart = rowGroupIndices[node]; uint64_t rowEnd = rowGroupIndices[node+1]; for (uint64_t i = rowStart; i< rowEnd; i++){ @@ -255,12 +255,18 @@ namespace storm { continue; } if (wu[k][to]==-1){ - calculateWu(k,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + calculateWu(dir, k,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); } between+=element.getValue()*wu[k][to]; } - if (between > res){ - res = between; + if (maximize(dir)){ + res = std::max(res,between); + } else { + if (res!=-1){ + res = std::min(res,between); + } else { + res = between; + } } } } // end no goal-prob state @@ -269,7 +275,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVd(uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateVd(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -305,13 +311,13 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (vd[k+1][to]==-1){ - calculateVd(k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); + calculateVd(dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); } res+=element.getValue()*vd[k+1][to]; } } else { //no-goal prob state logfile << "prob state: "; - res = 0; + res = -1; uint64_t rowStart = rowGroupIndices[node]; uint64_t rowEnd = rowGroupIndices[node+1]; for (uint64_t i = rowStart; i< rowEnd; i++){ @@ -324,12 +330,18 @@ namespace storm { continue; } if (vd[k][to]==-1){ - calculateVd(k,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); + calculateVd(dir, k,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); } between+=element.getValue()*vd[k][to]; } - if (between > res){ + if (maximize(dir)){ + res = std::max(res, between); + } else { + if (res!=-1){ + res =std::min(res,between); + } else { res = between; + } } } } @@ -338,7 +350,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - std::vector SparseMarkovAutomatonCslHelper::unifPlus( std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -441,9 +453,9 @@ namespace storm { // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateVd(k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates); - calculateWu(k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates); - calculateVu(k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates); + calculateVd(dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates); + calculateWu(dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates); + calculateVu(dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates); //also use iteration to keep maxNorm of vd and vu up to date, so the loop-condition is easy to prove ValueType diff = std::abs(vd[k][i]-vu[k][i]); maxNorm = std::max(maxNorm, diff); @@ -534,7 +546,7 @@ namespace storm { STORM_LOG_ASSERT(markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus, "Unknown solution technique."); // Why is optimization direction not passed? - return unifPlus(boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); + return unifPlus(dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index ff27180bd..3346ea93d 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -28,7 +28,7 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static std::vector unifPlus( std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static std::vector unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); template ::SupportsExponential, int>::type = 0> static std::vector computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); @@ -75,14 +75,14 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static void calculateVd(uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateVd(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); /*! * Computes vu vector according to UnifPlus * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateVu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); /*! @@ -90,7 +90,7 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static void calculateWu(uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateWu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile From fe863679bfae91277c45e09b947027508b086882 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sun, 19 Nov 2017 15:26:30 +0100 Subject: [PATCH 06/46] identify probCycles outgoing states --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 47 +++++++++++++++---- .../helper/SparseMarkovAutomatonCslHelper.h | 6 ++- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 88d470dce..54abee155 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -136,7 +136,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::printTransitions(std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, std::vector>& vd, std::vector>& vu, std::vector>& wu){ + void SparseMarkovAutomatonCslHelper::printTransitions(std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector>& vd, std::vector>& vu, std::vector>& wu){ std::ofstream logfile("U+logfile.txt", std::ios::app); auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -160,6 +160,13 @@ namespace storm { } logfile << "\n"; + logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; + for (int i =0 ; i< markovianStates.size() ; i++){ + logfile << (~markovianStates)[i] << "\t" << markovianStates[i] << "\t" << psiStates[i] << "\t" << cycleStates[i] << "\t" << cycleGoalStates[i] << "\n"; + } + + + logfile << "vd: \n"; for (uint_fast64_t i =0 ; i::SupportsExponential, int>::type=0> int SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix const& transitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t* counter) { - auto const &rowGroupIndice = transitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndice = transitionMatrix.getRowGroupIndices(); disc[node] = *counter; finish[node] = *counter; @@ -362,8 +369,31 @@ namespace storm { return finish[node]; } - template ::SupportsExponential, int>::type=0> + storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCyclesGoalStates(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& cycleStates) { + + storm::storage::BitVector goalStates(cycleStates.size(), false); + auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); + + for (uint64_t i = 0 ; i < transitionMatrix.getRowGroupCount() ; i++){ + if (!cycleStates[i]){ + continue; + } + auto from = rowGroupIndices[i]; + auto to = rowGroupIndices[i+1]; + for (auto j = from ; j::SupportsExponential, int>::type=0> storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCycles(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ storm::storage::BitVector const& probabilisticStates = ~markovianStates; @@ -392,7 +422,6 @@ namespace storm { auto f = finish[i]; for (int j =i; j SparseMarkovAutomatonCslHelper::unifPlus( std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~psiStates; auto cycleStates = identifyProbCycles(transitionMatrix, markovianStates, psiStates); + auto cycleGoals = identifyProbCyclesGoalStates(transitionMatrix, cycleStates); + - for (int i=0 ; i < cycleStates.size() ; i++ ){ - std::cout << cycleStates[i] << "\t" << probabilisticNonGoalStates[i] <<"\n"; - } std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = 0; @@ -423,6 +452,7 @@ namespace storm { //vectors to save calculation std::vector> vd,vu,wu; + printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished //transition matrix with diagonal entries. The values can be changed during uniformisation std::vector exitRate{exitRateVector}; @@ -508,7 +538,6 @@ namespace storm { vu = std::vector> (N + 1, init); wu = std::vector> (N + 1, init); - printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when develepmont is finished // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { @@ -521,7 +550,7 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when development is finished + //printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when development is finished // (6) double lambda diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 559912c2e..421a1e21a 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -69,6 +69,10 @@ namespace storm { } template ::SupportsExponential, int>::type=0> + static storm::storage::BitVector identifyProbCyclesGoalStates(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& cycleStates); + + + template ::SupportsExponential, int>::type=0> static storm::storage::BitVector identifyProbCycles(storm::storage::SparseMatrix const& TransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); /*! * Computes the poission-distribution @@ -114,7 +118,7 @@ namespace storm { */ template ::SupportsExponential, int>::type=0> - static void printTransitions(std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,std::vector>& vd, std::vector>& vu, std::vector>& wu); + static void printTransitions(std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector>& vd, std::vector>& vu, std::vector>& wu); template ::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector& markovianNonGoalValues, std::vector& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); From 253b34ce094404cc1ddccd23f762c4a285e9cbe3 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Mon, 20 Nov 2017 08:51:55 +0100 Subject: [PATCH 07/46] modularised diagonal-prob entrie delete and skipped zero loops in cycle identification --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 81 ++++++++++--------- .../helper/SparseMarkovAutomatonCslHelper.h | 6 +- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 725594d5b..b9aaa221e 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -162,7 +162,7 @@ namespace storm { logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; for (int i =0 ; i< markovianStates.size() ; i++){ - logfile << (~markovianStates)[i] << "\t" << markovianStates[i] << "\t" << psiStates[i] << "\t" << cycleStates[i] << "\t" << cycleGoalStates[i] << "\n"; + logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; } @@ -369,6 +369,9 @@ namespace storm { for(uint64_t i =from; i + std::vector SparseMarkovAutomatonCslHelper::deleteProbDiagonalEntries(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates){ - template ::SupportsExponential, int>::type> - std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ - STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - - - storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~psiStates; - auto cycleStates = identifyProbCycles(transitionMatrix, markovianStates, psiStates); - auto cycleGoals = identifyProbCyclesGoalStates(transitionMatrix, cycleStates); - - - std::ofstream logfile("U+logfile.txt", std::ios::app); - ValueType maxNorm = 0; - - //bitvectors to identify different kind of states -// storm::storage::BitVector const &markovianNonGoalStates = markovianStates & ~psiStates; -// storm::storage::BitVector const &probabilisticNonGoalStates = ~markovianStates & ~psiStates; - storm::storage::BitVector allStates(markovianStates.size(), true); - - //vectors to save calculation - std::vector> vd,vu,wu; - printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished - - //transition matrix with diagonal entries. The values can be changed during uniformisation - std::vector exitRate{exitRateVector}; - typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); - //delete prob-diagonal entries - for (uint64_t i =0; i::SupportsExponential, int>::type> + std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + + std::ofstream logfile("U+logfile.txt", std::ios::app); + ValueType maxNorm = 0; + + //bitvectors to identify different kind of states + storm::storage::BitVector allStates(markovianStates.size(), true); + + //vectors to save calculation + std::vector> vd,vu,wu; + + + //transition matrix with diagonal entries. The values can be changed during uniformisation + std::vector exitRate{exitRateVector}; + typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + + //delete prob-diagonal entries + deleteProbDiagonalEntries(fullTransitionMatrix, markovianStates); + + //identify cycles and cycleGoals + auto cycleStates = identifyProbCycles(transitionMatrix, markovianStates, psiStates); + auto cycleGoals = identifyProbCyclesGoalStates(transitionMatrix, cycleStates); //(1) define horizon, epsilon, kappa , N, lambda, @@ -543,13 +545,14 @@ namespace storm { } exitRate[i] = exitNew; } - + // (4) define vectors/matrices std::vector init(numberOfStates, -1); vd = std::vector> (N + 1, init); vu = std::vector> (N + 1, init); wu = std::vector> (N + 1, init); - + + printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { @@ -562,7 +565,7 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - //printTransitions(exitRate, fullTransitionMatrix, markovianStates,vd,vu,wu); // TODO: delete when development is finished + printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished // (6) double lambda diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 908668d2b..363de0867 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -68,7 +68,11 @@ namespace storm { return id-1; } - template ::SupportsExponential, int>::type=0> + template + static std::vector deleteProbDiagonalEntries(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); + + + template ::SupportsExponential, int>::type=0> static storm::storage::BitVector identifyProbCyclesGoalStates(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& cycleStates); From 286fc8aec7d87ebb891c43b719685b2218315e68 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Mon, 20 Nov 2017 16:02:18 +0100 Subject: [PATCH 08/46] fixed bugs, runnig now --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 27 ++++++++++++------- .../helper/SparseMarkovAutomatonCslHelper.h | 8 ++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index b9aaa221e..f654405a4 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -357,7 +357,7 @@ namespace storm { } template ::SupportsExponential, int>::type=0> - int SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix const& transitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t* counter) { + uint64_t SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix const& transitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t* counter) { auto const& rowGroupIndice = transitionMatrix.getRowGroupIndices(); disc[node] = *counter; @@ -430,7 +430,7 @@ namespace storm { storm::storage::BitVector cycleStates(markovianStates.size(), false); for (int i = 0 ; i< finish.size() ; i++){ auto f = finish[i]; - for (int j =i; j - std::vector SparseMarkovAutomatonCslHelper::deleteProbDiagonalEntries(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates){ + template ::SupportsExponential, int>::type=0> + void SparseMarkovAutomatonCslHelper::deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates){ auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); for (uint64_t i =0; i + std::vector SparseMarkovAutomatonCslHelper::deleteProbDiagonalEntries(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates){ + + } template ::SupportsExponential, int>::type> @@ -494,11 +502,14 @@ namespace storm { //delete prob-diagonal entries - deleteProbDiagonalEntries(fullTransitionMatrix, markovianStates); + //deleteProbDiagonalEntries(fullTransitionMatrix, markovianStates); + deleteProbDiagonals(fullTransitionMatrix, markovianStates); //identify cycles and cycleGoals - auto cycleStates = identifyProbCycles(transitionMatrix, markovianStates, psiStates); - auto cycleGoals = identifyProbCyclesGoalStates(transitionMatrix, cycleStates); + auto cycleStates = identifyProbCycles(fullTransitionMatrix, markovianStates, psiStates); + auto cycleGoals = identifyProbCyclesGoalStates(fullTransitionMatrix, cycleStates); + + printTransitions(exitRateVector, fullTransitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished //(1) define horizon, epsilon, kappa , N, lambda, @@ -552,7 +563,6 @@ namespace storm { vu = std::vector> (N + 1, init); wu = std::vector> (N + 1, init); - printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { @@ -565,7 +575,6 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - printTransitions(exitRateVector, transitionMatrix, markovianStates, psiStates, cycleStates, cycleGoals, vd,vu,wu); // TODO: delete when develepmont is finished // (6) double lambda diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 363de0867..015b71e67 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -56,6 +56,10 @@ namespace storm { static std::vector computeReachabilityTimes(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& backwardTransitions, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); private: + + template ::SupportsExponential, int>::type=0> + static void deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); + static uint64_t transformIndice(storm::storage::BitVector const& subset, uint64_t fakeId){ uint64_t id =0; uint64_t counter =0; @@ -84,14 +88,14 @@ namespace storm { * * @param parameter lambda to use * @param point i - * TODO: replace with Fox-Lynn + * TODO: replace with Fox-glynn * @return the probability */ template static ValueType poisson(ValueType lambda, uint64_t i); template ::SupportsExponential, int>::type=0> - static int trajans(storm::storage::SparseMatrix const& TransitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t * counter); + static uint64_t trajans(storm::storage::SparseMatrix const& TransitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t * counter); /*! * Computes vd vector according to UnifPlus From dfda3a154488ae852d5020664a7607a98b8130ff Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Mon, 20 Nov 2017 17:51:23 +0100 Subject: [PATCH 09/46] cleaned up --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 6 ------ .../csl/helper/SparseMarkovAutomatonCslHelper.h | 4 ---- 2 files changed, 10 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index f654405a4..fd1ae1161 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -473,12 +473,6 @@ namespace storm { } } } - } - - template - std::vector SparseMarkovAutomatonCslHelper::deleteProbDiagonalEntries(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates){ - - } template ::SupportsExponential, int>::type> diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 015b71e67..1cee6364d 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -72,10 +72,6 @@ namespace storm { return id-1; } - template - static std::vector deleteProbDiagonalEntries(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); - - template ::SupportsExponential, int>::type=0> static storm::storage::BitVector identifyProbCyclesGoalStates(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& cycleStates); From 8421ff5c654b7eedbcbc2610964ecd57e68ecb23 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Tue, 21 Nov 2017 09:55:04 +0100 Subject: [PATCH 10/46] first try, cmake not building --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 36 +++++++++++++------ .../helper/SparseMarkovAutomatonCslHelper.h | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index fd1ae1161..67eec89ee 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -136,7 +136,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::printTransitions(std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector>& vd, std::vector>& vu, std::vector>& wu){ + void SparseMarkovAutomatonCslHelper::printTransitions(std::vector> relReachability, std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector>& vd, std::vector>& vu, std::vector>& wu){ std::ofstream logfile("U+logfile.txt", std::ios::app); auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -165,6 +165,12 @@ namespace storm { logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; } + for (int i =0; i in(fullTransitionMatrix.getRowCount(), 0); + std::vector> relReachability(numberOfStates,in); + + printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished + for(int i=0 ; i& act = relReachability[j]; + for(auto element: fullTransitionMatrix.getRow(j)){ + if (markovianStates[element.getColumn()]){ + act[element.getColumn]=element.getValue(); + } + } + + } + } - // while not close enough to precision: + // while not close enough to precision: do { // (2) update parameter N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 1cee6364d..376b4e88a 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -122,7 +122,7 @@ namespace storm { */ template ::SupportsExponential, int>::type=0> - static void printTransitions(std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector>& vd, std::vector>& vu, std::vector>& wu); + static void printTransitions(std::vector> relReachability, std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector>& vd, std::vector>& vu, std::vector>& wu); template ::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector& markovianNonGoalValues, std::vector& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); From 5ba296404a2826d92e516b7ad07b8ad5d399e49f Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Thu, 23 Nov 2017 12:41:10 +0100 Subject: [PATCH 11/46] not finished version of MDP approach --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 186 +++++++++++++++--- .../helper/SparseMarkovAutomatonCslHelper.h | 8 +- 2 files changed, 167 insertions(+), 27 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 67eec89ee..3ef29e743 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -213,7 +213,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = vu.size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -221,7 +221,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (wu[N-1-(i-k)][node]==-1){ - calculateWu(dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + calculateWu(relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, minMaxLinearEquationSolverFactory); } res+=poisson(lambda, i)*wu[N-1-(i-k)][node]; } @@ -229,7 +229,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateWu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateWu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = wu.size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices( ); @@ -251,11 +251,72 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (wu[k+1][to]==-1){ - calculateWu(dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates); + calculateWu(relativeReachability, dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, minMaxLinearEquationSolverFactory); } res+=element.getValue()*wu[k+1][to]; } } else { + + // applying simpleMDP stuff + auto numberOfStates=relativeReachability[0].size(); + typename storm::storage::SparseMatrix probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); + auto probSize = probMatrix.getRowGroupCount(); + std::vector b(probSize, 0), x(probSize,0); + + //calculate b + for (uint64_t i =0 ; i> solver = minMaxLinearEquationSolverFactory.create(probMatrix); + + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero(), storm::utility::one()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + + + solver->solveEquations(dir, x, b); + + for (uint64_t i =0 ; i::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVd(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + void SparseMarkovAutomatonCslHelper::calculateVd(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -324,11 +384,83 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (vd[k+1][to]==-1){ - calculateVd(dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates); + calculateVd(relativeReachability, dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates, minMaxLinearEquationSolverFactory); } res+=element.getValue()*vd[k+1][to]; } + + vd[k][node]=res; + logfile << " res = " << res << "\n"; } else { //no-goal prob state + // applying simpleMDP stuff + logfile << "probState, applying MDP stuff "; + auto numberOfStates=relativeReachability[0].size(); + typename storm::storage::SparseMatrix probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); + auto probSize = probMatrix.getRowGroupCount(); + std::vector b(probSize, 0), x(probSize,0); + + //calculate b + for (uint64_t i =0 ; i> solver = minMaxLinearEquationSolverFactory.create(probMatrix); + + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero(), storm::utility::one()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + + + solver->solveEquations(dir, x, b); + logfile << "goal vector x is \n"; + for (int i =0 ; i::SupportsExponential, int>::type=0> @@ -482,7 +613,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ + std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -516,24 +647,32 @@ namespace storm { uint64_t N; //calculate relative ReachabilityVectors - std::vector in(fullTransitionMatrix.getRowCount(), 0); - std::vector> relReachability(numberOfStates,in); + std::vector in(numberOfStates, 0); + std::vector> relReachability(fullTransitionMatrix.getRowCount(),in); printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished - for(int i=0 ; i& act = relReachability[j]; for(auto element: fullTransitionMatrix.getRow(j)){ if (markovianStates[element.getColumn()]){ - act[element.getColumn]=element.getValue(); + act[element.getColumn()]=element.getValue(); } } - } } + + + printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished // while not close enough to precision: do { // (2) update parameter @@ -577,15 +716,17 @@ namespace storm { // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateVd(dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates); - calculateWu(dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates); - calculateVu(dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates); + calculateVd(relReachability, dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + calculateWu(relReachability, dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + calculateVu(relReachability, dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); //also use iteration to keep maxNorm of vd and vu up to date, so the loop-condition is easy to prove ValueType diff = std::abs(vd[k][i]-vu[k][i]); maxNorm = std::max(maxNorm, diff); } } + printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished + // (6) double lambda lambda=2*lambda; @@ -668,8 +809,7 @@ namespace storm { } else { STORM_LOG_ASSERT(markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus, "Unknown solution technique."); - // Why is optimization direction not passed? - return unifPlus(dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); + return unifPlus(dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 376b4e88a..7dac4cf6f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -28,7 +28,7 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static std::vector unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static std::vector unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); template ::SupportsExponential, int>::type = 0> static std::vector computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); @@ -98,14 +98,14 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static void calculateVd(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateVd(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); /*! * Computes vu vector according to UnifPlus * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); /*! @@ -113,7 +113,7 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static void calculateWu(OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + static void calculateWu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile From b90e88c365e794e0505105e2e32fd53d468514c7 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Fri, 24 Nov 2017 12:48:14 +0100 Subject: [PATCH 12/46] first version, seems to be working, need to check more --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 104 +++++++++--------- 1 file changed, 50 insertions(+), 54 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 3ef29e743..c84e48477 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -231,6 +231,11 @@ namespace storm { template ::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::calculateWu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. + + std::ofstream logfile("U+logfile.txt", std::ios::app); + + auto probabilisticStates = ~markovianStates; + uint64_t N = wu.size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices( ); @@ -255,46 +260,42 @@ namespace storm { } res+=element.getValue()*wu[k+1][to]; } + wu[k][node]=res; } else { - // applying simpleMDP stuff auto numberOfStates=relativeReachability[0].size(); typename storm::storage::SparseMatrix probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); auto probSize = probMatrix.getRowGroupCount(); - std::vector b(probSize, 0), x(probSize,0); + std::vector b(probMatrix.getRowCount(), 0), x(probSize,0); //calculate b - for (uint64_t i =0 ; i::SupportsExponential, int>::type> @@ -352,6 +352,8 @@ namespace storm { std::ofstream logfile("U+logfile.txt", std::ios::app); + auto probabilisticStates = ~markovianStates; + if (vd[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. logfile << "calculating vd for k = " << k << " node "<< node << " \t"; uint64_t N = vd.size()-1; @@ -397,41 +399,35 @@ namespace storm { auto numberOfStates=relativeReachability[0].size(); typename storm::storage::SparseMatrix probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); auto probSize = probMatrix.getRowGroupCount(); - std::vector b(probSize, 0), x(probSize,0); + std::vector b(probMatrix.getRowCount(), 0), x(probSize,0); //calculate b - for (uint64_t i =0 ; isolveEquations(dir, x, b); - logfile << "goal vector x is \n"; - for (int i =0 ; i Date: Fri, 24 Nov 2017 14:56:03 +0100 Subject: [PATCH 13/46] creating solver only once --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 70 ++++++++----------- .../helper/SparseMarkovAutomatonCslHelper.h | 6 +- 2 files changed, 31 insertions(+), 45 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index c84e48477..bd2c99760 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -213,7 +213,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver){ if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = vu.size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -221,7 +221,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (wu[N-1-(i-k)][node]==-1){ - calculateWu(relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, minMaxLinearEquationSolverFactory); + calculateWu(relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } res+=poisson(lambda, i)*wu[N-1-(i-k)][node]; } @@ -229,7 +229,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateWu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ + void SparseMarkovAutomatonCslHelper::calculateWu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver){ if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -256,7 +256,7 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (wu[k+1][to]==-1){ - calculateWu(relativeReachability, dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, minMaxLinearEquationSolverFactory); + calculateWu(relativeReachability, dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } res+=element.getValue()*wu[k+1][to]; } @@ -284,7 +284,7 @@ namespace storm { continue; } if (wu[k][to]==-1){ - calculateWu(relativeReachability, dir, k, to, lambda, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + calculateWu(relativeReachability, dir, k, to, lambda, wu, fullTransitionMatrix, markovianStates, psiStates, solver); } res = res + relativeReachability[j][to]*wu[k][to]; } @@ -297,19 +297,6 @@ namespace storm { logfile << b[i] << "\n"; } - - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); - requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - - std::unique_ptr> solver = minMaxLinearEquationSolverFactory.create(probMatrix); - - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero(), storm::utility::one()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); - - solver->solveEquations(dir, x, b); for (uint64_t i =0 ; i::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVd(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ + void SparseMarkovAutomatonCslHelper::calculateVd(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver){ std::ofstream logfile("U+logfile.txt", std::ios::app); @@ -386,7 +373,7 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (vd[k+1][to]==-1){ - calculateVd(relativeReachability, dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates, minMaxLinearEquationSolverFactory); + calculateVd(relativeReachability, dir,k+1,to,lambda,vd, fullTransitionMatrix, markovianStates,psiStates, solver); } res+=element.getValue()*vd[k+1][to]; } @@ -417,7 +404,7 @@ namespace storm { continue; } if (vd[k][to]==-1){ - calculateVd(relativeReachability, dir, k, to, lambda, vd, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + calculateVd(relativeReachability, dir, k, to, lambda, vd, fullTransitionMatrix, markovianStates, psiStates, solver); } res = res + relativeReachability[j][to]*vd[k][to]; } @@ -431,20 +418,6 @@ namespace storm { logfile << b[i] << "\n"; } - - - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); - requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - - std::unique_ptr> solver = minMaxLinearEquationSolverFactory.create(probMatrix); - - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero(), storm::utility::one()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); - - solver->solveEquations(dir, x, b); logfile << "vd goal vector x is \n"; for (int i =0 ; i> vd,vu,wu; @@ -625,10 +600,9 @@ namespace storm { //transition matrix with diagonal entries. The values can be changed during uniformisation std::vector exitRate{exitRateVector}; typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - - + typename storm::storage::SparseMatrix probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); + auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); //(1) define horizon, epsilon, kappa , N, lambda, @@ -666,9 +640,20 @@ namespace storm { } } + //create equitation solver + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); + requirements.clearBounds(); + STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + std::unique_ptr> solver = minMaxLinearEquationSolverFactory.create(probMatrix); - printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero(), storm::utility::one()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + + + printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished // while not close enough to precision: do { // (2) update parameter @@ -707,14 +692,15 @@ namespace storm { vd = std::vector> (N + 1, init); vu = std::vector> (N + 1, init); wu = std::vector> (N + 1, init); + // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateVd(relReachability, dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); - calculateWu(relReachability, dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); - calculateVu(relReachability, dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + calculateVd(relReachability, dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates, solver); + calculateWu(relReachability, dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates, solver); + calculateVu(relReachability, dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates, solver); //also use iteration to keep maxNorm of vd and vu up to date, so the loop-condition is easy to prove ValueType diff = std::abs(vd[k][i]-vu[k][i]); maxNorm = std::max(maxNorm, diff); diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 7dac4cf6f..d378ded43 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -98,14 +98,14 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static void calculateVd(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); + static void calculateVd(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver); /*! * Computes vu vector according to UnifPlus * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); + static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver); /*! @@ -113,7 +113,7 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static void calculateWu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); + static void calculateWu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile From ec41a5e661d8ebf816d3818b97b765b5306fb3db Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sat, 25 Nov 2017 14:39:55 +0100 Subject: [PATCH 14/46] reorganised and modulised storm --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 367 +++++++----------- .../helper/SparseMarkovAutomatonCslHelper.h | 24 +- 2 files changed, 143 insertions(+), 248 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index bd2c99760..de2459647 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -134,14 +134,23 @@ namespace storm { void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector& markovianNonGoalValues, std::vector& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } - - template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::printTransitions(std::vector> relReachability, std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector>& vd, std::vector>& vu, std::vector>& wu){ + + template::SupportsExponential, int>::type= 0> + void SparseMarkovAutomatonCslHelper::printTransitions( + storm::storage::SparseMatrix const &fullTransitionMatrix, + std::vector const &exitRateVector, storm::storage::BitVector const &markovianStates, + storm::storage::BitVector const &psiStates, std::vector> relReachability, + const storage::BitVector &cycleStates, const storage::BitVector &cycleGoalStates, + std::vector>> &unifVectors) { + + + std::ofstream logfile("U+logfile.txt", std::ios::app); - + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); + //Transition Matrix logfile << "number of states = num of row group count " << numberOfStates << "\n"; for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { logfile << " from node " << i << " "; @@ -161,8 +170,8 @@ namespace storm { logfile << "\n"; logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; - for (int i =0 ; i< markovianStates.size() ; i++){ - logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; + for (int i =0 ; i< markovianStates.size() ; i++){ + logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; } for (int i =0; i::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver){ - if (vu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. - uint64_t N = vu.size()-1; + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver){ + if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. + uint64_t N = unifVectors[1].size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ - if (wu[N-1-(i-k)][node]==-1){ - calculateWu(relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); + if (unifVectors[2][N-1-(i-k)][node]==-1){ + calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver); + //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } - res+=poisson(lambda, i)*wu[N-1-(i-k)][node]; + res+=poisson(lambda, i)*unifVectors[2][N-1-(i-k)][node]; } - vu[k][node]=res; + unifVectors[1][k][node]=res; } - template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateWu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver){ - if (wu[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. - - std::ofstream logfile("U+logfile.txt", std::ios::app); - - auto probabilisticStates = ~markovianStates; - uint64_t N = wu.size()-1; - auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices( ); - ValueType res; - if (k==N){ - wu[k][node]=0; - return; - } - if (psiStates[node]){ - wu[k][node]=1; - return; - } + template::SupportsExponential, int>::type= 0> + void SparseMarkovAutomatonCslHelper::calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, + std::vector> const &relativeReachability, + OptimizationDirection dir, + std::vector>> &unifVectors, + storm::storage::SparseMatrix const &fullTransitionMatrix, + storm::storage::BitVector const &markovianStates, + storm::storage::BitVector const &psiStates, + std::unique_ptr> const &solver) { - if (markovianStates[node]){ - res = 0; - auto line = fullTransitionMatrix.getRow(rowGroupIndices[node]); - for (auto &element : line){ - uint64_t to = element.getColumn(); - if (wu[k+1][to]==-1){ - calculateWu(relativeReachability, dir, k+1,to,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); - } - res+=element.getValue()*wu[k+1][to]; - } - wu[k][node]=res; - } else { - // applying simpleMDP stuff - auto numberOfStates=relativeReachability[0].size(); - typename storm::storage::SparseMatrix probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); - auto probSize = probMatrix.getRowGroupCount(); - std::vector b(probMatrix.getRowCount(), 0), x(probSize,0); - - //calculate b - uint64_t lineCounter=0; - for (int i =0; isolveEquations(dir, x, b); - - for (uint64_t i =0 ; i::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVd(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver){ - + if (unifVectors[kind][k][node]!=-1){return;} std::ofstream logfile("U+logfile.txt", std::ios::app); + logfile << "calculating vector " << kind << " for k = " << k << " node "<< node << " \t"; auto probabilisticStates = ~markovianStates; - - if (vd[k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. - logfile << "calculating vd for k = " << k << " node "<< node << " \t"; - uint64_t N = vd.size()-1; + auto numberOfStates=fullTransitionMatrix.getRowGroupCount(); + uint64_t N = unifVectors[kind].size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - ValueType res; + + // First Case, k==N, independent from kind of state if (k==N){ logfile << "k == N! res = 0\n"; - vd[k][node]=0; + unifVectors[kind][k][node]=0; return; } - + //goal state if (psiStates[node]){ - res = storm::utility::zero(); - for (uint64_t i = k ; i(); + for (uint64_t i = k ; i probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); - auto probSize = probMatrix.getRowGroupCount(); - std::vector b(probMatrix.getRowCount(), 0), x(probSize,0); + return; + } + //probabilistic non-goal State + if (probabilisticStates[node]){ + logfile << "probabilistic state: "; + std::vector b(probSize, 0), x(probabilisticStates.getNumberOfSetBits(),0); //calculate b uint64_t lineCounter=0; - for (int i =0; isolveEquations(dir, x, b); - logfile << "vd goal vector x is \n"; - for (int i =0 ; i::SupportsExponential, int>::type=0> uint64_t SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix const& transitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t* counter) { auto const& rowGroupIndice = transitionMatrix.getRowGroupIndices(); @@ -585,24 +475,29 @@ namespace storm { std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - std::ofstream logfile("U+logfile.txt", std::ios::app); - ValueType maxNorm = 0; + ValueType maxNorm = storm::utility::zero(); //bitvectors to identify different kind of states storm::storage::BitVector allStates(markovianStates.size(), true); - auto probabilisticStates = ~markovianStates; + storm::storage::BitVector probabilisticStates = ~markovianStates; //vectors to save calculation std::vector> vd,vu,wu; + std::vector>> unifVectors{}; //transition matrix with diagonal entries. The values can be changed during uniformisation std::vector exitRate{exitRateVector}; typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); - typename storm::storage::SparseMatrix probMatrix = fullTransitionMatrix.getSubmatrix(true, ~markovianStates , ~markovianStates, true); + typename storm::storage::SparseMatrix probMatrix{}; + uint64_t probSize =0; + if (probabilisticStates.getNumberOfSetBits()!=0){ //work around in case there are no prob states + probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates , probabilisticStates, true); + probSize = probMatrix.getRowCount(); + } - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); //(1) define horizon, epsilon, kappa , N, lambda, @@ -616,13 +511,14 @@ namespace storm { } uint64_t N; + + //calculate relative ReachabilityVectors std::vector in(numberOfStates, 0); std::vector> relReachability(fullTransitionMatrix.getRowCount(),in); - printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished - //calculate relative reachability + //calculate relative reachability for(uint64_t i=0 ; i> solver = minMaxLinearEquationSolverFactory.create(probMatrix); - - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero(), storm::utility::one()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); - - - printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished + std::unique_ptr> solver; + if (probSize!=0){ + solver = minMaxLinearEquationSolverFactory.create(probMatrix); + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero(), storm::utility::one()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + } // while not close enough to precision: do { // (2) update parameter @@ -692,29 +587,37 @@ namespace storm { vd = std::vector> (N + 1, init); vu = std::vector> (N + 1, init); wu = std::vector> (N + 1, init); - + unifVectors.clear(); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + + printTransitions(fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove + + //define 0=vd 1=vu 2=wu // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateVd(relReachability, dir, k, i, T*lambda, vd, fullTransitionMatrix, markovianStates, psiStates, solver); - calculateWu(relReachability, dir, k, i, T*lambda, wu, fullTransitionMatrix, markovianStates, psiStates, solver); - calculateVu(relReachability, dir, k, i, T*lambda, vu, wu, fullTransitionMatrix, markovianStates, psiStates, solver); - //also use iteration to keep maxNorm of vd and vu up to date, so the loop-condition is easy to prove - ValueType diff = std::abs(vd[k][i]-vu[k][i]); + calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); + calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); + calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); + //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove + ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); } } - - printTransitions(relReachability, exitRateVector, fullTransitionMatrix, markovianStates, psiStates, psiStates, psiStates, vd,vu,wu); // TODO: delete when develepmont is finished + std::cout << "\nTBU was " << unifVectors[0][0][0] << "\n"; + printTransitions(fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove - // (6) double lambda + // (6) double lambda lambda=2*lambda; } while (maxNorm>epsilon*(1-kappa)); - return vd[0]; + + return unifVectors[0][0]; } template ::SupportsExponential, int>::type> @@ -1234,7 +1137,7 @@ namespace storm { return v.front() * uniformizationRate; } - + template std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); template std::vector SparseMarkovAutomatonCslHelper::computeUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index d378ded43..3d5b8d049 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -56,6 +56,8 @@ namespace storm { static std::vector computeReachabilityTimes(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& backwardTransitions, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); private: + template ::SupportsExponential, int>::type=0> + static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver); template ::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -93,27 +95,15 @@ namespace storm { template ::SupportsExponential, int>::type=0> static uint64_t trajans(storm::storage::SparseMatrix const& TransitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t * counter); - /*! - * Computes vd vector according to UnifPlus - * - */ - template ::SupportsExponential, int>::type=0> - static void calculateVd(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vd, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver); - -/*! + /* * Computes vu vector according to UnifPlus * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& vu, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver); + static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver); + - /*! - * Computes wu vector according to UnifPlus - * - */ - template ::SupportsExponential, int>::type=0> - static void calculateWu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, ValueType lambda, std::vector>& wu, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile @@ -122,7 +112,9 @@ namespace storm { */ template ::SupportsExponential, int>::type=0> - static void printTransitions(std::vector> relReachability, std::vector const& exitRateVector, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& cycleStates, storm::storage::BitVector const& cycleGoalStates, std::vector>& vd, std::vector>& vu, std::vector>& wu); + static void printTransitions(storm::storage::SparseMatrix const& fullTransitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, + storm::storage::BitVector const& psiStates, std::vector> relReachability, + storm::storage::BitVector const& cycleStates , storm::storage::BitVector const& cycleGoalStates ,std::vector>>& unifVectors); template ::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector& markovianNonGoalValues, std::vector& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); From 42e650362b623ff568a02ebb4b8b9d3463182a0e Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sat, 25 Nov 2017 15:44:25 +0100 Subject: [PATCH 15/46] fixed the sife of result vector MDP approach, add selfLoop deletion --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index de2459647..609a03e94 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -258,6 +258,7 @@ namespace storm { logfile << "calculating vector " << kind << " for k = " << k << " node "<< node << " \t"; auto probabilisticStates = ~markovianStates; + auto numberOfProbStates = probabilisticStates.getNumberOfSetBits(); auto numberOfStates=fullTransitionMatrix.getRowGroupCount(); uint64_t N = unifVectors[kind].size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -309,7 +310,7 @@ namespace storm { //probabilistic non-goal State if (probabilisticStates[node]){ logfile << "probabilistic state: "; - std::vector b(probSize, 0), x(probabilisticStates.getNumberOfSetBits(),0); + std::vector b(probSize, 0), x(numberOfProbStates,0); //calculate b uint64_t lineCounter=0; for (int i =0; i exitRate{exitRateVector}; typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); + // delete diagonals + deleteProbDiagonals(fullTransitionMatrix, markovianStates); typename storm::storage::SparseMatrix probMatrix{}; uint64_t probSize =0; if (probabilisticStates.getNumberOfSetBits()!=0){ //work around in case there are no prob states @@ -518,6 +522,7 @@ namespace storm { std::vector> relReachability(fullTransitionMatrix.getRowCount(),in); + //calculate relative reachability for(uint64_t i=0 ; i Date: Sun, 26 Nov 2017 15:06:39 +0100 Subject: [PATCH 16/46] leaving some Log prints" --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 33 ++++++++----------- .../helper/SparseMarkovAutomatonCslHelper.h | 2 +- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 609a03e94..8bd2ba44c 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -136,7 +136,7 @@ namespace storm { } template::SupportsExponential, int>::type= 0> - void SparseMarkovAutomatonCslHelper::printTransitions( + void SparseMarkovAutomatonCslHelper::printTransitions(const uint64_t N, ValueType const diff, storm::storage::SparseMatrix const &fullTransitionMatrix, std::vector const &exitRateVector, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, std::vector> relReachability, @@ -169,19 +169,12 @@ namespace storm { } logfile << "\n"; - logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; + /*logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; for (int i =0 ; i< markovianStates.size() ; i++){ logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; - } - - for (int i =0; i> const &solver) { if (unifVectors[kind][k][node]!=-1){return;} - std::ofstream logfile("U+logfile.txt", std::ios::app); - logfile << "calculating vector " << kind << " for k = " << k << " node "<< node << " \t"; + //std::ofstream logfile("U+logfile.txt", std::ios::app); + //logfile << "calculating vector " << kind << " for k = " << k << " node "<< node << " \t"; auto probabilisticStates = ~markovianStates; auto numberOfProbStates = probabilisticStates.getNumberOfSetBits(); @@ -266,7 +259,7 @@ namespace storm { // First Case, k==N, independent from kind of state if (k==N){ - logfile << "k == N! res = 0\n"; + //logfile << "k == N! res = 0\n"; unifVectors[kind][k][node]=0; return; } @@ -285,14 +278,14 @@ namespace storm { // WU unifVectors[kind][k][node]=1; } - logfile << "goal state node " << node << " res = " << res << "\n"; + //logfile << "goal state node " << node << " res = " << res << "\n"; return; } //markovian non-goal State if (markovianStates[node]){ - logfile << "markovian state: "; + //logfile << "markovian state: "; res = 0; auto line = fullTransitionMatrix.getRow(rowGroupIndices[node]); for (auto &element : line){ @@ -303,13 +296,13 @@ namespace storm { res+=element.getValue()*unifVectors[kind][k+1][to]; } unifVectors[kind][k][node]=res; - logfile << " res = " << res << "\n"; + //logfile << " res = " << res << "\n"; return; } //probabilistic non-goal State if (probabilisticStates[node]){ - logfile << "probabilistic state: "; + //logfile << "probabilistic state: "; std::vector b(probSize, 0), x(numberOfProbStates,0); //calculate b uint64_t lineCounter=0; @@ -347,7 +340,7 @@ namespace storm { unifVectors[kind][k][trueI]=x[i]; } - logfile << " res = " << unifVectors[kind][k][node] << " but calculated more \n"; + //logfile << " res = " << unifVectors[kind][k][node] << " but calculated more \n"; } //end probabilistic states } @@ -610,7 +603,7 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - printTransitions(fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove + printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove // (6) double lambda diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 3d5b8d049..49970334b 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -112,7 +112,7 @@ namespace storm { */ template ::SupportsExponential, int>::type=0> - static void printTransitions(storm::storage::SparseMatrix const& fullTransitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, + static void printTransitions(const uint64_t N, ValueType const diff, storm::storage::SparseMatrix const& fullTransitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::vector> relReachability, storm::storage::BitVector const& cycleStates , storm::storage::BitVector const& cycleGoalStates ,std::vector>>& unifVectors); From 4b43a1c42c9cbe69f193deddb8da3fe59afaaef5 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sun, 26 Nov 2017 18:15:22 +0100 Subject: [PATCH 17/46] catching case psiStates=probStates, logprints still included --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 67 ++++++++++--------- .../helper/SparseMarkovAutomatonCslHelper.h | 6 +- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 8bd2ba44c..3d12a0cbe 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -141,11 +141,7 @@ namespace storm { std::vector const &exitRateVector, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, std::vector> relReachability, const storage::BitVector &cycleStates, const storage::BitVector &cycleGoalStates, - std::vector>> &unifVectors) { - - - - std::ofstream logfile("U+logfile.txt", std::ios::app); + std::vector>> &unifVectors, std::ofstream& logfile) { auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); @@ -169,12 +165,12 @@ namespace storm { } logfile << "\n"; - /*logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; + logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; for (int i =0 ; i< markovianStates.size() ; i++){ logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; - } */ + } - logfile << "Iteration for N = " << N << "maximal difference was " << " diff\n"; + logfile << "Iteration for N = " << N << "maximal difference was " << diff << "\n"; logfile << "vd: \n"; for (uint64_t i =0 ; i @@ -217,7 +211,7 @@ namespace storm { template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver){ + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -225,7 +219,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver); + calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } res+=poisson(lambda, i)*unifVectors[2][N-1-(i-k)][node]; @@ -244,11 +238,14 @@ namespace storm { storm::storage::SparseMatrix const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr> const &solver) { + std::unique_ptr> const &solver, std::ofstream& logfile) { - if (unifVectors[kind][k][node]!=-1){return;} - //std::ofstream logfile("U+logfile.txt", std::ios::app); - //logfile << "calculating vector " << kind << " for k = " << k << " node "<< node << " \t"; + + if (unifVectors[kind][k][node]!=-1){ + logfile << "already calculated for k = " << k << " node = " << node << "\n"; + return; + } + std::string print = std::string("calculating vector ") + std::to_string(kind) + " for k = " + std::to_string(k) + " node " + std::to_string(node) +" \t"; auto probabilisticStates = ~markovianStates; auto numberOfProbStates = probabilisticStates.getNumberOfSetBits(); @@ -259,7 +256,7 @@ namespace storm { // First Case, k==N, independent from kind of state if (k==N){ - //logfile << "k == N! res = 0\n"; + logfile << print << "k == N! res = 0\n"; unifVectors[kind][k][node]=0; return; } @@ -278,31 +275,29 @@ namespace storm { // WU unifVectors[kind][k][node]=1; } - //logfile << "goal state node " << node << " res = " << res << "\n"; + logfile << print << "goal state node " << node << " res = " << res << "\n"; return; } //markovian non-goal State if (markovianStates[node]){ - //logfile << "markovian state: "; res = 0; auto line = fullTransitionMatrix.getRow(rowGroupIndices[node]); for (auto &element : line){ uint64_t to = element.getColumn(); if (unifVectors[kind][k+1][to]==-1){ - calculateUnifPlusVector(k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); + calculateUnifPlusVector(k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); } res+=element.getValue()*unifVectors[kind][k+1][to]; } unifVectors[kind][k][node]=res; - //logfile << " res = " << res << "\n"; + logfile << print << "markovian state: " << " res = " << res << "\n"; return; } //probabilistic non-goal State if (probabilisticStates[node]){ - //logfile << "probabilistic state: "; std::vector b(probSize, 0), x(numberOfProbStates,0); //calculate b uint64_t lineCounter=0; @@ -322,7 +317,7 @@ namespace storm { if (unifVectors[kind][k][to] == -1) { calculateUnifPlusVector(k, to, kind, lambda, probSize, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, - psiStates, solver); + psiStates, solver, logfile); } res = res + relativeReachability[j][to] * unifVectors[kind][k][to]; } @@ -340,7 +335,7 @@ namespace storm { unifVectors[kind][k][trueI]=x[i]; } - //logfile << " res = " << unifVectors[kind][k][node] << " but calculated more \n"; + logfile << print << "probabilistic state: "<< " res = " << unifVectors[kind][k][node] << " but calculated more \n"; } //end probabilistic states } @@ -467,12 +462,16 @@ namespace storm { } template ::SupportsExponential, int>::type> - std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ + std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + + + std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = storm::utility::zero(); //bitvectors to identify different kind of states + storm::storage::BitVector markovianStates = markovStates; storm::storage::BitVector allStates(markovianStates.size(), true); storm::storage::BitVector probabilisticStates = ~markovianStates; @@ -482,6 +481,14 @@ namespace storm { std::vector>> unifVectors{}; + //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! + for (uint64_t i =0 ; i exitRate{exitRateVector}; typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); @@ -595,22 +602,22 @@ namespace storm { // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); - calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); - calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver); + calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); + calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); + calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); } } - printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors); //TODO remove - + printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors, logfile); //TODO remove // (6) double lambda lambda=2*lambda; } while (maxNorm>epsilon*(1-kappa)); + logfile.close(); return unifVectors[0][0]; } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 49970334b..b2ad305a1 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -57,7 +57,7 @@ namespace storm { private: template ::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver); + static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile); template ::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -100,7 +100,7 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver); + static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile); @@ -114,7 +114,7 @@ namespace storm { template ::SupportsExponential, int>::type=0> static void printTransitions(const uint64_t N, ValueType const diff, storm::storage::SparseMatrix const& fullTransitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::vector> relReachability, - storm::storage::BitVector const& cycleStates , storm::storage::BitVector const& cycleGoalStates ,std::vector>>& unifVectors); + storm::storage::BitVector const& cycleStates , storm::storage::BitVector const& cycleGoalStates ,std::vector>>& unifVectors, std::ofstream& logfile); template ::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector& markovianNonGoalValues, std::vector& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); From b155abc0994b8321dce1bc381990ba3766d049cd Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sun, 26 Nov 2017 18:55:17 +0100 Subject: [PATCH 18/46] fixed stupid, big bug. add exit for stock-case --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 3d12a0cbe..d88a50cec 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -469,6 +469,7 @@ namespace storm { std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = storm::utility::zero(); + ValueType oldDiff = -storm::utility::zero(); //bitvectors to identify different kind of states storm::storage::BitVector markovianStates = markovStates; @@ -556,6 +557,7 @@ namespace storm { } // while not close enough to precision: do { + maxNorm = storm::utility::zero(); // (2) update parameter N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); @@ -615,6 +617,14 @@ namespace storm { // (6) double lambda lambda=2*lambda; + // (7) escape if not coming closer to solution + if (oldDiff!=-1){ + if (oldDiff==maxNorm){ + std::cout << "Not coming closer to solution as " << maxNorm << "/n"; + break; + } + } + oldDiff = maxNorm; } while (maxNorm>epsilon*(1-kappa)); logfile.close(); From 7cdff078419ca3c93fd650335fc412787f25ee76 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Mon, 27 Nov 2017 13:06:42 +0100 Subject: [PATCH 19/46] back copz fox glznn ' --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 26 +- .../helper/SparseMarkovAutomatonCslHelper.h | 319 +++++++++++++++++- 2 files changed, 331 insertions(+), 14 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index d88a50cec..a9d8c0158 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -211,7 +211,7 @@ namespace storm { template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile){ + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -219,10 +219,10 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile); + calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } - res+=poisson(lambda, i)*unifVectors[2][N-1-(i-k)][node]; + res+=poisson[i]*unifVectors[2][N-1-(i-k)][node]; } unifVectors[1][k][node]=res; } @@ -238,7 +238,7 @@ namespace storm { storm::storage::SparseMatrix const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr> const &solver, std::ofstream& logfile) { + std::unique_ptr> const &solver, std::ofstream& logfile, std::vector poisson) { if (unifVectors[kind][k][node]!=-1){ @@ -267,7 +267,7 @@ namespace storm { // Vd res = storm::utility::zero(); for (uint64_t i = k ; i SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - - std::ofstream logfile("U+logfile.txt", std::ios::app); ValueType maxNorm = storm::utility::zero(); ValueType oldDiff = -storm::utility::zero(); @@ -589,6 +587,9 @@ namespace storm { exitRate[i] = exitNew; } + // calculate poisson distribution + std::vector poisson = foxGlynnProb(lambda*T, N, epsilon*kappa); + // (4) define vectors/matrices std::vector init(numberOfStates, -1); vd = std::vector> (N + 1, init); @@ -604,9 +605,9 @@ namespace storm { // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); - calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); - calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile); + calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); + calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); + calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); @@ -615,6 +616,7 @@ namespace storm { printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors, logfile); //TODO remove // (6) double lambda + lambda=2*lambda; // (7) escape if not coming closer to solution diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index b2ad305a1..5e8c16c33 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -57,7 +57,7 @@ namespace storm { private: template ::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile); + static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector poisson); template ::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -80,6 +80,321 @@ namespace storm { template ::SupportsExponential, int>::type=0> static storm::storage::BitVector identifyProbCycles(storm::storage::SparseMatrix const& TransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + + //TODO: move this + + typedef struct FoxGlynn + { + int left; + int right; + double total_weight; + double *weights; + } FoxGlynn; + + static std::vector foxGlynnProb(double lambdaT, int N, double precision){ + + FoxGlynn* fg = NULL; + if(!fox_glynn(lambdaT, DBL_MIN, DBL_MAX, precision, &fg)) { + printf("ERROR: fox-glynn failed\n"); + return std::vector{}; + } + + long double sumOfPoissonProbs = 0.0; + std::vector poisson_p(N,0.0); + unsigned long iter_num; + + //for(int i=fg->left; i<=fg->right; i++) { + for (int i = 0; iweights[i-fg->left]/fg->total_weight; + sumOfPoissonProbs+=poisson_p[i]; + } + + /*for(int i=fg->left-1; i>=0; i--) { + poisson_p[i] = poisson_p[i+1]*((i+1)/(lambdaT)); + sumOfPoissonProbs+=poisson_p[i]; + }*/ + + iter_num = fg->right; + + freeFG(fg); + + return poisson_p; + } + + static bool finder(const int m, const double lambda, const double tau, const double omega, + const double epsilon, double * pw_m, FoxGlynn *pFG) + { + /*The pi constant*/ + static const double pi = 3.14159265358979323846264; + static const double lambda_25 = 25.0; + static const double lambda_400 = 40; + + const double sqrt_2_pi = sqrt( 2.0 * pi ); + const double sqrt_2 = sqrt(2.0); + const double sqrt_lambda = sqrt(lambda); + double lambda_max, k, k_rtp = HUGE_VAL, k_prime, c_m_inf, result, al, dkl, bl; + + /*Simple bad cases, when we quit*/ + if( lambda == 0.0 ) + { + printf("ERROR: Fox-Glynn: lambda = 0, terminating the algorithm\n"); + return false; + } + /* The requested error level must not be smaller than the minimum machine precision + (needed to guarantee the convergence of the error conditions) */ + if( epsilon < tau) + { + printf("ERROR: Fox-Glynn: epsilon < tau, invalid error level, terminating the algorithm\n"); + printf("epsilon %f, tau %f\n",epsilon,tau); + return false; + } + /* zero is used as left truncation point for lambda <= 25 */ + pFG->left = 0; + lambda_max = lambda; + + /* for lambda below 25 the exponential can be smaller than tau */ + /* if that is the case we expect underflows and warn the user */ + if( 0.0 < lambda && lambda <= lambda_25 ) + { + if( exp( -lambda ) <= tau ) + { + printf("ERROR: Fox-Glynn: 0 < lambda < 25, underflow. The results are UNRELIABLE.\n"); + } + } + + bl = (1.0 + 1.0/lambda) * exp(1.0 / (8.0 * lambda)); + + /****Compute pFG->right truncation point****/ + /*According to Fox-Glynn, if lambda < 400 we should take lambda = 400, + otherwise use the original value. This is for computing the right truncation point*/ + if(lambda < lambda_400) + lambda_max = lambda_400; + k = 4; + al = (1.0+1.0/lambda_max) * exp(1.0/16.0) * sqrt_2; + dkl = exp(-2.0/9.0 * (k * sqrt(2.0 * lambda_max) + 1.5 )); + dkl = 1.0 / (1.0 - dkl); + /* find right truncation point */ + + /* This loop is a modification to the original Fox-Glynn paper. + The search for the right truncation point is only terminated by + the error condition and not by the stop index from the FG paper. + This can yield more accurate results if neccesary.*/ + while((epsilon/2.0) < ((al * dkl * exp(-(k*k)/2.0))/(k*sqrt_2_pi))) + { + k++; + dkl = exp(-2.0/9.0 * (k * sqrt_2 * sqrt(lambda_max) + 1.5 )); + dkl = 1.0 / (1.0 - dkl); + } + k_rtp = k; + pFG->right = (int)ceil(m + k_rtp * sqrt_2 * sqrt(lambda_max) + 1.5 ); + + + /****Compute pFG->left truncation point****/ + /* compute the left truncation point for lambda > 25 */ + /* for lambda <= 25 we use zero as left truncation point */ + if(lambda > lambda_25) + { + /*Start looking for the left truncation point*/ + /* start search at k=4 (taken from original Fox-Glynn paper */ + k = 4; + /* increase the left truncation point as long as we fulfill the error condition */ + + /* This loop is a modification to the original Fox-Glynn paper. + The search for the left truncation point is only terminated by + the error condition and not by the stop index from the FG paper. + This can yield more accurate results if neccesary.*/ + while((epsilon/2.0) < ((bl * exp(-(k*k)/2.0))/(k * sqrt_2_pi))) + k++; + /*Finally the left truncation point is found*/ + pFG->left = (int)floor(m - k*sqrt(lambda)- 1.5 ); + /* for small lambda the above calculation can yield negative truncation points, crop them here */ + if(pFG->left < 0) + pFG->left = 0; + /* perform underflow check */ + k_prime = k + 3.0 / (2.0 * sqrt_lambda); + /*We take the c_m_inf = 0.02935 / sqrt( m ), as for lambda >= 25 + c_m = 1 / ( sqrt( 2.0 * pi * m ) ) * exp( m - lambda - 1 / ( 12.0 * m ) ) => c_m_inf*/ + c_m_inf = 0.02935 / sqrt((double) m); + result = 0.0; + if( 0.0 < k_prime && k_prime <= sqrt_lambda / 2.0 ) + { + result = c_m_inf * exp( - pow(k_prime,2.0) / 2.0 - pow(k_prime, 3.0) / (3.0 * sqrt_lambda) ); + } + else + { + if( k_prime <= sqrt( m + 1.0 ) / m ) + { + double result_1 = c_m_inf * pow( + 1.0 - k_prime / sqrt((double) (m + 1)), + k_prime * sqrt((double) (m + 1))); + double result_2 = exp( - lambda ); + /*Take the maximum*/ + result = ( result_1 > result_2 ? result_1 : result_2); + } + else + { + /*NOTE: It will be an underflow error*/; + printf("ERROR: Fox-Glynn: lambda >= 25, underflow. The results are UNRELIABLE.\n"); + } + } + if ( result * omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ) <= tau ) + { + printf("ERROR: Fox-Glynn: lambda >= 25, underflow. The results are UNRELIABLE.\n"); + } + } + + + + /*We still have to perform an underflow check for the right truncation point when lambda >= 400*/ + if( lambda >= lambda_400 ) + { + k_prime = k_rtp * sqrt_2 + 3.0 / (2.0 * sqrt_lambda); + /*We take the c_m_inf = 0.02935 / sqrt( m ), as for lambda >= 25 + c_m = 1 / ( sqrt( 2.0 * pi * m ) ) * exp( m - lambda - 1 / ( 12.0 * m ) ) => c_m_inf*/ + c_m_inf = 0.02935 / sqrt((double) m); + result = c_m_inf * exp( - pow( k_prime + 1.0 , 2.0 ) / 2.0 ); + if( result * omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ) <= tau) + { + printf("ERROR: Fox-Glynn: lambda >= 400, underflow. The results are UNRELIABLE.\n"); + } + } + /*Time to set the initial value for weights*/ + *pw_m = omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ); + + return true; + } + +/***************************************************************************** +Name : weighter +Role : The WEIGHTER function from the Fox-Glynn algorithm +@param : double lambda: (rate of uniformization)*(mission time) +@param : double tau: underflow +@param : double omega: overflow +@param : double epsilon: error bound +@param : FoxGlynn *: return by reference +@return : TRUE if everything is fine, otherwise FALSE. + This is the F parameter of Fox-Glynn finder function. +remark : +******************************************************************************/ + static bool weighter(const double lambda, const double tau, const double omega, const double epsilon, FoxGlynn *pFG) + { + static const double pi = 3.14159265358979323846264; + static const double lambda_25 = 25.0; + static const double lambda_400 = 40; + /*The magic m point*/ + const int m = (int)floor(lambda); + double w_m = 0; + int j, s, t; + + if( ! finder( m, lambda, tau, omega, epsilon, &w_m, pFG ) ) + return false; + + /*Allocate space for weights*/ + pFG->weights = (double *) calloc((size_t) (pFG->right - pFG->left + 1), + sizeof(double)); + /*Set an initial weight*/ + pFG->weights[ m - pFG->left ] = w_m; + + /*Fill the left side of the array*/ + for( j = m; j > pFG->left; j-- ) + pFG->weights[ ( j - pFG->left ) - 1 ] = ( j / lambda ) * pFG->weights[ j - pFG->left ]; + + /*Fill the right side of the array, have two cases lambda < 400 & lambda >= 400*/ + if( lambda < lambda_400 ) + { + /*Perform the underflow check, according to Fox-Glynn*/ + if( pFG->right > 600 ) + { + printf("ERROR: Fox-Glynn: pFG->right > 600, underflow is possible\n"); + return false; + } + /*Compute weights*/ + for( j = m; j < pFG->right; j++ ) + { + double q = lambda / ( j + 1 ); + if( pFG->weights[ j - pFG->left ] > tau / q ) + { + pFG->weights[ ( j - pFG->left ) + 1 ] = q * pFG->weights[ j - pFG->left ]; + }else{ + pFG->right = j; + break; /*It's time to compute W*/ + } + } + }else{ + /*Compute weights*/ + for( j = m; j < pFG->right; j++ ) + pFG->weights[ ( j - pFG->left ) + 1 ] = ( lambda / ( j + 1 ) ) * pFG->weights[ j - pFG->left ]; + } + + /*It is time to compute the normalization weight W*/ + pFG->total_weight = 0.0; + s = pFG->left; + t = pFG->right; + + while( s < t ) + { + if( pFG->weights[ s - pFG->left ] <= pFG->weights[ t - pFG->left ] ) + { + pFG->total_weight += pFG->weights[ s - pFG->left ]; + s++; + }else{ + pFG->total_weight += pFG->weights[ t - pFG->left ]; + t--; + } + } + pFG->total_weight += pFG->weights[ s - pFG->left ]; + + /* printf("Fox-Glynn: ltp = %d, rtp = %d, w = %10.15le \n", pFG->left, pFG->right, pFG->total_weight); */ + + return true; + } + +/***************************************************************************** +Name : fox_glynn +Role : get poisson probabilities. +@param : double lambda: (rate of uniformization)*(mission time) +@param : double tau: underflow +@param : double omega: overflow +@param : double epsilon: error bound +@param : FoxGlynn **: return a new FoxGlynn structure by reference +@return : TRUE if it worked fine, otherwise false +remark : +******************************************************************************/ + static bool fox_glynn(const double lambda, const double tau, const double omega, const double epsilon, FoxGlynn **ppFG) + { + /* printf("Fox-Glynn: lambda = %3.3le, epsilon = %1.8le\n",lambda, epsilon); */ + + *ppFG = (FoxGlynn *) calloc((size_t) 1, sizeof(FoxGlynn)); + (*ppFG)->weights = NULL; + + return weighter(lambda, tau, omega, epsilon, *ppFG); + } + + +/** +* Fries the memory allocated for the FoxGlynn structure +* @param fg the structure to free +*/ + static void freeFG(FoxGlynn * fg) + { + if( fg ){ + if( fg->weights ) + free(fg->weights); + free(fg); + } + } + + /*! + * Computes the poission-distribution + * + * + * @param parameter lambda to use + * @param point i + * TODO: replace with Fox-Lynn + * @return the probability + */ + + /*! * Computes the poission-distribution * @@ -100,7 +415,7 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile); + static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector poisson); From 2e69c59c7868648364cbd9b83ebce13b4c9c73b1 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Mon, 27 Nov 2017 13:36:43 +0100 Subject: [PATCH 20/46] references for poisson --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 4 ++-- .../modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index a9d8c0158..d83286338 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -211,7 +211,7 @@ namespace storm { template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector poisson){ + void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -238,7 +238,7 @@ namespace storm { storm::storage::SparseMatrix const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr> const &solver, std::ofstream& logfile, std::vector poisson) { + std::unique_ptr> const &solver, std::ofstream& logfile, std::vector const& poisson) { if (unifVectors[kind][k][node]!=-1){ diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 5e8c16c33..ff536e71f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -57,7 +57,7 @@ namespace storm { private: template ::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector poisson); + static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson); template ::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -415,7 +415,7 @@ remark : * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector poisson); + static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson); From 7db58c6374662f61ffb829494cde5f0023dad097 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Tue, 28 Nov 2017 17:22:30 +0100 Subject: [PATCH 21/46] using existing fox glynn now --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 340 ++++++++++-------- .../helper/SparseMarkovAutomatonCslHelper.h | 3 + 2 files changed, 196 insertions(+), 147 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index d83286338..4264a9b28 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -369,6 +369,45 @@ namespace storm { return finish[node]; } + template::SupportsExponential, int>::type= 0> + void SparseMarkovAutomatonCslHelper::identify( + storm::storage::SparseMatrix const &fullTransitionMatrix, + storm::storage::BitVector const &markovianStates, storm::storage::BitVector const& psiStates) { + auto indices = fullTransitionMatrix.getRowGroupIndices(); + bool realProb = false; + bool NDM = false; + bool Alternating = true; + bool probStates = false; + bool markStates = false; + + for (uint64_t i=0; i::SupportsExponential, int>::type=0> storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCyclesGoalStates(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& cycleStates) { @@ -463,174 +502,181 @@ namespace storm { template ::SupportsExponential, int>::type> std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ - STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - - std::ofstream logfile("U+logfile.txt", std::ios::app); - ValueType maxNorm = storm::utility::zero(); - ValueType oldDiff = -storm::utility::zero(); - - //bitvectors to identify different kind of states - storm::storage::BitVector markovianStates = markovStates; - storm::storage::BitVector allStates(markovianStates.size(), true); - storm::storage::BitVector probabilisticStates = ~markovianStates; - - - //vectors to save calculation - std::vector> vd,vu,wu; - std::vector>> unifVectors{}; - - - //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! - for (uint64_t i =0 ; i exitRate{exitRateVector}; - typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); - // delete diagonals - deleteProbDiagonals(fullTransitionMatrix, markovianStates); - typename storm::storage::SparseMatrix probMatrix{}; - uint64_t probSize =0; - if (probabilisticStates.getNumberOfSetBits()!=0){ //work around in case there are no prob states - probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates , probabilisticStates, true); - probSize = probMatrix.getRowCount(); - } - auto& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + std::ofstream logfile("U+logfile.txt", std::ios::app); + ValueType maxNorm = storm::utility::zero(); + ValueType oldDiff = -storm::utility::zero(); + //bitvectors to identify different kind of states + storm::storage::BitVector markovianStates = markovStates; + storm::storage::BitVector allStates(markovianStates.size(), true); + storm::storage::BitVector probabilisticStates = ~markovianStates; - //(1) define horizon, epsilon, kappa , N, lambda, - uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); - double T = boundsPair.second; - ValueType kappa = storm::utility::one() /10; // would be better as option-parameter - ValueType epsilon = storm::settings::getModule().getPrecision(); - ValueType lambda = exitRateVector[0]; - for (ValueType act: exitRateVector) { - lambda = std::max(act, lambda); - } - uint64_t N; + //vectors to save calculation + std::vector> vd,vu,wu; + std::vector>> unifVectors{}; - //calculate relative ReachabilityVectors - std::vector in(numberOfStates, 0); - std::vector> relReachability(fullTransitionMatrix.getRowCount(),in); + //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! + for (uint64_t i =0 ; i exitRate{exitRateVector}; + typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); + // delete diagonals + deleteProbDiagonals(fullTransitionMatrix, markovianStates); + typename storm::storage::SparseMatrix probMatrix{}; + uint64_t probSize =0; + if (probabilisticStates.getNumberOfSetBits()!=0){ //work around in case there are no prob states + probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates , probabilisticStates, true); + probSize = probMatrix.getRowCount(); + } + auto& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - //calculate relative reachability - for(uint64_t i=0 ; i() /10; // would be better as option-parameter + ValueType epsilon = storm::settings::getModule().getPrecision(); + ValueType lambda = exitRateVector[0]; + for (ValueType act: exitRateVector) { + lambda = std::max(act, lambda); } - auto from = rowGroupIndices[i]; - auto to = rowGroupIndices[i+1]; - for (auto j=from ; j& act = relReachability[j]; - for(auto element: fullTransitionMatrix.getRow(j)){ - if (markovianStates[element.getColumn()]){ - act[element.getColumn()]=element.getValue(); - } - } - } - } + uint64_t N; - //create equitation solver - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); - requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - std::unique_ptr> solver; - if (probSize!=0){ - solver = minMaxLinearEquationSolverFactory.create(probMatrix); - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero(), storm::utility::one()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); - } - // while not close enough to precision: - do { - maxNorm = storm::utility::zero(); - // (2) update parameter - N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); - - // (3) uniform - just applied to markovian states - for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { - if (!markovianStates[i]) { - continue; - } - uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row - if (exitRate[i] == lambda) { - continue; //already unified - } - auto line = fullTransitionMatrix.getRow(from); - ValueType exitOld = exitRate[i]; - ValueType exitNew = lambda; - for (auto &v : line) { - if (v.getColumn() == i) { //diagonal element - ValueType newSelfLoop = exitNew - exitOld + v.getValue(); - ValueType newRate = newSelfLoop / exitNew; - v.setValue(newRate); - } else { //modify probability - ValueType propOld = v.getValue(); - ValueType propNew = propOld * exitOld / exitNew; - v.setValue(propNew); - } - } - exitRate[i] = exitNew; - } + //calculate relative ReachabilityVectors + std::vector in(numberOfStates, 0); + std::vector> relReachability(fullTransitionMatrix.getRowCount(),in); - // calculate poisson distribution - std::vector poisson = foxGlynnProb(lambda*T, N, epsilon*kappa); - - // (4) define vectors/matrices - std::vector init(numberOfStates, -1); - vd = std::vector> (N + 1, init); - vu = std::vector> (N + 1, init); - wu = std::vector> (N + 1, init); - - unifVectors.clear(); - unifVectors.push_back(vd); - unifVectors.push_back(vd); - unifVectors.push_back(vd); - - //define 0=vd 1=vu 2=wu - // (5) calculate vectors and maxNorm - for (uint64_t i = 0; i < numberOfStates; i++) { - for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); - calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); - calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); - //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove - ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); - maxNorm = std::max(maxNorm, diff); - } - } - printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors, logfile); //TODO remove - // (6) double lambda - lambda=2*lambda; + //calculate relative reachability - // (7) escape if not coming closer to solution - if (oldDiff!=-1){ - if (oldDiff==maxNorm){ - std::cout << "Not coming closer to solution as " << maxNorm << "/n"; - break; - } - } - oldDiff = maxNorm; - } while (maxNorm>epsilon*(1-kappa)); + for(uint64_t i=0 ; i& act = relReachability[j]; + for(auto element: fullTransitionMatrix.getRow(j)){ + if (markovianStates[element.getColumn()]){ + act[element.getColumn()]=element.getValue(); + } + } + } + } + + //create equitation solver + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); + requirements.clearBounds(); + STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + + std::unique_ptr> solver; + if (probSize!=0){ + solver = minMaxLinearEquationSolverFactory.create(probMatrix); + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero(), storm::utility::one()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + } + // while not close enough to precision: + do { + maxNorm = storm::utility::zero(); + // (2) update parameter + N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); + + // (3) uniform - just applied to markovian states + for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + if (!markovianStates[i]) { + continue; + } + uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row + + if (exitRate[i] == lambda) { + continue; //already unified + } + + auto line = fullTransitionMatrix.getRow(from); + ValueType exitOld = exitRate[i]; + ValueType exitNew = lambda; + for (auto &v : line) { + if (v.getColumn() == i) { //diagonal element + ValueType newSelfLoop = exitNew - exitOld + v.getValue(); + ValueType newRate = newSelfLoop / exitNew; + v.setValue(newRate); + } else { //modify probability + ValueType propOld = v.getValue(); + ValueType propNew = propOld * exitOld / exitNew; + v.setValue(propNew); + } + } + exitRate[i] = exitNew; + } + + // calculate poisson distribution + std::tuple> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff(T*lambda, 1e+300, epsilon*kappa/ 8.0); + + // Scale the weights so they add up to one. + for (auto& element : std::get<3>(foxGlynnResult)) { + element /= std::get<2>(foxGlynnResult); + } + // (4) define vectors/matrices + std::vector init(numberOfStates, -1); + vd = std::vector> (N + 1, init); + vu = std::vector> (N + 1, init); + wu = std::vector> (N + 1, init); + + unifVectors.clear(); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + + //define 0=vd 1=vu 2=wu + // (5) calculate vectors and maxNorm + for (uint64_t i = 0; i < numberOfStates; i++) { + for (uint64_t k = N; k <= N; k--) { + calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); + calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); + calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); + //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove + ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); + maxNorm = std::max(maxNorm, diff); + } + } + printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors, logfile); //TODO remove + + // (6) double lambda + + lambda=2*lambda; + + // (7) escape if not coming closer to solution + if (oldDiff!=-1){ + if (oldDiff==maxNorm){ + std::cout << "Not coming closer to solution as " << maxNorm << "/n"; + break; + } + } + oldDiff = maxNorm; + } while (maxNorm>epsilon*(1-kappa)); + + logfile.close(); + return unifVectors[0][0]; - logfile.close(); - return unifVectors[0][0]; } template ::SupportsExponential, int>::type> diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index ff536e71f..ab036c8c3 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -56,6 +56,9 @@ namespace storm { static std::vector computeReachabilityTimes(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& backwardTransitions, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); private: + template ::SupportsExponential, int>::type=0> + static void identify(storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,storm::storage::BitVector const& psiStates); + template ::SupportsExponential, int>::type=0> static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson); From 535a6017e3c0336d96a66213886645ddc80351a8 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Wed, 29 Nov 2017 17:56:58 +0100 Subject: [PATCH 22/46] fixed use of FoxLynn after CutOff --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 336 ++++++++++-------- 1 file changed, 180 insertions(+), 156 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 4264a9b28..b4c7b0526 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -242,7 +242,7 @@ namespace storm { if (unifVectors[kind][k][node]!=-1){ - logfile << "already calculated for k = " << k << " node = " << node << "\n"; + //logfile << "already calculated for k = " << k << " node = " << node << "\n"; return; } std::string print = std::string("calculating vector ") + std::to_string(kind) + " for k = " + std::to_string(k) + " node " + std::to_string(node) +" \t"; @@ -267,8 +267,10 @@ namespace storm { // Vd res = storm::utility::zero(); for (uint64_t i = k ; i::SupportsExponential, int>::type> - std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory){ - STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + template::SupportsExponential, int>::type> + std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, + std::pair const &boundsPair, + std::vector const &exitRateVector, + storm::storage::SparseMatrix const &transitionMatrix, + storm::storage::BitVector const &markovStates, + storm::storage::BitVector const &psiStates, + storm::solver::MinMaxLinearEquationSolverFactory const &minMaxLinearEquationSolverFactory) { + STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + + + std::ofstream logfile("U+logfile.txt", std::ios::app); + ValueType maxNorm = storm::utility::zero(); + ValueType oldDiff = -storm::utility::zero(); + + //bitvectors to identify different kind of states + storm::storage::BitVector markovianStates = markovStates; + storm::storage::BitVector allStates(markovianStates.size(), true); + storm::storage::BitVector probabilisticStates = ~markovianStates; + + + //vectors to save calculation + std::vector> vd, vu, wu; + std::vector>> unifVectors{}; + + + //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! + for (uint64_t i = 0; i < psiStates.size(); i++) { + if (psiStates[i]) { + markovianStates.set(i, true); + probabilisticStates.set(i, false); + } + } + + //transition matrix with diagonal entries. The values can be changed during uniformisation + std::vector exitRate{exitRateVector}; + typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix( + true, allStates, allStates, true); + // delete diagonals + deleteProbDiagonals(fullTransitionMatrix, markovianStates); + typename storm::storage::SparseMatrix probMatrix{}; + uint64_t probSize = 0; + if (probabilisticStates.getNumberOfSetBits() != 0) { //work around in case there are no prob states + probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates, probabilisticStates, + true); + probSize = probMatrix.getRowCount(); + } + + auto &rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + + //(1) define horizon, epsilon, kappa , N, lambda, + uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); + double T = boundsPair.second; + ValueType kappa = storm::utility::one() / 10; // would be better as option-parameter + ValueType epsilon = storm::settings::getModule().getPrecision(); + ValueType lambda = exitRateVector[0]; + for (ValueType act: exitRateVector) { + lambda = std::max(act, lambda); + } + uint64_t N; + - std::ofstream logfile("U+logfile.txt", std::ios::app); - ValueType maxNorm = storm::utility::zero(); - ValueType oldDiff = -storm::utility::zero(); - //bitvectors to identify different kind of states - storm::storage::BitVector markovianStates = markovStates; - storm::storage::BitVector allStates(markovianStates.size(), true); - storm::storage::BitVector probabilisticStates = ~markovianStates; + //calculate relative ReachabilityVectors + std::vector in(numberOfStates, 0); + std::vector> relReachability(fullTransitionMatrix.getRowCount(), in); - //vectors to save calculation - std::vector> vd,vu,wu; - std::vector>> unifVectors{}; + //calculate relative reachability - //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! - for (uint64_t i =0 ; i &act = relReachability[j]; + for (auto element: fullTransitionMatrix.getRow(j)) { + if (markovianStates[element.getColumn()]) { + act[element.getColumn()] = element.getValue(); } } - - //transition matrix with diagonal entries. The values can be changed during uniformisation - std::vector exitRate{exitRateVector}; - typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates , allStates , true); - // delete diagonals - deleteProbDiagonals(fullTransitionMatrix, markovianStates); - typename storm::storage::SparseMatrix probMatrix{}; - uint64_t probSize =0; - if (probabilisticStates.getNumberOfSetBits()!=0){ //work around in case there are no prob states - probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates , probabilisticStates, true); - probSize = probMatrix.getRowCount(); } + } - auto& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + //create equitation solver + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements( + true, dir); + requirements.clearBounds(); + STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, + "Cannot establish requirements for solver."); + + std::unique_ptr> solver; + if (probSize != 0) { + solver = minMaxLinearEquationSolverFactory.create(probMatrix); + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero(), storm::utility::one()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + } + // while not close enough to precision: + do { + maxNorm = storm::utility::zero(); + // (2) update parameter + N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); + + // (3) uniform - just applied to markovian states + for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + if (!markovianStates[i]) { + continue; + } + uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row + if (exitRate[i] == lambda) { + continue; //already unified + } - //(1) define horizon, epsilon, kappa , N, lambda, - uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); - double T = boundsPair.second; - ValueType kappa = storm::utility::one() /10; // would be better as option-parameter - ValueType epsilon = storm::settings::getModule().getPrecision(); - ValueType lambda = exitRateVector[0]; - for (ValueType act: exitRateVector) { - lambda = std::max(act, lambda); + auto line = fullTransitionMatrix.getRow(from); + ValueType exitOld = exitRate[i]; + ValueType exitNew = lambda; + for (auto &v : line) { + if (v.getColumn() == i) { //diagonal element + ValueType newSelfLoop = exitNew - exitOld + v.getValue(); + ValueType newRate = newSelfLoop / exitNew; + v.setValue(newRate); + } else { //modify probability + ValueType propOld = v.getValue(); + ValueType propNew = propOld * exitOld / exitNew; + v.setValue(propNew); + } + } + exitRate[i] = exitNew; } - uint64_t N; + // calculate poisson distribution + std::tuple> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff( + T * lambda, 1e+300, epsilon * epsilon * kappa); - //calculate relative ReachabilityVectors - std::vector in(numberOfStates, 0); - std::vector> relReachability(fullTransitionMatrix.getRowCount(),in); + // Scale the weights so they add up to one. + for (auto &element : std::get<3>(foxGlynnResult)) { + element /= std::get<2>(foxGlynnResult); + } + // (4) define vectors/matrices + std::vector init(numberOfStates, -1); + vd = std::vector>(N + 1, init); + vu = std::vector>(N + 1, init); + wu = std::vector>(N + 1, init); + + unifVectors.clear(); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + unifVectors.push_back(vd); + + //define 0=vd 1=vu 2=wu + // (5) calculate vectors and maxNorm + for (uint64_t i = 0; i < numberOfStates; i++) { + for (uint64_t k = N; k <= N; k--) { + calculateUnifPlusVector(k, i, 0, lambda, probSize, relReachability, dir, unifVectors, + fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + std::get<3>(foxGlynnResult)); + calculateUnifPlusVector(k, i, 2, lambda, probSize, relReachability, dir, unifVectors, + fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + std::get<3>(foxGlynnResult)); + calculateVu(relReachability, dir, k, i, 1, lambda, probSize, unifVectors, + fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + std::get<3>(foxGlynnResult)); + //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove + ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); + maxNorm = std::max(maxNorm, diff); + } + } + printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove - //calculate relative reachability + // (6) double lambda - for(uint64_t i=0 ; i& act = relReachability[j]; - for(auto element: fullTransitionMatrix.getRow(j)){ - if (markovianStates[element.getColumn()]){ - act[element.getColumn()]=element.getValue(); - } - } - } - } + lambda = 2 * lambda; - //create equitation solver - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(true, dir); - requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - - std::unique_ptr> solver; - if (probSize!=0){ - solver = minMaxLinearEquationSolverFactory.create(probMatrix); - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero(), storm::utility::one()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); - } - // while not close enough to precision: - do { - maxNorm = storm::utility::zero(); - // (2) update parameter - N = ceil(lambda*T*exp(2)-log(kappa*epsilon)); - - // (3) uniform - just applied to markovian states - for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { - if (!markovianStates[i]) { - continue; - } - uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row - - if (exitRate[i] == lambda) { - continue; //already unified - } - - auto line = fullTransitionMatrix.getRow(from); - ValueType exitOld = exitRate[i]; - ValueType exitNew = lambda; - for (auto &v : line) { - if (v.getColumn() == i) { //diagonal element - ValueType newSelfLoop = exitNew - exitOld + v.getValue(); - ValueType newRate = newSelfLoop / exitNew; - v.setValue(newRate); - } else { //modify probability - ValueType propOld = v.getValue(); - ValueType propNew = propOld * exitOld / exitNew; - v.setValue(propNew); - } - } - exitRate[i] = exitNew; - } - - // calculate poisson distribution - std::tuple> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff(T*lambda, 1e+300, epsilon*kappa/ 8.0); - - // Scale the weights so they add up to one. - for (auto& element : std::get<3>(foxGlynnResult)) { - element /= std::get<2>(foxGlynnResult); - } - // (4) define vectors/matrices - std::vector init(numberOfStates, -1); - vd = std::vector> (N + 1, init); - vu = std::vector> (N + 1, init); - wu = std::vector> (N + 1, init); - - unifVectors.clear(); - unifVectors.push_back(vd); - unifVectors.push_back(vd); - unifVectors.push_back(vd); - - //define 0=vd 1=vu 2=wu - // (5) calculate vectors and maxNorm - for (uint64_t i = 0; i < numberOfStates; i++) { - for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(k,i,0,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); - calculateUnifPlusVector(k,i,2,lambda,probSize,relReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); - calculateVu(relReachability,dir,k,i,1,lambda,probSize,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, std::get<3>(foxGlynnResult)); - //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove - ValueType diff = std::abs(unifVectors[0][k][i]-unifVectors[1][k][i]); - maxNorm = std::max(maxNorm, diff); - } - } - printTransitions(N, maxNorm, fullTransitionMatrix,exitRate,markovianStates,psiStates,relReachability,psiStates, psiStates,unifVectors, logfile); //TODO remove - - // (6) double lambda - - lambda=2*lambda; - - // (7) escape if not coming closer to solution - if (oldDiff!=-1){ - if (oldDiff==maxNorm){ - std::cout << "Not coming closer to solution as " << maxNorm << "/n"; - break; - } - } - oldDiff = maxNorm; - } while (maxNorm>epsilon*(1-kappa)); - - logfile.close(); - return unifVectors[0][0]; + // (7) escape if not coming closer to solution + if (oldDiff != -1) { + if (oldDiff == maxNorm) { + std::cout << "Not coming closer to solution as " << maxNorm << "/n"; + break; + } + } + oldDiff = maxNorm; + } while (maxNorm > epsilon * (1 - kappa)); + + logfile.close(); + return unifVectors[0][0]; } From d2b14cfac28f32768f1baf735c84f62a751c930b Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Wed, 29 Nov 2017 17:58:43 +0100 Subject: [PATCH 23/46] skript for easier running one singe instance --- pstorm.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 pstorm.py diff --git a/pstorm.py b/pstorm.py new file mode 100644 index 000000000..aaa5a6b25 --- /dev/null +++ b/pstorm.py @@ -0,0 +1,15 @@ +import sys +import os +import subprocess +prop = ' --prop \"Pmax=? [F<1 \\"goal\\"]\" --ma:technique unifplus' +storm= '/home/timo/ustorm/build/bin/storm' + + +if len(sys.argv)<2: + print("no input file found\n") + exit() + +for a in sys.argv[1:]: + file = " --prism " + a + cmd = storm + file + prop + os.system(cmd) From 2a1487dc390049fc438f7c1c11057d6e782e28a5 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Wed, 29 Nov 2017 20:05:25 +0100 Subject: [PATCH 24/46] back to copied version of foxglynn, leaving too small values --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 11 ++++++----- .../csl/helper/SparseMarkovAutomatonCslHelper.h | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index b4c7b0526..23a8accde 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -267,7 +267,7 @@ namespace storm { // Vd res = storm::utility::zero(); for (uint64_t i = k ; i1e-300){ ValueType between = poisson[i]; res+=between; } @@ -652,6 +652,8 @@ namespace storm { } + std::vector poisson = foxGlynnProb(lambda*T, N+1, epsilon*kappa); + // (4) define vectors/matrices std::vector init(numberOfStates, -1); vd = std::vector>(N + 1, init); @@ -669,13 +671,13 @@ namespace storm { for (uint64_t k = N; k <= N; k--) { calculateUnifPlusVector(k, i, 0, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - std::get<3>(foxGlynnResult)); + poisson); calculateUnifPlusVector(k, i, 2, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - std::get<3>(foxGlynnResult)); + poisson); calculateVu(relReachability, dir, k, i, 1, lambda, probSize, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - std::get<3>(foxGlynnResult)); + poisson); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); @@ -700,7 +702,6 @@ namespace storm { logfile.close(); return unifVectors[0][0]; - } template ::SupportsExponential, int>::type> diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index ab036c8c3..4ce22a17b 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -106,16 +106,17 @@ namespace storm { std::vector poisson_p(N,0.0); unsigned long iter_num; + std::cout << "fg left " << fg->left << " fh right " << fg->right <<"\n"; //for(int i=fg->left; i<=fg->right; i++) { for (int i = 0; iweights[i-fg->left]/fg->total_weight; sumOfPoissonProbs+=poisson_p[i]; } - /*for(int i=fg->left-1; i>=0; i--) { + for(int i=fg->left-1; i>=0; i--) { poisson_p[i] = poisson_p[i+1]*((i+1)/(lambdaT)); sumOfPoissonProbs+=poisson_p[i]; - }*/ + } iter_num = fg->right; From e0b5fa51c4c9fe27df1d4535b70ab96595da7e7c Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Fri, 1 Dec 2017 13:26:26 +0100 Subject: [PATCH 25/46] new FoxGlynn not included yet --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index fc329c1e7..6bb648e5f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -456,7 +456,6 @@ namespace storm { return goalStates; } - std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { template ::SupportsExponential, int>::type=0> storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCycles(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ @@ -666,7 +665,7 @@ namespace storm { // calculate poisson distribution - std::tuple> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff( + /*std::tuple> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff( T * lambda, 1e+300, epsilon * epsilon * kappa); @@ -674,7 +673,7 @@ namespace storm { for (auto &element : std::get<3>(foxGlynnResult)) { element /= std::get<2>(foxGlynnResult); } - +*/ std::vector poisson = foxGlynnProb(lambda*T, N+1, epsilon*kappa); From 382bc61d6b072d2f6f4845d95bf632c776a4a5a3 Mon Sep 17 00:00:00 2001 From: dehnert Date: Fri, 1 Dec 2017 14:23:56 +0100 Subject: [PATCH 26/46] some fixes related to introduction of environments --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 47 +++++++++---------- .../helper/SparseMarkovAutomatonCslHelper.h | 8 ++-- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 6bb648e5f..d72eeee13 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -158,7 +158,7 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } - template::SupportsExponential, int>::type= 0> + template::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::printTransitions(const uint64_t N, ValueType const diff, storm::storage::SparseMatrix const &fullTransitionMatrix, std::vector const &exitRateVector, storm::storage::BitVector const &markovianStates, @@ -234,7 +234,7 @@ namespace storm { template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson){ + void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -242,7 +242,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); + calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } res+=poisson[i]*unifVectors[2][N-1-(i-k)][node]; @@ -253,8 +253,8 @@ namespace storm { - template::SupportsExponential, int>::type= 0> - void SparseMarkovAutomatonCslHelper::calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, + template::SupportsExponential, int>::type> + void SparseMarkovAutomatonCslHelper::calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const &relativeReachability, OptimizationDirection dir, std::vector>> &unifVectors, @@ -312,7 +312,7 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (unifVectors[kind][k+1][to]==-1){ - calculateUnifPlusVector(k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); + calculateUnifPlusVector(env, k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); } res+=element.getValue()*unifVectors[kind][k+1][to]; } @@ -340,7 +340,7 @@ namespace storm { continue; } if (unifVectors[kind][k][to] == -1) { - calculateUnifPlusVector(k, to, kind, lambda, probSize, relativeReachability, dir, + calculateUnifPlusVector(env, k, to, kind, lambda, probSize, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, poisson); } @@ -351,7 +351,7 @@ namespace storm { } } - solver->solveEquations(dir, x, b); + solver->solveEquations(env, dir, x, b); @@ -366,7 +366,7 @@ namespace storm { } - template ::SupportsExponential, int>::type=0> + template ::SupportsExponential, int>::type> uint64_t SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix const& transitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t* counter) { auto const& rowGroupIndice = transitionMatrix.getRowGroupIndices(); @@ -394,7 +394,7 @@ namespace storm { return finish[node]; } - template::SupportsExponential, int>::type= 0> + template::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::identify( storm::storage::SparseMatrix const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const& psiStates) { @@ -433,7 +433,7 @@ namespace storm { std:: cout << "prob States :" << probStates <<" markovian States: " << markStates << " realProb: "<< realProb << " NDM: " << NDM << " Alternating: " << Alternating << "\n"; } - template ::SupportsExponential, int>::type=0> + template ::SupportsExponential, int>::type> storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCyclesGoalStates(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& cycleStates) { storm::storage::BitVector goalStates(cycleStates.size(), false); @@ -457,7 +457,7 @@ namespace storm { } - template ::SupportsExponential, int>::type=0> + template ::SupportsExponential, int>::type> storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCycles(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ storm::storage::BitVector const& probabilisticStates = ~markovianStates; @@ -491,7 +491,7 @@ namespace storm { } - template ::SupportsExponential, int>::type=0> + template ::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates){ auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); @@ -526,7 +526,7 @@ namespace storm { } template::SupportsExponential, int>::type> - std::vector SparseMarkovAutomatonCslHelper::unifPlus(OptimizationDirection dir, + std::vector SparseMarkovAutomatonCslHelper::unifPlus(Environment const& env, OptimizationDirection dir, std::pair const &boundsPair, std::vector const &exitRateVector, storm::storage::SparseMatrix const &transitionMatrix, @@ -615,15 +615,14 @@ namespace storm { } //create equitation solver - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements( - true, dir); + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); std::unique_ptr> solver; if (probSize != 0) { - solver = minMaxLinearEquationSolverFactory.create(probMatrix); + solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); solver->setHasUniqueSolution(); solver->setBounds(storm::utility::zero(), storm::utility::one()); solver->setRequirementsChecked(); @@ -692,13 +691,13 @@ namespace storm { // (5) calculate vectors and maxNorm for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { - calculateUnifPlusVector(k, i, 0, lambda, probSize, relReachability, dir, unifVectors, + calculateUnifPlusVector(env, k, i, 0, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, poisson); - calculateUnifPlusVector(k, i, 2, lambda, probSize, relReachability, dir, unifVectors, + calculateUnifPlusVector(env, k, i, 2, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, poisson); - calculateVu(relReachability, dir, k, i, 1, lambda, probSize, unifVectors, + calculateVu(env, relReachability, dir, k, i, 1, lambda, probSize, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, poisson); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove @@ -728,7 +727,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilitiesImca(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { + std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilitiesImca(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { STORM_LOG_TRACE("Using IMCA's technique to compute bounded until probabilities."); uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); @@ -793,15 +792,15 @@ namespace storm { } template ::SupportsExponential, int>::type> - std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { + std::vector SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory) { auto const& markovAutomatonSettings = storm::settings::getModule(); if (markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::Imca) { - return computeBoundedUntilProbabilitiesImca(dir, transitionMatrix, exitRateVector, markovianStates, psiStates, boundsPair, minMaxLinearEquationSolverFactory); + return computeBoundedUntilProbabilitiesImca(env, dir, transitionMatrix, exitRateVector, markovianStates, psiStates, boundsPair, minMaxLinearEquationSolverFactory); } else { STORM_LOG_ASSERT(markovAutomatonSettings.getTechnique() == storm::settings::modules::MarkovAutomatonSettings::BoundedReachabilityTechnique::UnifPlus, "Unknown solution technique."); - return unifPlus(dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); + return unifPlus(env, dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates, minMaxLinearEquationSolverFactory); } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 73e37cf81..bff568487 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -30,13 +30,13 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static std::vector unifPlus(OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); + static std::vector unifPlus(Environment const& env, OptimizationDirection dir, std::pair const& boundsPair, std::vector const& exitRateVector, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); template ::SupportsExponential, int>::type = 0> static std::vector computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); template ::SupportsExponential, int>::type = 0> - static std::vector computeBoundedUntilProbabilitiesImca(OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); + static std::vector computeBoundedUntilProbabilitiesImca(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); template ::SupportsExponential, int>::type = 0> static std::vector computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); @@ -62,7 +62,7 @@ namespace storm { static void identify(storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,storm::storage::BitVector const& psiStates); template ::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson); + static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson); template ::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -421,7 +421,7 @@ remark : * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson); + static void calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson); From a77b0267f8e9d3defbb6d78e04c536e21a90ccb4 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Fri, 1 Dec 2017 20:10:48 +0100 Subject: [PATCH 27/46] using the new version of FoxGlynn --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 35 +- .../helper/SparseMarkovAutomatonCslHelper.h | 324 ------------------ 2 files changed, 10 insertions(+), 349 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index d72eeee13..529ce05b0 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -219,20 +219,6 @@ namespace storm { } } - template - ValueType SparseMarkovAutomatonCslHelper::poisson(ValueType lambda, uint64_t i) { - ValueType res = pow(lambda, i); - ValueType fac = 1; - for (uint64_t j = i ; j>0 ; j--){ - fac = fac *j; - } - res = res / fac ; - res = res * exp(-lambda); - return res; - } - - - template ::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. @@ -245,7 +231,9 @@ namespace storm { calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } - res+=poisson[i]*unifVectors[2][N-1-(i-k)][node]; + if (i(); for (uint64_t i = k ; i1e-300){ + if (i> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff( - T * lambda, 1e+300, epsilon * epsilon * kappa); + storm::utility::numerical::FoxGlynnResult foxGlynnResult = storm::utility::numerical::foxGlynn(lambda*T, epsilon*kappa); // Scale the weights so they add up to one. - for (auto &element : std::get<3>(foxGlynnResult)) { - element /= std::get<2>(foxGlynnResult); + for (auto& element : foxGlynnResult.weights) { + element /= foxGlynnResult.totalWeight; } -*/ - std::vector poisson = foxGlynnProb(lambda*T, N+1, epsilon*kappa); // (4) define vectors/matrices std::vector init(numberOfStates, -1); @@ -693,13 +678,13 @@ namespace storm { for (uint64_t k = N; k <= N; k--) { calculateUnifPlusVector(env, k, i, 0, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - poisson); + foxGlynnResult.weights); calculateUnifPlusVector(env, k, i, 2, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - poisson); + foxGlynnResult.weights); calculateVu(env, relReachability, dir, k, i, 1, lambda, probSize, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - poisson); + foxGlynnResult.weights); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index bff568487..2b62d244f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -88,330 +88,6 @@ namespace storm { //TODO: move this - typedef struct FoxGlynn - { - int left; - int right; - double total_weight; - double *weights; - } FoxGlynn; - - static std::vector foxGlynnProb(double lambdaT, int N, double precision){ - - FoxGlynn* fg = NULL; - if(!fox_glynn(lambdaT, DBL_MIN, DBL_MAX, precision, &fg)) { - printf("ERROR: fox-glynn failed\n"); - return std::vector{}; - } - - long double sumOfPoissonProbs = 0.0; - std::vector poisson_p(N,0.0); - unsigned long iter_num; - - std::cout << "fg left " << fg->left << " fh right " << fg->right <<"\n"; - //for(int i=fg->left; i<=fg->right; i++) { - for (int i = 0; iweights[i-fg->left]/fg->total_weight; - sumOfPoissonProbs+=poisson_p[i]; - } - - for(int i=fg->left-1; i>=0; i--) { - poisson_p[i] = poisson_p[i+1]*((i+1)/(lambdaT)); - sumOfPoissonProbs+=poisson_p[i]; - } - - iter_num = fg->right; - - freeFG(fg); - - return poisson_p; - } - - static bool finder(const int m, const double lambda, const double tau, const double omega, - const double epsilon, double * pw_m, FoxGlynn *pFG) - { - /*The pi constant*/ - static const double pi = 3.14159265358979323846264; - static const double lambda_25 = 25.0; - static const double lambda_400 = 40; - - const double sqrt_2_pi = sqrt( 2.0 * pi ); - const double sqrt_2 = sqrt(2.0); - const double sqrt_lambda = sqrt(lambda); - double lambda_max, k, k_rtp = HUGE_VAL, k_prime, c_m_inf, result, al, dkl, bl; - - /*Simple bad cases, when we quit*/ - if( lambda == 0.0 ) - { - printf("ERROR: Fox-Glynn: lambda = 0, terminating the algorithm\n"); - return false; - } - /* The requested error level must not be smaller than the minimum machine precision - (needed to guarantee the convergence of the error conditions) */ - if( epsilon < tau) - { - printf("ERROR: Fox-Glynn: epsilon < tau, invalid error level, terminating the algorithm\n"); - printf("epsilon %f, tau %f\n",epsilon,tau); - return false; - } - /* zero is used as left truncation point for lambda <= 25 */ - pFG->left = 0; - lambda_max = lambda; - - /* for lambda below 25 the exponential can be smaller than tau */ - /* if that is the case we expect underflows and warn the user */ - if( 0.0 < lambda && lambda <= lambda_25 ) - { - if( exp( -lambda ) <= tau ) - { - printf("ERROR: Fox-Glynn: 0 < lambda < 25, underflow. The results are UNRELIABLE.\n"); - } - } - - bl = (1.0 + 1.0/lambda) * exp(1.0 / (8.0 * lambda)); - - /****Compute pFG->right truncation point****/ - /*According to Fox-Glynn, if lambda < 400 we should take lambda = 400, - otherwise use the original value. This is for computing the right truncation point*/ - if(lambda < lambda_400) - lambda_max = lambda_400; - k = 4; - al = (1.0+1.0/lambda_max) * exp(1.0/16.0) * sqrt_2; - dkl = exp(-2.0/9.0 * (k * sqrt(2.0 * lambda_max) + 1.5 )); - dkl = 1.0 / (1.0 - dkl); - /* find right truncation point */ - - /* This loop is a modification to the original Fox-Glynn paper. - The search for the right truncation point is only terminated by - the error condition and not by the stop index from the FG paper. - This can yield more accurate results if neccesary.*/ - while((epsilon/2.0) < ((al * dkl * exp(-(k*k)/2.0))/(k*sqrt_2_pi))) - { - k++; - dkl = exp(-2.0/9.0 * (k * sqrt_2 * sqrt(lambda_max) + 1.5 )); - dkl = 1.0 / (1.0 - dkl); - } - k_rtp = k; - pFG->right = (int)ceil(m + k_rtp * sqrt_2 * sqrt(lambda_max) + 1.5 ); - - - /****Compute pFG->left truncation point****/ - /* compute the left truncation point for lambda > 25 */ - /* for lambda <= 25 we use zero as left truncation point */ - if(lambda > lambda_25) - { - /*Start looking for the left truncation point*/ - /* start search at k=4 (taken from original Fox-Glynn paper */ - k = 4; - /* increase the left truncation point as long as we fulfill the error condition */ - - /* This loop is a modification to the original Fox-Glynn paper. - The search for the left truncation point is only terminated by - the error condition and not by the stop index from the FG paper. - This can yield more accurate results if neccesary.*/ - while((epsilon/2.0) < ((bl * exp(-(k*k)/2.0))/(k * sqrt_2_pi))) - k++; - /*Finally the left truncation point is found*/ - pFG->left = (int)floor(m - k*sqrt(lambda)- 1.5 ); - /* for small lambda the above calculation can yield negative truncation points, crop them here */ - if(pFG->left < 0) - pFG->left = 0; - /* perform underflow check */ - k_prime = k + 3.0 / (2.0 * sqrt_lambda); - /*We take the c_m_inf = 0.02935 / sqrt( m ), as for lambda >= 25 - c_m = 1 / ( sqrt( 2.0 * pi * m ) ) * exp( m - lambda - 1 / ( 12.0 * m ) ) => c_m_inf*/ - c_m_inf = 0.02935 / sqrt((double) m); - result = 0.0; - if( 0.0 < k_prime && k_prime <= sqrt_lambda / 2.0 ) - { - result = c_m_inf * exp( - pow(k_prime,2.0) / 2.0 - pow(k_prime, 3.0) / (3.0 * sqrt_lambda) ); - } - else - { - if( k_prime <= sqrt( m + 1.0 ) / m ) - { - double result_1 = c_m_inf * pow( - 1.0 - k_prime / sqrt((double) (m + 1)), - k_prime * sqrt((double) (m + 1))); - double result_2 = exp( - lambda ); - /*Take the maximum*/ - result = ( result_1 > result_2 ? result_1 : result_2); - } - else - { - /*NOTE: It will be an underflow error*/; - printf("ERROR: Fox-Glynn: lambda >= 25, underflow. The results are UNRELIABLE.\n"); - } - } - if ( result * omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ) <= tau ) - { - printf("ERROR: Fox-Glynn: lambda >= 25, underflow. The results are UNRELIABLE.\n"); - } - } - - - - /*We still have to perform an underflow check for the right truncation point when lambda >= 400*/ - if( lambda >= lambda_400 ) - { - k_prime = k_rtp * sqrt_2 + 3.0 / (2.0 * sqrt_lambda); - /*We take the c_m_inf = 0.02935 / sqrt( m ), as for lambda >= 25 - c_m = 1 / ( sqrt( 2.0 * pi * m ) ) * exp( m - lambda - 1 / ( 12.0 * m ) ) => c_m_inf*/ - c_m_inf = 0.02935 / sqrt((double) m); - result = c_m_inf * exp( - pow( k_prime + 1.0 , 2.0 ) / 2.0 ); - if( result * omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ) <= tau) - { - printf("ERROR: Fox-Glynn: lambda >= 400, underflow. The results are UNRELIABLE.\n"); - } - } - /*Time to set the initial value for weights*/ - *pw_m = omega / ( 1.0e+10 * ( pFG->right - pFG->left ) ); - - return true; - } - -/***************************************************************************** -Name : weighter -Role : The WEIGHTER function from the Fox-Glynn algorithm -@param : double lambda: (rate of uniformization)*(mission time) -@param : double tau: underflow -@param : double omega: overflow -@param : double epsilon: error bound -@param : FoxGlynn *: return by reference -@return : TRUE if everything is fine, otherwise FALSE. - This is the F parameter of Fox-Glynn finder function. -remark : -******************************************************************************/ - static bool weighter(const double lambda, const double tau, const double omega, const double epsilon, FoxGlynn *pFG) - { - static const double pi = 3.14159265358979323846264; - static const double lambda_25 = 25.0; - static const double lambda_400 = 40; - /*The magic m point*/ - const int m = (int)floor(lambda); - double w_m = 0; - int j, s, t; - - if( ! finder( m, lambda, tau, omega, epsilon, &w_m, pFG ) ) - return false; - - /*Allocate space for weights*/ - pFG->weights = (double *) calloc((size_t) (pFG->right - pFG->left + 1), - sizeof(double)); - /*Set an initial weight*/ - pFG->weights[ m - pFG->left ] = w_m; - - /*Fill the left side of the array*/ - for( j = m; j > pFG->left; j-- ) - pFG->weights[ ( j - pFG->left ) - 1 ] = ( j / lambda ) * pFG->weights[ j - pFG->left ]; - - /*Fill the right side of the array, have two cases lambda < 400 & lambda >= 400*/ - if( lambda < lambda_400 ) - { - /*Perform the underflow check, according to Fox-Glynn*/ - if( pFG->right > 600 ) - { - printf("ERROR: Fox-Glynn: pFG->right > 600, underflow is possible\n"); - return false; - } - /*Compute weights*/ - for( j = m; j < pFG->right; j++ ) - { - double q = lambda / ( j + 1 ); - if( pFG->weights[ j - pFG->left ] > tau / q ) - { - pFG->weights[ ( j - pFG->left ) + 1 ] = q * pFG->weights[ j - pFG->left ]; - }else{ - pFG->right = j; - break; /*It's time to compute W*/ - } - } - }else{ - /*Compute weights*/ - for( j = m; j < pFG->right; j++ ) - pFG->weights[ ( j - pFG->left ) + 1 ] = ( lambda / ( j + 1 ) ) * pFG->weights[ j - pFG->left ]; - } - - /*It is time to compute the normalization weight W*/ - pFG->total_weight = 0.0; - s = pFG->left; - t = pFG->right; - - while( s < t ) - { - if( pFG->weights[ s - pFG->left ] <= pFG->weights[ t - pFG->left ] ) - { - pFG->total_weight += pFG->weights[ s - pFG->left ]; - s++; - }else{ - pFG->total_weight += pFG->weights[ t - pFG->left ]; - t--; - } - } - pFG->total_weight += pFG->weights[ s - pFG->left ]; - - /* printf("Fox-Glynn: ltp = %d, rtp = %d, w = %10.15le \n", pFG->left, pFG->right, pFG->total_weight); */ - - return true; - } - -/***************************************************************************** -Name : fox_glynn -Role : get poisson probabilities. -@param : double lambda: (rate of uniformization)*(mission time) -@param : double tau: underflow -@param : double omega: overflow -@param : double epsilon: error bound -@param : FoxGlynn **: return a new FoxGlynn structure by reference -@return : TRUE if it worked fine, otherwise false -remark : -******************************************************************************/ - static bool fox_glynn(const double lambda, const double tau, const double omega, const double epsilon, FoxGlynn **ppFG) - { - /* printf("Fox-Glynn: lambda = %3.3le, epsilon = %1.8le\n",lambda, epsilon); */ - - *ppFG = (FoxGlynn *) calloc((size_t) 1, sizeof(FoxGlynn)); - (*ppFG)->weights = NULL; - - return weighter(lambda, tau, omega, epsilon, *ppFG); - } - - -/** -* Fries the memory allocated for the FoxGlynn structure -* @param fg the structure to free -*/ - static void freeFG(FoxGlynn * fg) - { - if( fg ){ - if( fg->weights ) - free(fg->weights); - free(fg); - } - } - - /*! - * Computes the poission-distribution - * - * - * @param parameter lambda to use - * @param point i - * TODO: replace with Fox-Lynn - * @return the probability - */ - - - /*! - * Computes the poission-distribution - * - * - * @param parameter lambda to use - * @param point i - * TODO: replace with Fox-glynn - * @return the probability - */ - template - static ValueType poisson(ValueType lambda, uint64_t i); template ::SupportsExponential, int>::type=0> static uint64_t trajans(storm::storage::SparseMatrix const& TransitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t * counter); From d79b4caf9e0aa42a4125bdcc21ae4a4dd42ca747 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sat, 2 Dec 2017 16:19:58 +0100 Subject: [PATCH 28/46] new implementation of relReachability to avoid waste of memory --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 529ce05b0..60c00b5fb 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -223,7 +223,7 @@ namespace storm { void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; - auto rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ @@ -258,9 +258,8 @@ namespace storm { } std::string print = std::string("calculating vector ") + std::to_string(kind) + " for k = " + std::to_string(k) + " node " + std::to_string(node) +" \t"; - auto probabilisticStates = ~markovianStates; - auto numberOfProbStates = probabilisticStates.getNumberOfSetBits(); auto numberOfStates=fullTransitionMatrix.getRowGroupCount(); + auto numberOfProbStates = numberOfStates - markovianStates.getNumberOfSetBits(); uint64_t N = unifVectors[kind].size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); ValueType res; @@ -310,7 +309,7 @@ namespace storm { } //probabilistic non-goal State - if (probabilisticStates[node]){ + if (!markovianStates[node]){ std::vector b(probSize, 0), x(numberOfProbStates,0); //calculate b uint64_t lineCounter=0; @@ -321,10 +320,11 @@ namespace storm { auto rowStart = rowGroupIndices[i]; auto rowEnd = rowGroupIndices[i + 1]; for (auto j = rowStart; j < rowEnd; j++) { + uint64_t stateCount = 0; res = 0; for (auto &element:fullTransitionMatrix.getRow(j)) { auto to = element.getColumn(); - if (probabilisticStates[to]) { + if (!markovianStates[to]) { continue; } if (unifVectors[kind][k][to] == -1) { @@ -332,7 +332,8 @@ namespace storm { unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, poisson); } - res = res + relativeReachability[j][to] * unifVectors[kind][k][to]; + res = res + relativeReachability[j][stateCount] * unifVectors[kind][k][to]; + stateCount++; } b[lineCounter] = res; lineCounter++; @@ -344,7 +345,7 @@ namespace storm { for (uint64_t i =0 ; i(); ValueType oldDiff = -storm::utility::zero(); @@ -535,7 +537,6 @@ namespace storm { //vectors to save calculation - std::vector> vd, vu, wu; std::vector>> unifVectors{}; @@ -552,7 +553,7 @@ namespace storm { typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix( true, allStates, allStates, true); // delete diagonals - deleteProbDiagonals(fullTransitionMatrix, markovianStates); + deleteProbDiagonals(fullTransitionMatrix, markovianStates); typename storm::storage::SparseMatrix probMatrix{}; uint64_t probSize = 0; if (probabilisticStates.getNumberOfSetBits() != 0) { //work around in case there are no prob states @@ -579,24 +580,23 @@ namespace storm { //calculate relative ReachabilityVectors - std::vector in(numberOfStates, 0); - std::vector> relReachability(fullTransitionMatrix.getRowCount(), in); + std::vector in{}; + std::vector> relReachability(transitionMatrix.getRowCount(), in); //calculate relative reachability for (uint64_t i = 0; i < numberOfStates; i++) { - if (markovianStates[i]) { + if (markovStates[i]) { continue; } auto from = rowGroupIndices[i]; auto to = rowGroupIndices[i + 1]; for (auto j = from; j < to; j++) { - std::vector &act = relReachability[j]; - for (auto element: fullTransitionMatrix.getRow(j)) { - if (markovianStates[element.getColumn()]) { - act[element.getColumn()] = element.getValue(); + for (auto& element: fullTransitionMatrix.getRow(j)) { + if (markovStates[element.getColumn()]) { + relReachability[j].push_back(element.getValue()); } } } @@ -618,6 +618,7 @@ namespace storm { } // while not close enough to precision: do { + logfile << "starting iteration\n"; maxNorm = storm::utility::zero(); // (2) update parameter N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); @@ -663,14 +664,12 @@ namespace storm { // (4) define vectors/matrices std::vector init(numberOfStates, -1); - vd = std::vector>(N + 1, init); - vu = std::vector>(N + 1, init); - wu = std::vector>(N + 1, init); + std::vector> v = std::vector>(N + 1, init); unifVectors.clear(); - unifVectors.push_back(vd); - unifVectors.push_back(vd); - unifVectors.push_back(vd); + unifVectors.push_back(v); + unifVectors.push_back(v); + unifVectors.push_back(v); //define 0=vd 1=vu 2=wu // (5) calculate vectors and maxNorm From f5a9a51511340b7448c0905948d1f39187779835 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sat, 2 Dec 2017 16:41:12 +0100 Subject: [PATCH 29/46] removed logfileprints --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 60c00b5fb..c68302797 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -266,7 +266,7 @@ namespace storm { // First Case, k==N, independent from kind of state if (k==N){ - logfile << print << "k == N! res = 0\n"; + //logfile << print << "k == N! res = 0\n"; unifVectors[kind][k][node]=0; return; } @@ -287,7 +287,7 @@ namespace storm { // WU unifVectors[kind][k][node]=1; } - logfile << print << "goal state node " << node << " res = " << res << "\n"; + //logfile << print << "goal state node " << node << " res = " << res << "\n"; return; } @@ -304,7 +304,7 @@ namespace storm { res+=element.getValue()*unifVectors[kind][k+1][to]; } unifVectors[kind][k][node]=res; - logfile << print << "markovian state: " << " res = " << res << "\n"; + //logfile << print << "markovian state: " << " res = " << res << "\n"; return; } @@ -349,7 +349,7 @@ namespace storm { unifVectors[kind][k][trueI]=x[i]; } - logfile << print << "probabilistic state: "<< " res = " << unifVectors[kind][k][node] << " but calculated more \n"; + //logfile << print << "probabilistic state: "<< " res = " << unifVectors[kind][k][node] << " but calculated more \n"; } //end probabilistic states } @@ -526,7 +526,7 @@ namespace storm { std::ofstream logfile("U+logfile.txt", std::ios::app); - logfile << "Using U+\n"; + //logfile << "Using U+\n"; ValueType maxNorm = storm::utility::zero(); ValueType oldDiff = -storm::utility::zero(); @@ -618,7 +618,7 @@ namespace storm { } // while not close enough to precision: do { - logfile << "starting iteration\n"; + //logfile << "starting iteration\n"; maxNorm = storm::utility::zero(); // (2) update parameter N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); @@ -689,7 +689,7 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda From 7148319243374facb369b89b22f14c5c120fa59e Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sat, 2 Dec 2017 16:44:25 +0100 Subject: [PATCH 30/46] typo --- .../modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index c68302797..e1a6b3375 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -690,7 +690,7 @@ namespace storm { } } //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove + // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda From 4b2ddf3c6f01917c03a2f7e0edb2cb00f7f2b5ea Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sat, 9 Dec 2017 16:06:55 +0100 Subject: [PATCH 31/46] leaving probloop deletion --- .../modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index e1a6b3375..450af4410 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -553,7 +553,7 @@ namespace storm { typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix( true, allStates, allStates, true); // delete diagonals - deleteProbDiagonals(fullTransitionMatrix, markovianStates); + //deleteProbDiagonals(fullTransitionMatrix, markovianStates); //for now leaving this out typename storm::storage::SparseMatrix probMatrix{}; uint64_t probSize = 0; if (probabilisticStates.getNumberOfSetBits() != 0) { //work around in case there are no prob states From fcd91ecb303ed29d06982b97df233afa871c55d2 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sun, 10 Dec 2017 15:11:53 +0100 Subject: [PATCH 32/46] fixed typo --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 450af4410..e9b2edfc5 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -588,14 +588,14 @@ namespace storm { //calculate relative reachability for (uint64_t i = 0; i < numberOfStates; i++) { - if (markovStates[i]) { + if (markovianStates[i]) { continue; } auto from = rowGroupIndices[i]; auto to = rowGroupIndices[i + 1]; for (auto j = from; j < to; j++) { for (auto& element: fullTransitionMatrix.getRow(j)) { - if (markovStates[element.getColumn()]) { + if (markovianStates[element.getColumn()]) { relReachability[j].push_back(element.getValue()); } } From 79ba044c496be8e3147c4068032d42ddc6b34f3f Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Tue, 12 Dec 2017 13:34:47 +0100 Subject: [PATCH 33/46] prints --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index e9b2edfc5..93758ee94 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -661,6 +661,13 @@ namespace storm { element /= foxGlynnResult.totalWeight; } + ValueType leftSum=0; + for (int i =0 ; i< foxGlynnResult.left; i++){ + leftSum += foxGlynnResult.weights[i]; + std::cout << foxGlynnResult.weights[i] << "\n"; + } + std::cout<< "sum Left is " << leftSum <<"\n"; + // (4) define vectors/matrices std::vector init(numberOfStates, -1); From 9dda579e58773f894d81cf74bfac267f171c47ea Mon Sep 17 00:00:00 2001 From: dehnert Date: Wed, 13 Dec 2017 16:18:13 +0100 Subject: [PATCH 34/46] slightly patched Fox-Glynn --- src/storm/utility/numerical.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/storm/utility/numerical.cpp b/src/storm/utility/numerical.cpp index cec474ff7..9c17928ab 100644 --- a/src/storm/utility/numerical.cpp +++ b/src/storm/utility/numerical.cpp @@ -229,6 +229,7 @@ namespace storm { } else { t = j; result.right = j + result.left; + result.weights.resize(result.right - result.left + 1); // It's time to compute W. break; @@ -257,7 +258,7 @@ namespace storm { } result.totalWeight += result.weights[j]; - STORM_LOG_TRACE("Fox-Glynn: ltp = " << result.left << ", rtp = " << result.right << ", w = " << result.totalWeight << "."); + STORM_LOG_TRACE("Fox-Glynn: ltp = " << result.left << ", rtp = " << result.right << ", w = " << result.totalWeight << ", " << result.weights.size() << " weights."); return result; } From 95c12cf6d8a60539c89354afa04bdef9bb37c6a7 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Wed, 13 Dec 2017 16:25:29 +0100 Subject: [PATCH 35/46] new use of FixGlynn --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 37 +++++++++---------- .../helper/SparseMarkovAutomatonCslHelper.h | 5 ++- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 93758ee94..b64a04459 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -22,7 +22,7 @@ #include "storm/storage/expressions/Expression.h" #include "storm/storage/expressions/ExpressionManager.h" -#include "storm/utility/numerical.h" +//#include "storm/utility/numerical.h" #include "storm/solver/MinMaxLinearEquationSolver.h" #include "storm/solver/LpSolver.h" @@ -220,7 +220,7 @@ namespace storm { } template ::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson){ + void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -231,8 +231,8 @@ namespace storm { calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } - if (i=poisson.left && i<=poisson.right){ + res+=poisson.weights[i-poisson.left]*unifVectors[2][N-1-(i-k)][node]; } } unifVectors[1][k][node]=res; @@ -249,7 +249,7 @@ namespace storm { storm::storage::SparseMatrix const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr> const &solver, std::ofstream& logfile, std::vector const& poisson) { + std::unique_ptr> const &solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson) { if (unifVectors[kind][k][node]!=-1){ @@ -277,8 +277,8 @@ namespace storm { // Vd res = storm::utility::zero(); for (uint64_t i = k ; i=poisson.left && i<=poisson.right){ + ValueType between = poisson.weights[i-poisson.left]; res+=between; } } @@ -621,7 +621,6 @@ namespace storm { //logfile << "starting iteration\n"; maxNorm = storm::utility::zero(); // (2) update parameter - N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); // (3) uniform - just applied to markovian states for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { @@ -655,18 +654,18 @@ namespace storm { storm::utility::numerical::FoxGlynnResult foxGlynnResult = storm::utility::numerical::foxGlynn(lambda*T, epsilon*kappa); + N = std::max(ceil(lambda * T * exp(2) - log(kappa * epsilon)), ceil(foxGlynnResult.right - foxGlynnResult.left +1 )); // Scale the weights so they add up to one. for (auto& element : foxGlynnResult.weights) { element /= foxGlynnResult.totalWeight; } - ValueType leftSum=0; - for (int i =0 ; i< foxGlynnResult.left; i++){ - leftSum += foxGlynnResult.weights[i]; - std::cout << foxGlynnResult.weights[i] << "\n"; + ValueType sum = 0; + for (auto i = foxGlynnResult.left ; i<=foxGlynnResult.right; i++){ + sum+=foxGlynnResult.weights[i-foxGlynnResult.left]; } - std::cout<< "sum Left is " << leftSum <<"\n"; + std::cout << " left " << foxGlynnResult.left << " right " << foxGlynnResult.right << " size " << foxGlynnResult.weights.size() << " sum " << sum << "\n"; // (4) define vectors/matrices @@ -684,20 +683,20 @@ namespace storm { for (uint64_t k = N; k <= N; k--) { calculateUnifPlusVector(env, k, i, 0, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult.weights); + foxGlynnResult); calculateUnifPlusVector(env, k, i, 2, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult.weights); + foxGlynnResult); calculateVu(env, relReachability, dir, k, i, 1, lambda, probSize, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult.weights); + foxGlynnResult); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); maxNorm = std::max(maxNorm, diff); } } - //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove + printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda @@ -706,7 +705,7 @@ namespace storm { // (7) escape if not coming closer to solution if (oldDiff != -1) { if (oldDiff == maxNorm) { - std::cout << "Not coming closer to solution as " << maxNorm << "/n"; + std::cout << "Not coming closer to solution as " << maxNorm << "\n"; break; } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 2b62d244f..ac005ce38 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -1,6 +1,7 @@ #ifndef STORM_MODELCHECKER_SPARSE_MARKOVAUTOMATON_CSL_MODELCHECKER_HELPER_H_ #define STORM_MODELCHECKER_SPARSE_MARKOVAUTOMATON_CSL_MODELCHECKER_HELPER_H_ +#include #include "storm/storage/BitVector.h" #include "storm/storage/MaximalEndComponent.h" #include "storm/solver/OptimizationDirection.h" @@ -62,7 +63,7 @@ namespace storm { static void identify(storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,storm::storage::BitVector const& psiStates); template ::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson); + static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson); template ::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -97,7 +98,7 @@ namespace storm { * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, std::vector const& poisson); + static void calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson); From cc8b6f6af0a6ec60f5c43b7792722e3fac2e96fc Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Wed, 13 Dec 2017 21:04:58 +0100 Subject: [PATCH 36/46] fixed stupid uniformisation bug --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index b64a04459..b427bcfbd 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -570,15 +570,12 @@ namespace storm { double T = boundsPair.second; ValueType kappa = storm::utility::one() / 10; // would be better as option-parameter ValueType epsilon = storm::settings::getModule().getPrecision(); - ValueType lambda = exitRateVector[0]; - for (ValueType act: exitRateVector) { + ValueType lambda = exitRate[0]; + for (ValueType act: exitRate) { lambda = std::max(act, lambda); } uint64_t N; - - - //calculate relative ReachabilityVectors std::vector in{}; std::vector> relReachability(transitionMatrix.getRowCount(), in); @@ -621,10 +618,11 @@ namespace storm { //logfile << "starting iteration\n"; maxNorm = storm::utility::zero(); // (2) update parameter + N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); // (3) uniform - just applied to markovian states - for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { - if (!markovianStates[i]) { + for (uint64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + if (!markovianStates[i] || psiStates[i]) { continue; } uint64_t from = rowGroupIndices[i]; //markovian state -> no Nondeterminism -> only one row @@ -638,7 +636,7 @@ namespace storm { ValueType exitNew = lambda; for (auto &v : line) { if (v.getColumn() == i) { //diagonal element - ValueType newSelfLoop = exitNew - exitOld + v.getValue(); + ValueType newSelfLoop = exitNew - exitOld + v.getValue()*exitOld; ValueType newRate = newSelfLoop / exitNew; v.setValue(newRate); } else { //modify probability @@ -654,8 +652,6 @@ namespace storm { storm::utility::numerical::FoxGlynnResult foxGlynnResult = storm::utility::numerical::foxGlynn(lambda*T, epsilon*kappa); - N = std::max(ceil(lambda * T * exp(2) - log(kappa * epsilon)), ceil(foxGlynnResult.right - foxGlynnResult.left +1 )); - // Scale the weights so they add up to one. for (auto& element : foxGlynnResult.weights) { element /= foxGlynnResult.totalWeight; @@ -695,8 +691,8 @@ namespace storm { maxNorm = std::max(maxNorm, diff); } } - printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove + //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda From e5f71aa851431aaa5bc414d2053be0b771c8b9c1 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Tue, 19 Dec 2017 10:30:09 +0100 Subject: [PATCH 37/46] prints for foxGlynn --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index b427bcfbd..ad8c44b0f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -193,7 +193,8 @@ namespace storm { logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; } - logfile << "Iteration for N = " << N << "maximal difference was " << diff << "\n"; + logfile << "Iteration for N = " << N << " maximal difference was " << diff << "\n"; + logfile << "vd: \n"; for (uint64_t i =0 ; i foxGlynnResult = storm::utility::numerical::foxGlynn(lambda*T, epsilon*kappa); + storm::utility::numerical::FoxGlynnResult foxGlynnResult = storm::utility::numerical::foxGlynn(lambda*T, epsilon*kappa/100); // Scale the weights so they add up to one. for (auto& element : foxGlynnResult.weights) { @@ -660,6 +661,8 @@ namespace storm { ValueType sum = 0; for (auto i = foxGlynnResult.left ; i<=foxGlynnResult.right; i++){ sum+=foxGlynnResult.weights[i-foxGlynnResult.left]; + logfile << i << "\t" << foxGlynnResult.weights[i-foxGlynnResult.left]; + logfile << i << "\t" << sum; } std::cout << " left " << foxGlynnResult.left << " right " << foxGlynnResult.right << " size " << foxGlynnResult.weights.size() << " sum " << sum << "\n"; @@ -706,6 +709,7 @@ namespace storm { } } oldDiff = maxNorm; + std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; } while (maxNorm > epsilon * (1 - kappa)); logfile.close(); From 7577ca48ec8d5d4b03259eab209cd29dd4ac724d Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Tue, 19 Dec 2017 17:17:51 +0100 Subject: [PATCH 38/46] changed loop of diff checking; ; --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index ad8c44b0f..819d684c5 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -690,10 +690,15 @@ namespace storm { fullTransitionMatrix, markovianStates, psiStates, solver, logfile, foxGlynnResult); //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove - ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); - maxNorm = std::max(maxNorm, diff); + //ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); } } + + //only iterate over result vector, as the results can only get more precise + for (uint64_t i = 0; i < numberOfStates; i++){ + ValueType diff = std::abs(unifVectors[0][0][i]-unifVectors[1][0][i]); + maxNorm = std::max(maxNorm, diff); + } //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove From 95c23b50d14d5fed337a69a482d5b4d5b33bf99d Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Tue, 19 Dec 2017 18:26:56 +0100 Subject: [PATCH 39/46] removing log prints again --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 819d684c5..e56e03044 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -658,15 +658,6 @@ namespace storm { element /= foxGlynnResult.totalWeight; } - ValueType sum = 0; - for (auto i = foxGlynnResult.left ; i<=foxGlynnResult.right; i++){ - sum+=foxGlynnResult.weights[i-foxGlynnResult.left]; - logfile << i << "\t" << foxGlynnResult.weights[i-foxGlynnResult.left]; - logfile << i << "\t" << sum; - } - std::cout << " left " << foxGlynnResult.left << " right " << foxGlynnResult.right << " size " << foxGlynnResult.weights.size() << " sum " << sum << "\n"; - - // (4) define vectors/matrices std::vector init(numberOfStates, -1); std::vector> v = std::vector>(N + 1, init); @@ -714,7 +705,7 @@ namespace storm { } } oldDiff = maxNorm; - std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; + //std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; } while (maxNorm > epsilon * (1 - kappa)); logfile.close(); From 0004c9b2bb21d28e9f4e11ef39bca8d6d4967984 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Thu, 21 Dec 2017 01:08:57 +0100 Subject: [PATCH 40/46] adding version with value iteration --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 80 ++++++++----------- 1 file changed, 34 insertions(+), 46 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index e56e03044..a5b70f3d2 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -310,49 +310,36 @@ namespace storm { } //probabilistic non-goal State - if (!markovianStates[node]){ - std::vector b(probSize, 0), x(numberOfProbStates,0); - //calculate b - uint64_t lineCounter=0; - for (int i =0; isolveEquations(env, dir, x, b); - - - - for (uint64_t i =0 ; i fullTransitionMatrix = transitionMatrix.getSubmatrix( true, allStates, allStates, true); // delete diagonals - //deleteProbDiagonals(fullTransitionMatrix, markovianStates); //for now leaving this out + deleteProbDiagonals(fullTransitionMatrix, markovianStates); //for now leaving this out typename storm::storage::SparseMatrix probMatrix{}; uint64_t probSize = 0; if (probabilisticStates.getNumberOfSetBits() != 0) { //work around in case there are no prob states @@ -584,7 +571,7 @@ namespace storm { //calculate relative reachability - + /* for (uint64_t i = 0; i < numberOfStates; i++) { if (markovianStates[i]) { continue; @@ -600,20 +587,21 @@ namespace storm { } } - //create equitation solver + //create equitation solver storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); + requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - + */ std::unique_ptr> solver; - if (probSize != 0) { + /*if (probSize != 0) { solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); solver->setHasUniqueSolution(); solver->setBounds(storm::utility::zero(), storm::utility::one()); solver->setRequirementsChecked(); solver->setCachingEnabled(true); - } + } */ // while not close enough to precision: do { //logfile << "starting iteration\n"; @@ -690,8 +678,8 @@ namespace storm { ValueType diff = std::abs(unifVectors[0][0][i]-unifVectors[1][0][i]); maxNorm = std::max(maxNorm, diff); } - //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove + printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda @@ -705,7 +693,7 @@ namespace storm { } } oldDiff = maxNorm; - //std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; + std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; } while (maxNorm > epsilon * (1 - kappa)); logfile.close(); From 3a94b8ad690864d080a479c8ce189db5649673d4 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Thu, 21 Dec 2017 17:50:54 +0100 Subject: [PATCH 41/46] ignoring kappa, taking in account epsilon --- .../modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index a5b70f3d2..07939614f 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -694,7 +694,7 @@ namespace storm { } oldDiff = maxNorm; std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; - } while (maxNorm > epsilon * (1 - kappa)); + } while (maxNorm > epsilon /* * (1 - kappa)*/); logfile.close(); return unifVectors[0][0]; From b9007aa2e9f78a5a555e6bb81be96c69818b5bcf Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Tue, 2 Jan 2018 10:34:44 +0100 Subject: [PATCH 42/46] removed logprints --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 07939614f..4b419d92e 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -678,8 +678,8 @@ namespace storm { ValueType diff = std::abs(unifVectors[0][0][i]-unifVectors[1][0][i]); maxNorm = std::max(maxNorm, diff); } - printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove + //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, + // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove // (6) double lambda From 0d1de8aba9e929e0b6dc71270066e9cff72db018 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sat, 6 Jan 2018 13:23:20 +0100 Subject: [PATCH 43/46] restructured code, SCC missing --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 303 +++++------------- .../helper/SparseMarkovAutomatonCslHelper.h | 28 +- 2 files changed, 76 insertions(+), 255 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 4b419d92e..ad95dee20 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -158,70 +158,13 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); } - template::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::printTransitions(const uint64_t N, ValueType const diff, - storm::storage::SparseMatrix const &fullTransitionMatrix, - std::vector const &exitRateVector, storm::storage::BitVector const &markovianStates, - storm::storage::BitVector const &psiStates, std::vector> relReachability, - const storage::BitVector &cycleStates, const storage::BitVector &cycleGoalStates, - std::vector>> &unifVectors, std::ofstream& logfile) { - - auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); - - //Transition Matrix - logfile << "number of states = num of row group count " << numberOfStates << "\n"; - for (uint_fast64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { - logfile << " from node " << i << " "; - auto from = rowGroupIndices[i]; - auto to = rowGroupIndices[i+1]; - for (auto j = from ; j < to; j++){ - for (auto &v : fullTransitionMatrix.getRow(j)) { - if (markovianStates[i]){ - logfile << v.getValue() *exitRateVector[i] << " -> "<< v.getColumn() << "\t"; - } else { - logfile << v.getValue() << " -> "<< v.getColumn() << "\t"; - } - } - logfile << "\n"; - } - } - logfile << "\n"; - - logfile << "probStates\tmarkovianStates\tgoalStates\tcycleStates\tcycleGoalStates\n"; - for (int i =0 ; i< markovianStates.size() ; i++){ - logfile << (~markovianStates)[i] << "\t\t" << markovianStates[i] << "\t\t" << psiStates[i] << "\t\t" << cycleStates[i] << "\t\t" << cycleGoalStates[i] << "\n"; - } - - logfile << "Iteration for N = " << N << " maximal difference was " << diff << "\n"; - - logfile << "vd: \n"; - for (uint64_t i =0 ; i::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson){ + void SparseMarkovAutomatonCslHelper::calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, + uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, + std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, + storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, + std::unique_ptr> const& solver, std::ofstream& logfile, + storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); @@ -229,7 +172,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson); + calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson, cycleFree); //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); } if (i>=poisson.left && i<=poisson.right){ @@ -250,7 +193,8 @@ namespace storm { storm::storage::SparseMatrix const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr> const &solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson) { + std::unique_ptr> const &solver, std::ofstream& logfile, + storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree) { if (unifVectors[kind][k][node]!=-1){ @@ -300,7 +244,7 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (unifVectors[kind][k+1][to]==-1){ - calculateUnifPlusVector(env, k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); + calculateUnifPlusVector(env, k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson, cycleFree); } res+=element.getValue()*unifVectors[kind][k+1][to]; } @@ -310,164 +254,80 @@ namespace storm { } //probabilistic non-goal State - res = -1; - uint64_t rowStart = rowGroupIndices[node]; - uint64_t rowEnd = rowGroupIndices[node+1]; - for (uint64_t i = rowStart; i< rowEnd; i++){ - auto line = fullTransitionMatrix.getRow(i); - ValueType between = 0; - for (auto& element: line){ - uint64_t to = element.getColumn(); - if (to==node){ - continue; - } - if (unifVectors[kind][k][to]==-1){ - calculateUnifPlusVector(env, k,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson); - } - between+=element.getValue()*unifVectors[kind][k][to]; - } - if (maximize(dir)){ - res = std::max(res,between); - } else { - if (res!=-1){ - res = std::min(res,between); - } else { - res = between; - } - } - } - unifVectors[kind][k][node]=res; - //logfile << print << "probabilistic state: "<< " res = " << unifVectors[kind][k][node] << " but calculated more \n"; - - //end probabilistic states - } - - - template ::SupportsExponential, int>::type> - uint64_t SparseMarkovAutomatonCslHelper::trajans(storm::storage::SparseMatrix const& transitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t* counter) { - auto const& rowGroupIndice = transitionMatrix.getRowGroupIndices(); - - disc[node] = *counter; - finish[node] = *counter; - (*counter)+=1; - - auto from = rowGroupIndice[node]; - auto to = rowGroupIndice[node+1]; - - for(uint64_t i =from; i::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::identify( - storm::storage::SparseMatrix const &fullTransitionMatrix, - storm::storage::BitVector const &markovianStates, storm::storage::BitVector const& psiStates) { - auto indices = fullTransitionMatrix.getRowGroupIndices(); - bool realProb = false; - bool NDM = false; - bool Alternating = true; - bool probStates = false; - bool markStates = false; - - for (uint64_t i=0; i::SupportsExponential, int>::type> - storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCyclesGoalStates(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& cycleStates) { - - storm::storage::BitVector goalStates(cycleStates.size(), false); - auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); - - for (uint64_t i = 0 ; i < transitionMatrix.getRowGroupCount() ; i++){ - if (!cycleStates[i]){ + //not cycle free - use solver technique, calling SVI per default + //solving all sub-MDP's in one iteration + std::vector b(probSize, 0), x(numberOfProbStates,0); + //calculate b + uint64_t lineCounter=0; + for (int i =0; i::SupportsExponential, int>::type> - storm::storage::BitVector SparseMarkovAutomatonCslHelper::identifyProbCycles(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates){ - - storm::storage::BitVector const& probabilisticStates = ~markovianStates; - storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~psiStates; - - storm::storage::SparseMatrix const& probMatrix = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, probabilisticNonGoalStates); - uint64_t probSize = probMatrix.getRowGroupCount(); - std::vector disc(probSize, 0), finish(probSize, 0); - - uint64_t counter =1; - - for (uint64_t i =0; isolveEquations(env, dir, x, b); - storm::storage::BitVector cycleStates(markovianStates.size(), false); - for (int i = 0 ; i< finish.size() ; i++){ - auto f = finish[i]; - for (int j =i+1; j::SupportsExponential, int>::type> void SparseMarkovAutomatonCslHelper::deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates){ auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); @@ -512,6 +372,7 @@ namespace storm { storm::solver::MinMaxLinearEquationSolverFactory const &minMaxLinearEquationSolverFactory) { STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + bool cycleFree; std::ofstream logfile("U+logfile.txt", std::ios::app); //logfile << "Using U+\n"; @@ -571,7 +432,6 @@ namespace storm { //calculate relative reachability - /* for (uint64_t i = 0; i < numberOfStates; i++) { if (markovianStates[i]) { continue; @@ -593,15 +453,14 @@ namespace storm { requirements.clearBounds(); STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - */ std::unique_ptr> solver; - /*if (probSize != 0) { + if (probSize != 0) { solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); solver->setHasUniqueSolution(); solver->setBounds(storm::utility::zero(), storm::utility::one()); solver->setRequirementsChecked(); solver->setCachingEnabled(true); - } */ + } // while not close enough to precision: do { //logfile << "starting iteration\n"; @@ -661,15 +520,13 @@ namespace storm { for (uint64_t k = N; k <= N; k--) { calculateUnifPlusVector(env, k, i, 0, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult); + foxGlynnResult, cycleFree); calculateUnifPlusVector(env, k, i, 2, lambda, probSize, relReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult); + foxGlynnResult, cycleFree); calculateVu(env, relReachability, dir, k, i, 1, lambda, probSize, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, logfile, - foxGlynnResult); - //also use iteration to keep maxNorm of vd and vup to date, so the loop-condition is easy to prove - //ValueType diff = std::abs(unifVectors[0][k][i] - unifVectors[1][k][i]); + foxGlynnResult, cycleFree); } } @@ -678,23 +535,11 @@ namespace storm { ValueType diff = std::abs(unifVectors[0][0][i]-unifVectors[1][0][i]); maxNorm = std::max(maxNorm, diff); } - //printTransitions(N, maxNorm, fullTransitionMatrix, exitRate, markovianStates, psiStates, - // relReachability, psiStates, psiStates, unifVectors, logfile); //TODO remove - // (6) double lambda lambda = 2 * lambda; - // (7) escape if not coming closer to solution - if (oldDiff != -1) { - if (oldDiff == maxNorm) { - std::cout << "Not coming closer to solution as " << maxNorm << "\n"; - break; - } - } - oldDiff = maxNorm; - std::cout << "Finished Iteration for N = " << N << " with difference " << maxNorm << "\n"; - } while (maxNorm > epsilon /* * (1 - kappa)*/); + } while (maxNorm > epsilon*(1 - kappa)); logfile.close(); return unifVectors[0][0]; diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index ac005ce38..82492aa6e 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -60,10 +60,7 @@ namespace storm { private: template ::SupportsExponential, int>::type=0> - static void identify(storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates,storm::storage::BitVector const& psiStates); - - template ::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson); + static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree); template ::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); @@ -80,28 +77,12 @@ namespace storm { return id-1; } - template ::SupportsExponential, int>::type=0> - static storm::storage::BitVector identifyProbCyclesGoalStates(storm::storage::SparseMatrix const& transitionMatrix, storm::storage::BitVector const& cycleStates); - - - template ::SupportsExponential, int>::type=0> - static storm::storage::BitVector identifyProbCycles(storm::storage::SparseMatrix const& TransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); - - //TODO: move this - - - template ::SupportsExponential, int>::type=0> - static uint64_t trajans(storm::storage::SparseMatrix const& TransitionMatrix, uint64_t node, std::vector& disc, std::vector& finish, uint64_t * counter); - /* * Computes vu vector according to UnifPlus * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson); - - - + static void calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile @@ -109,11 +90,6 @@ namespace storm { * */ - template ::SupportsExponential, int>::type=0> - static void printTransitions(const uint64_t N, ValueType const diff, storm::storage::SparseMatrix const& fullTransitionMatrix, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, - storm::storage::BitVector const& psiStates, std::vector> relReachability, - storm::storage::BitVector const& cycleStates , storm::storage::BitVector const& cycleGoalStates ,std::vector>>& unifVectors, std::ofstream& logfile); - template ::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector& markovianNonGoalValues, std::vector& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); From 2ea911f86570090b0291dd4f8cb308ad415cd565 Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sat, 6 Jan 2018 17:09:02 +0100 Subject: [PATCH 44/46] finished version of implementation --- .../csl/helper/SparseMarkovAutomatonCslHelper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index ad95dee20..6fee0321e 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -372,19 +372,19 @@ namespace storm { storm::solver::MinMaxLinearEquationSolverFactory const &minMaxLinearEquationSolverFactory) { STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - bool cycleFree; + std::ofstream logfile("U+logfile.txt", std::ios::app); //logfile << "Using U+\n"; ValueType maxNorm = storm::utility::zero(); - ValueType oldDiff = -storm::utility::zero(); //bitvectors to identify different kind of states storm::storage::BitVector markovianStates = markovStates; storm::storage::BitVector allStates(markovianStates.size(), true); storm::storage::BitVector probabilisticStates = ~markovianStates; - + storm::storage::StronglyConnectedComponentDecomposition sccList(transitionMatrix, probabilisticStates, true, false); + bool cycleFree = sccList.size() == 0; //vectors to save calculation std::vector>> unifVectors{}; From 6a52a953c23bfc3683580c16b24d055077a0fddb Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sat, 6 Jan 2018 17:56:47 +0100 Subject: [PATCH 45/46] clean up code --- .../helper/SparseMarkovAutomatonCslHelper.cpp | 114 +++++++++--------- .../helper/SparseMarkovAutomatonCslHelper.h | 23 ++-- 2 files changed, 68 insertions(+), 69 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index 6fee0321e..283814633 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -163,7 +163,7 @@ namespace storm { uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, - std::unique_ptr> const& solver, std::ofstream& logfile, + std::unique_ptr> const& solver, storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree){ if (unifVectors[1][k][node]!=-1){return;} //dynamic programming. avoiding multiple calculation. uint64_t N = unifVectors[1].size()-1; @@ -172,8 +172,7 @@ namespace storm { ValueType res =0; for (uint64_t i = k ; i < N ; i++ ){ if (unifVectors[2][N-1-(i-k)][node]==-1){ - calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, logfile, poisson, cycleFree); - //old: relativeReachability, dir, (N-1-(i-k)),node,lambda,wu,fullTransitionMatrix,markovianStates,psiStates, solver); + calculateUnifPlusVector(env, N-1-(i-k),node,2,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix, markovianStates,psiStates,solver, poisson, cycleFree); } if (i>=poisson.left && i<=poisson.right){ res+=poisson.weights[i-poisson.left]*unifVectors[2][N-1-(i-k)][node]; @@ -193,15 +192,13 @@ namespace storm { storm::storage::SparseMatrix const &fullTransitionMatrix, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, - std::unique_ptr> const &solver, std::ofstream& logfile, + std::unique_ptr> const &solver, storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree) { if (unifVectors[kind][k][node]!=-1){ - //logfile << "already calculated for k = " << k << " node = " << node << "\n"; - return; + return; //already calculated } - std::string print = std::string("calculating vector ") + std::to_string(kind) + " for k = " + std::to_string(k) + " node " + std::to_string(node) +" \t"; auto numberOfStates=fullTransitionMatrix.getRowGroupCount(); auto numberOfProbStates = numberOfStates - markovianStates.getNumberOfSetBits(); @@ -211,12 +208,11 @@ namespace storm { // First Case, k==N, independent from kind of state if (k==N){ - //logfile << print << "k == N! res = 0\n"; unifVectors[kind][k][node]=0; return; } - //goal state + //goal state, independent from kind of state if (psiStates[node]){ if (kind==0){ // Vd @@ -232,9 +228,7 @@ namespace storm { // WU unifVectors[kind][k][node]=1; } - //logfile << print << "goal state node " << node << " res = " << res << "\n"; return; - } //markovian non-goal State @@ -244,12 +238,11 @@ namespace storm { for (auto &element : line){ uint64_t to = element.getColumn(); if (unifVectors[kind][k+1][to]==-1){ - calculateUnifPlusVector(env, k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, logfile, poisson, cycleFree); + calculateUnifPlusVector(env, k+1,to,kind,lambda,probSize,relativeReachability,dir,unifVectors,fullTransitionMatrix,markovianStates,psiStates,solver, poisson, cycleFree); } res+=element.getValue()*unifVectors[kind][k+1][to]; } unifVectors[kind][k][node]=res; - //logfile << print << "markovian state: " << " res = " << res << "\n"; return; } @@ -270,7 +263,7 @@ namespace storm { if (unifVectors[kind][k][to] == -1) { calculateUnifPlusVector(env, k, to, kind, lambda, probSize, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, - solver, logfile, poisson, cycleFree); + solver, poisson, cycleFree); } between += element.getValue() * unifVectors[kind][k][to]; } @@ -310,7 +303,7 @@ namespace storm { if (unifVectors[kind][k][to] == -1) { calculateUnifPlusVector(env, k, to, kind, lambda, probSize, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, - psiStates, solver, logfile, poisson, cycleFree); + psiStates, solver, poisson, cycleFree); } res = res + relativeReachability[j][stateCount] * unifVectors[kind][k][to]; stateCount++; @@ -372,17 +365,12 @@ namespace storm { storm::solver::MinMaxLinearEquationSolverFactory const &minMaxLinearEquationSolverFactory) { STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); - - - std::ofstream logfile("U+logfile.txt", std::ios::app); - //logfile << "Using U+\n"; - ValueType maxNorm = storm::utility::zero(); - //bitvectors to identify different kind of states storm::storage::BitVector markovianStates = markovStates; storm::storage::BitVector allStates(markovianStates.size(), true); storm::storage::BitVector probabilisticStates = ~markovianStates; + //searching for SCC on Underlying MDP to decide which algorhitm is applied storm::storage::StronglyConnectedComponentDecomposition sccList(transitionMatrix, probabilisticStates, true, false); bool cycleFree = sccList.size() == 0; //vectors to save calculation @@ -390,6 +378,7 @@ namespace storm { //transitions from goalStates will be ignored. still: they are not allowed to be probabilistic! + // to make sure we apply our formula and NOT the MDP algorithm for (uint64_t i = 0; i < psiStates.size(); i++) { if (psiStates[i]) { markovianStates.set(i, true); @@ -397,12 +386,15 @@ namespace storm { } } - //transition matrix with diagonal entries. The values can be changed during uniformisation + //transition matrix with extended with diagonal entries. Therefore, the values can be changed during uniformisation + // exitRateVector with changeable exit Rates std::vector exitRate{exitRateVector}; typename storm::storage::SparseMatrix fullTransitionMatrix = transitionMatrix.getSubmatrix( true, allStates, allStates, true); - // delete diagonals - deleteProbDiagonals(fullTransitionMatrix, markovianStates); //for now leaving this out + + + // delete diagonals - needed for VI, not vor SVI + deleteProbDiagonals(fullTransitionMatrix, markovianStates); typename storm::storage::SparseMatrix probMatrix{}; uint64_t probSize = 0; if (probabilisticStates.getNumberOfSetBits() != 0) { //work around in case there are no prob states @@ -411,10 +403,12 @@ namespace storm { probSize = probMatrix.getRowCount(); } + // indices for transition martrix auto &rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); - //(1) define horizon, epsilon, kappa , N, lambda, + + //(1) define/declare horizon, epsilon, kappa , N, lambda, maxNorm uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); double T = boundsPair.second; ValueType kappa = storm::utility::one() / 10; // would be better as option-parameter @@ -424,47 +418,50 @@ namespace storm { lambda = std::max(act, lambda); } uint64_t N; + ValueType maxNorm = storm::utility::zero(); - //calculate relative ReachabilityVectors + //calculate relative ReachabilityVectors and create solver - just needed for cycles std::vector in{}; std::vector> relReachability(transitionMatrix.getRowCount(), in); + std::unique_ptr> solver; - - - //calculate relative reachability - for (uint64_t i = 0; i < numberOfStates; i++) { - if (markovianStates[i]) { - continue; - } - auto from = rowGroupIndices[i]; - auto to = rowGroupIndices[i + 1]; - for (auto j = from; j < to; j++) { - for (auto& element: fullTransitionMatrix.getRow(j)) { - if (markovianStates[element.getColumn()]) { - relReachability[j].push_back(element.getValue()); + if (!cycleFree) { + //calculate relative reachability + for (uint64_t i = 0; i < numberOfStates; i++) { + if (markovianStates[i]) { + continue; + } + auto from = rowGroupIndices[i]; + auto to = rowGroupIndices[i + 1]; + for (auto j = from; j < to; j++) { + for (auto &element: fullTransitionMatrix.getRow(j)) { + if (markovianStates[element.getColumn()]) { + relReachability[j].push_back(element.getValue()); + } } } } - } - //create equitation solver - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); - - requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, - "Cannot establish requirements for solver."); - std::unique_ptr> solver; - if (probSize != 0) { - solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); - solver->setHasUniqueSolution(); - solver->setBounds(storm::utility::zero(), storm::utility::one()); - solver->setRequirementsChecked(); - solver->setCachingEnabled(true); + //create equitation solver + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements( + env, true, dir); + + requirements.clearBounds(); + STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, + "Cannot establish requirements for solver."); + if (probSize != 0) { + solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero(), storm::utility::one()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + } } + // while not close enough to precision: do { - //logfile << "starting iteration\n"; maxNorm = storm::utility::zero(); + // (2) update parameter N = ceil(lambda * T * exp(2) - log(kappa * epsilon)); @@ -519,13 +516,13 @@ namespace storm { for (uint64_t i = 0; i < numberOfStates; i++) { for (uint64_t k = N; k <= N; k--) { calculateUnifPlusVector(env, k, i, 0, lambda, probSize, relReachability, dir, unifVectors, - fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + fullTransitionMatrix, markovianStates, psiStates, solver, foxGlynnResult, cycleFree); calculateUnifPlusVector(env, k, i, 2, lambda, probSize, relReachability, dir, unifVectors, - fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + fullTransitionMatrix, markovianStates, psiStates, solver, foxGlynnResult, cycleFree); calculateVu(env, relReachability, dir, k, i, 1, lambda, probSize, unifVectors, - fullTransitionMatrix, markovianStates, psiStates, solver, logfile, + fullTransitionMatrix, markovianStates, psiStates, solver, foxGlynnResult, cycleFree); } } @@ -535,13 +532,12 @@ namespace storm { ValueType diff = std::abs(unifVectors[0][0][i]-unifVectors[1][0][i]); maxNorm = std::max(maxNorm, diff); } - // (6) double lambda + // (6) double lambda lambda = 2 * lambda; } while (maxNorm > epsilon*(1 - kappa)); - logfile.close(); return unifVectors[0][0]; } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 82492aa6e..527af3a0a 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -19,13 +19,7 @@ namespace storm { public: /*! - * Computes TBU according to the UnifPlus algorithm - * - * @param boundsPair With precondition that the first component is 0, the second one gives the time bound - * @param exitRateVector the exit-rates of the given MA - * @param transitionMatrix the transitions of the given MA - * @param markovianStates bitvector refering to the markovian states - * @param psiStates bitvector refering to the goal states + * Computes time-bounded reachability according to the UnifPlus algorithm * * @return the probability vector * @@ -59,12 +53,21 @@ namespace storm { static std::vector computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, storm::storage::SparseMatrix const& backwardTransitions, std::vector const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory); private: + /* + * calculating the unifVectors uv, ow according to Unif+ for MA + */ template ::SupportsExponential, int>::type=0> - static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree); + static void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector> const& relativeReachability, OptimizationDirection dir, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree); + /* + * deleting the probabilistic Diagonals + */ template ::SupportsExponential, int>::type=0> static void deleteProbDiagonals(storm::storage::SparseMatrix& transitionMatrix, storm::storage::BitVector const& markovianStates); + /* + * with having only a subset of the originalMatrix/vector, we need to transform indice + */ static uint64_t transformIndice(storm::storage::BitVector const& subset, uint64_t fakeId){ uint64_t id =0; uint64_t counter =0; @@ -78,11 +81,11 @@ namespace storm { } /* - * Computes vu vector according to UnifPlus + * Computes vu vector according to Unif+ for MA * */ template ::SupportsExponential, int>::type=0> - static void calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, std::ofstream& logfile, storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree); + static void calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree); /*! * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile From 4a321aab28bc1dd8faff27f981fc658d2a6023dd Mon Sep 17 00:00:00 2001 From: Timo Philipp Gros Date: Sat, 6 Jan 2018 18:55:00 +0100 Subject: [PATCH 46/46] delete comment --- .../csl/helper/SparseMarkovAutomatonCslHelper.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 527af3a0a..0125b2feb 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -87,12 +87,6 @@ namespace storm { template ::SupportsExponential, int>::type=0> static void calculateVu(Environment const& env, std::vector> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t node, uint64_t const kind, ValueType lambda, uint64_t probSize, std::vector>>& unifVectors, storm::storage::SparseMatrix const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr> const& solver, storm::utility::numerical::FoxGlynnResult const & poisson, bool cycleFree); - /*! - * Prints the TransitionMatrix and the vectors vd, vu, wu to the logfile - * TODO: delete when development is finished - * - */ - template ::SupportsExponential, int>::type = 0> static void computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix const& transitionMatrix, std::vector const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector& markovianNonGoalValues, std::vector& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory const& minMaxLinearEquationSolverFactory);