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_ */