12template<
typename ValueType>
17template<
typename ValueType>
19 : data(matrix.getRowCount()),
20 columnCount(matrix.getColumnCount()),
21 nonzeroEntryCount(matrix.getNonzeroEntryCount()),
22 trivialRowGrouping(matrix.hasTrivialRowGrouping()) {
23 STORM_LOG_THROW(!revertEquationSystem || trivialRowGrouping, storm::exceptions::InvalidArgumentException,
"Illegal option for creating flexible matrix.");
25 if (!trivialRowGrouping) {
31 for (
auto const& element : row) {
34 if (revertEquationSystem && rowIndex == element.getColumn()) {
35 getRow(rowIndex).emplace_back(element.getColumn(), storm::utility::one<ValueType>());
40 if (setAllValuesToOne) {
41 if (revertEquationSystem && element.getColumn() == rowIndex &&
storm::utility::isOne(element.getValue())) {
44 getRow(rowIndex).emplace_back(element.getColumn(), storm::utility::one<ValueType>());
47 if (revertEquationSystem) {
48 if (element.getColumn() == rowIndex) {
52 getRow(rowIndex).emplace_back(element.getColumn(), storm::utility::one<ValueType>() - element.getValue());
54 getRow(rowIndex).emplace_back(element.getColumn(), -element.getValue());
57 getRow(rowIndex).emplace_back(element);
64template<
typename ValueType>
66 this->data[row].reserve(numberOfElements);
69template<
typename ValueType>
71 return this->data[index];
74template<
typename ValueType>
76 return this->data[index];
79template<
typename ValueType>
82 STORM_LOG_ASSERT(offset < this->getRowGroupSize(rowGroup),
"Invalid offset.");
83 return getRow(rowGroupIndices[rowGroup] + offset);
86template<
typename ValueType>
89 STORM_LOG_ASSERT(offset < this->getRowGroupSize(rowGroup),
"Invalid offset.");
90 return getRow(rowGroupIndices[rowGroup] + offset);
93template<
typename ValueType>
95 return rowGroupIndices;
98template<
typename ValueType>
100 return this->data.size();
103template<
typename ValueType>
108template<
typename ValueType>
110 return nonzeroEntryCount;
113template<
typename ValueType>
115 return rowGroupIndices.size() - 1;
118template<
typename ValueType>
120 return rowGroupIndices[group + 1] - rowGroupIndices[group];
123template<
typename ValueType>
125 ValueType sum = storm::utility::zero<ValueType>();
126 for (
auto const& element : getRow(row)) {
127 sum += element.getValue();
132template<
typename ValueType>
134 this->nonzeroEntryCount = 0;
135 this->columnCount = 0;
136 for (
auto const& row : this->data) {
137 for (
auto const& element : row) {
139 ++this->nonzeroEntryCount;
140 this->columnCount = std::max(element.getColumn() + 1, this->columnCount);
145template<
typename ValueType>
147 for (
auto const& row : this->data) {
155template<
typename ValueType>
157 return trivialRowGrouping;
160template<
typename ValueType>
162 for (uint_fast64_t rowIndex = 0; rowIndex < this->data.size(); ++rowIndex) {
163 auto& row = this->data[rowIndex];
164 if (!rowConstraint.
get(rowIndex)) {
170 for (
auto const& element : row) {
171 if (columnConstraint.
get(element.getColumn())) {
172 newRow.push_back(element);
175 row = std::move(newRow);
179template<
typename ValueType>
182 STORM_LOG_ERROR_COND(this->columnCount == this->getRowCount(),
"insertNewRowsAtEnd only works when the FlexibleMatrix is square but column count is "
183 << columnCount <<
" and row count is " << this->getRowCount());
188 this->data.push_back(newRow);
190 this->columnCount = getRowCount();
194template<
typename ValueType>
196 uint_fast64_t numEntries = 0;
197 for (
auto const& row : this->data) {
198 numEntries += row.size();
202 hasTrivialRowGrouping() ? 0 : getRowGroupCount());
203 uint_fast64_t currRowIndex = 0;
204 auto rowGroupIndexIt = getRowGroupIndices().begin();
205 for (
auto const& row : this->data) {
206 if (!hasTrivialRowGrouping()) {
207 while (currRowIndex >= *rowGroupIndexIt) {
212 for (
auto const& entry : row) {
213 matrixBuilder.
addNextValue(currRowIndex, entry.getColumn(), entry.getValue());
218 if (!hasTrivialRowGrouping()) {
219 while (currRowIndex >= *rowGroupIndexIt) {
224 return matrixBuilder.
build();
227template<
typename ValueType>
230 uint_fast64_t numEntries = 0;
231 for (
auto rowIndex : rowConstraint) {
232 auto const& row = data[rowIndex];
233 for (
auto const& entry : row) {
234 if (columnConstraint.
get(entry.getColumn())) {
239 uint_fast64_t numRowGroups = 0;
240 if (!hasTrivialRowGrouping()) {
241 auto lastRowGroupIndexIt = getRowGroupIndices().
end() - 1;
242 auto rowGroupIndexIt = getRowGroupIndices().begin();
243 while (rowGroupIndexIt != lastRowGroupIndexIt) {
245 if (rowConstraint.
getNextSetIndex(*rowGroupIndexIt) < *(++rowGroupIndexIt)) {
251 std::vector<uint_fast64_t> oldToNewColumnIndexMapping(getColumnCount(), getColumnCount());
252 uint_fast64_t newColumnIndex = 0;
253 for (
auto oldColumnIndex : columnConstraint) {
254 oldToNewColumnIndexMapping[oldColumnIndex] = newColumnIndex++;
259 uint_fast64_t currRowIndex = 0;
260 auto rowGroupIndexIt = getRowGroupIndices().begin();
261 for (
auto oldRowIndex : rowConstraint) {
262 if (!hasTrivialRowGrouping() && oldRowIndex >= *rowGroupIndexIt) {
267 }
while (oldRowIndex >= *rowGroupIndexIt);
269 auto const& row = data[oldRowIndex];
270 for (
auto const& entry : row) {
271 if (columnConstraint.
get(entry.getColumn())) {
272 matrixBuilder.
addNextValue(currRowIndex, oldToNewColumnIndexMapping[entry.getColumn()], entry.getValue());
277 return matrixBuilder.
build();
280template<
typename ValueType>
282 for (
auto const& entry : this->getRow(state)) {
283 if (entry.getColumn() < state) {
285 }
else if (entry.getColumn() > state) {
287 }
else if (entry.getColumn() == state) {
294template<
typename ValueType>
297 row_type row = this->getRow(rowIndex);
298 for (
index_type column = 0; column < this->getColumnCount(); ++column) {
299 if (columnIndex < row.size() && row[columnIndex].getColumn() == column) {
301 out << row[columnIndex].getValue() <<
"\t";
311template<
typename ValueType>
325 for (FlexibleIndex rowGroup = 0; rowGroup < rowGroupCount; ++rowGroup) {
326 out <<
"\t---- group " << rowGroup <<
"/" << (rowGroupCount - 1) <<
" ---- \n";
327 FlexibleIndex endRow = matrix.rowGroupIndices[rowGroup + 1];
329 for (FlexibleIndex row = matrix.rowGroupIndices[rowGroup]; row < endRow; ++row) {
331 out << rowGroup <<
"\t(\t";
333 out <<
"\t)\t" << rowGroup <<
'\n';
339 for (FlexibleIndex row = 0; row < matrix.
getRowCount(); ++row) {
341 out << row <<
"\t(\t";
343 out <<
"\t)\t" << row <<
'\n';
357template class FlexibleSparseMatrix<double>;
A bit vector that is internally represented as a vector of 64-bit values.
uint64_t getNextSetIndex(uint64_t startingIndex) const
Retrieves the index of the bit that is the next bit set to true in the bit vector.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
The flexible sparse matrix is used during state elimination.
void reserveInRow(index_type row, index_type numberOfElements)
Reserves space for elements in row.
index_type getRowGroupSize(index_type group) const
Returns the size of the given row group.
index_type getColumnCount() const
Returns the number of columns of the matrix.
value_type getRowSum(index_type row) const
Computes the sum of the entries in a given row.
void updateDimensions()
Recomputes the number of columns and the number of non-zero entries.
index_type getNonzeroEntryCount() const
Returns the cached number of nonzero entries in the matrix.
std::ostream & printRow(std::ostream &out, index_type const &rowIndex) const
Print row.
std::vector< index_type > const & getRowGroupIndices() const
Returns the grouping of rows of this matrix.
storm::storage::SparseMatrix< ValueType > createSparseMatrix()
Creates a sparse matrix from the flexible sparse matrix.
row_type & getRow(index_type)
Returns an object representing the given row.
bool empty() const
Checks if the matrix has no elements.
void filterEntries(storm::storage::BitVector const &rowConstraint, storm::storage::BitVector const &columnConstraint)
Erases all entries whose row and column does not satisfy the given rowConstraint and the given column...
index_type getRowCount() const
Returns the number of rows of the matrix.
FlexibleSparseMatrix()=default
Constructs an empty flexible sparse matrix.
bool hasTrivialRowGrouping() const
Retrieves whether the matrix has a (possibly) trivial row grouping.
index_type insertNewRowsAtEnd(index_type numRows)
Inserts new, empty rows at the end of the FlexibleSparseMatrix.
bool rowHasDiagonalElement(storm::storage::sparse::state_type state)
Checks whether the given state has a self-loop with an arbitrary probability in the probability matri...
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
std::vector< storm::storage::MatrixEntry< index_type, value_type > > row_type
This class represents a number of consecutive rows of the matrix.
index_type getNumberOfEntries() const
Retrieves the number of entries in the rows.
A class that can be used to build a sparse matrix by adding value by value.
void addNextValue(index_type row, index_type column, value_type const &value)
Sets the matrix entry at the given row and column to the given value.
void newRowGroup(index_type startingRow)
Starts a new row group in the matrix.
SparseMatrix< value_type > build(index_type overriddenRowCount=0, index_type overriddenColumnCount=0, index_type overriddenRowGroupCount=0)
A class that holds a possibly non-square matrix in the compressed row storage format.
const_rows getRow(index_type row) const
Returns an object representing the given row.
const_iterator end(index_type row) const
Retrieves an iterator that points past the end of the given row.
std::vector< index_type > const & getRowGroupIndices() const
Returns the grouping of rows of this matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_ERROR_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
bool isOne(ValueType const &a)
bool isZero(ValueType const &a)