49 lines
2.7 KiB
49 lines
2.7 KiB
#ifndef STORM_UTILITY_MATRIX_H_
|
|
#define STORM_UTILITY_MATRIX_H_
|
|
|
|
#include "src/storage/SparseMatrix.h"
|
|
#include "src/storage/Scheduler.h"
|
|
#include "src/exceptions/InvalidStateException.h"
|
|
|
|
namespace storm {
|
|
namespace utility {
|
|
namespace matrix {
|
|
|
|
/*!
|
|
* Applies the given scheduler to the given transition matrix. This means that all choices that are not taken by the scheduler are
|
|
* dropped from the transition matrix. If a state has no choice enabled, it is equipped with a self-loop instead.
|
|
*
|
|
* @param transitionMatrix The transition matrix of the original system.
|
|
* @param scheduler The scheduler to apply to the system.
|
|
* @return A transition matrix that corresponds to all transitions of the given system that are selected by the given scheduler.
|
|
*/
|
|
template <typename T>
|
|
storm::storage::SparseMatrix<T> applyScheduler(storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::Scheduler const& scheduler) {
|
|
storm::storage::SparseMatrixBuilder<T> matrixBuilder(transitionMatrix.getRowGroupCount(), transitionMatrix.getColumnCount());
|
|
|
|
for (uint_fast64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) {
|
|
if (scheduler.isChoiceDefined(state)) {
|
|
// Check whether the choice is valid for this state.
|
|
uint_fast64_t choice = transitionMatrix.getRowGroupIndices()[state] + scheduler.getChoice(state);
|
|
if (choice >= transitionMatrix.getRowGroupIndices()[state + 1]) {
|
|
throw storm::exceptions::InvalidStateException() << "Scheduler defines illegal choice " << choice << " for state " << state << ".";
|
|
}
|
|
|
|
// If a valid choice for this state is defined, we copy over the corresponding entries.
|
|
typename storm::storage::SparseMatrix<T>::const_rows selectedRow = transitionMatrix.getRow(choice);
|
|
for (auto const& entry : selectedRow) {
|
|
matrixBuilder.addNextValue(state, entry.getColumn(), entry.getValue());
|
|
}
|
|
} else {
|
|
// If no valid choice for the state is defined, we insert a self-loop.
|
|
matrixBuilder.addNextValue(state, state, storm::utility::constantOne<T>());
|
|
}
|
|
}
|
|
|
|
return matrixBuilder.build();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif /* STORM_UTILITY_MATRIX_H_ */
|