|
|
@ -44,9 +44,16 @@ namespace storm { |
|
|
|
// * a matrix aProbabilistic with all (non-discretized) transitions from probabilistic non-goal states to other probabilistic non-goal states.
|
|
|
|
// * a matrix aProbabilisticToMarkovian with all (non-discretized) transitions from probabilistic non-goal states to all Markovian non-goal states.
|
|
|
|
typename storm::storage::SparseMatrix<ValueType> aMarkovian = transitionMatrix.getSubmatrix(true, markovianNonGoalStates, markovianNonGoalStates, true); |
|
|
|
typename storm::storage::SparseMatrix<ValueType> aMarkovianToProbabilistic = transitionMatrix.getSubmatrix(true, markovianNonGoalStates, probabilisticNonGoalStates); |
|
|
|
typename storm::storage::SparseMatrix<ValueType> aProbabilistic = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, probabilisticNonGoalStates); |
|
|
|
typename storm::storage::SparseMatrix<ValueType> aProbabilisticToMarkovian = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, markovianNonGoalStates); |
|
|
|
|
|
|
|
bool existProbabilisticStates = !probabilisticNonGoalStates.empty(); |
|
|
|
typename storm::storage::SparseMatrix<ValueType> aMarkovianToProbabilistic; |
|
|
|
typename storm::storage::SparseMatrix<ValueType> aProbabilistic; |
|
|
|
typename storm::storage::SparseMatrix<ValueType> aProbabilisticToMarkovian; |
|
|
|
if (existProbabilisticStates) { |
|
|
|
aMarkovianToProbabilistic = transitionMatrix.getSubmatrix(true, markovianNonGoalStates, probabilisticNonGoalStates); |
|
|
|
aProbabilistic = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, probabilisticNonGoalStates); |
|
|
|
aProbabilisticToMarkovian = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, markovianNonGoalStates); |
|
|
|
} |
|
|
|
|
|
|
|
// The matrices with transitions from Markovian states need to be digitized.
|
|
|
|
// Digitize aMarkovian. Based on whether the transition is a self-loop or not, we apply the two digitization rules.
|
|
|
@ -64,20 +71,25 @@ namespace storm { |
|
|
|
} |
|
|
|
|
|
|
|
// Digitize aMarkovianToProbabilistic. As there are no self-loops in this case, we only need to apply the digitization formula for regular successors.
|
|
|
|
rowIndex = 0; |
|
|
|
for (auto state : markovianNonGoalStates) { |
|
|
|
for (auto& element : aMarkovianToProbabilistic.getRow(rowIndex)) { |
|
|
|
element.setValue((1 - std::exp(-exitRates[state] * delta)) * element.getValue()); |
|
|
|
if (existProbabilisticStates) { |
|
|
|
rowIndex = 0; |
|
|
|
for (auto state : markovianNonGoalStates) { |
|
|
|
for (auto& element : aMarkovianToProbabilistic.getRow(rowIndex)) { |
|
|
|
element.setValue((1 - std::exp(-exitRates[state] * delta)) * element.getValue()); |
|
|
|
} |
|
|
|
++rowIndex; |
|
|
|
} |
|
|
|
++rowIndex; |
|
|
|
} |
|
|
|
|
|
|
|
// Initialize the two vectors that hold the variable one-step probabilities to all target states for probabilistic and Markovian (non-goal) states.
|
|
|
|
std::vector<ValueType> bProbabilistic(aProbabilistic.getRowCount()); |
|
|
|
std::vector<ValueType> bProbabilistic(existProbabilisticStates ? aProbabilistic.getRowCount() : 0); |
|
|
|
std::vector<ValueType> bMarkovian(markovianNonGoalStates.getNumberOfSetBits()); |
|
|
|
|
|
|
|
// Compute the two fixed right-hand side vectors, one for Markovian states and one for the probabilistic ones.
|
|
|
|
std::vector<ValueType> bProbabilisticFixed = transitionMatrix.getConstrainedRowGroupSumVector(probabilisticNonGoalStates, goalStates); |
|
|
|
std::vector<ValueType> bProbabilisticFixed; |
|
|
|
if (existProbabilisticStates) { |
|
|
|
bProbabilisticFixed = transitionMatrix.getConstrainedRowGroupSumVector(probabilisticNonGoalStates, goalStates); |
|
|
|
} |
|
|
|
std::vector<ValueType> bMarkovianFixed; |
|
|
|
bMarkovianFixed.reserve(markovianNonGoalStates.getNumberOfSetBits()); |
|
|
|
for (auto state : markovianNonGoalStates) { |
|
|
@ -110,25 +122,34 @@ namespace storm { |
|
|
|
// * perform one timed-step using v_MS := A_MSwG * v_MS + A_MStoPS * v_PS + (A * 1_G)|MS
|
|
|
|
std::vector<ValueType> markovianNonGoalValuesSwap(markovianNonGoalValues); |
|
|
|
for (uint64_t currentStep = 0; currentStep < numberOfSteps; ++currentStep) { |
|
|
|
// Start by (re-)computing bProbabilistic = bProbabilisticFixed + aProbabilisticToMarkovian * vMarkovian.
|
|
|
|
aProbabilisticToMarkovian.multiplyWithVector(markovianNonGoalValues, bProbabilistic); |
|
|
|
storm::utility::vector::addVectors(bProbabilistic, bProbabilisticFixed, bProbabilistic); |
|
|
|
if (existProbabilisticStates) { |
|
|
|
// Start by (re-)computing bProbabilistic = bProbabilisticFixed + aProbabilisticToMarkovian * vMarkovian.
|
|
|
|
aProbabilisticToMarkovian.multiplyWithVector(markovianNonGoalValues, bProbabilistic); |
|
|
|
storm::utility::vector::addVectors(bProbabilistic, bProbabilisticFixed, bProbabilistic); |
|
|
|
|
|
|
|
// Now perform the inner value iteration for probabilistic states.
|
|
|
|
solver->solveEquations(env, dir, probabilisticNonGoalValues, bProbabilistic); |
|
|
|
// Now perform the inner value iteration for probabilistic states.
|
|
|
|
solver->solveEquations(env, dir, probabilisticNonGoalValues, bProbabilistic); |
|
|
|
|
|
|
|
// (Re-)compute bMarkovian = bMarkovianFixed + aMarkovianToProbabilistic * vProbabilistic.
|
|
|
|
aMarkovianToProbabilistic.multiplyWithVector(probabilisticNonGoalValues, bMarkovian); |
|
|
|
storm::utility::vector::addVectors(bMarkovian, bMarkovianFixed, bMarkovian); |
|
|
|
} |
|
|
|
|
|
|
|
// (Re-)compute bMarkovian = bMarkovianFixed + aMarkovianToProbabilistic * vProbabilistic.
|
|
|
|
aMarkovianToProbabilistic.multiplyWithVector(probabilisticNonGoalValues, bMarkovian); |
|
|
|
storm::utility::vector::addVectors(bMarkovian, bMarkovianFixed, bMarkovian); |
|
|
|
aMarkovian.multiplyWithVector(markovianNonGoalValues, markovianNonGoalValuesSwap); |
|
|
|
std::swap(markovianNonGoalValues, markovianNonGoalValuesSwap); |
|
|
|
storm::utility::vector::addVectors(markovianNonGoalValues, bMarkovian, markovianNonGoalValues); |
|
|
|
if (existProbabilisticStates) { |
|
|
|
storm::utility::vector::addVectors(markovianNonGoalValues, bMarkovian, markovianNonGoalValues); |
|
|
|
} else { |
|
|
|
storm::utility::vector::addVectors(markovianNonGoalValues, bMarkovianFixed, markovianNonGoalValues); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// After the loop, perform one more step of the value iteration for PS states.
|
|
|
|
aProbabilisticToMarkovian.multiplyWithVector(markovianNonGoalValues, bProbabilistic); |
|
|
|
storm::utility::vector::addVectors(bProbabilistic, bProbabilisticFixed, bProbabilistic); |
|
|
|
solver->solveEquations(env, dir, probabilisticNonGoalValues, bProbabilistic); |
|
|
|
if (existProbabilisticStates) { |
|
|
|
// After the loop, perform one more step of the value iteration for PS states.
|
|
|
|
aProbabilisticToMarkovian.multiplyWithVector(markovianNonGoalValues, bProbabilistic); |
|
|
|
storm::utility::vector::addVectors(bProbabilistic, bProbabilisticFixed, bProbabilistic); |
|
|
|
solver->solveEquations(env, dir, probabilisticNonGoalValues, bProbabilistic); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> |
|
|
|