|  | @ -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 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.
 |  |  |                 // * 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> 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.
 |  |  |                 // 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.
 |  |  |                 // 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.
 |  |  |                 // 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.
 |  |  |                 // 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()); |  |  |                 std::vector<ValueType> bMarkovian(markovianNonGoalStates.getNumberOfSetBits()); | 
		
	
		
			
				|  |  |                  |  |  |                  | 
		
	
		
			
				|  |  |                 // Compute the two fixed right-hand side vectors, one for Markovian states and one for the probabilistic ones.
 |  |  |                 // 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; |  |  |                 std::vector<ValueType> bMarkovianFixed; | 
		
	
		
			
				|  |  |                 bMarkovianFixed.reserve(markovianNonGoalStates.getNumberOfSetBits()); |  |  |                 bMarkovianFixed.reserve(markovianNonGoalStates.getNumberOfSetBits()); | 
		
	
		
			
				|  |  |                 for (auto state : markovianNonGoalStates) { |  |  |                 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
 |  |  |                 // *    perform one timed-step using v_MS := A_MSwG * v_MS + A_MStoPS * v_PS + (A * 1_G)|MS
 | 
		
	
		
			
				|  |  |                 std::vector<ValueType> markovianNonGoalValuesSwap(markovianNonGoalValues); |  |  |                 std::vector<ValueType> markovianNonGoalValuesSwap(markovianNonGoalValues); | 
		
	
		
			
				|  |  |                 for (uint64_t currentStep = 0; currentStep < numberOfSteps; ++currentStep) { |  |  |                 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); |  |  |                     aMarkovian.multiplyWithVector(markovianNonGoalValues, markovianNonGoalValuesSwap); | 
		
	
		
			
				|  |  |                     std::swap(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> |  |  |             template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> | 
		
	
	
		
			
				|  | 
 |