#include "src/storage/FlexibleSparseMatrix.h" #include "src/storage/SparseMatrix.h" #include "src/storage/BitVector.h" #include "src/adapters/CarlAdapter.h" #include "src/utility/constants.h" namespace storm { namespace storage { template FlexibleSparseMatrix::FlexibleSparseMatrix(index_type rows) : data(rows), columnCount(0), nonzeroEntryCount(0) { // Intentionally left empty. } template FlexibleSparseMatrix::FlexibleSparseMatrix(storm::storage::SparseMatrix const& matrix, bool setAllValuesToOne) : data(matrix.getRowCount()), columnCount(matrix.getColumnCount()), nonzeroEntryCount(matrix.getNonzeroEntryCount()), nontrivialRowGrouping(matrix.hasNontrivialRowGrouping()) { if (nontrivialRowGrouping) { rowGroupIndices = matrix.getRowGroupIndices(); rowIndications = matrix.getRowIndications(); // Not fully implemented yet assert(false); } for (index_type rowIndex = 0; rowIndex < matrix.getRowCount(); ++rowIndex) { typename storm::storage::SparseMatrix::const_rows row = matrix.getRow(rowIndex); reserveInRow(rowIndex, row.getNumberOfEntries()); for (auto const& element : row) { // If the probability is zero, we skip this entry. if (storm::utility::isZero(element.getValue())) { continue; } if (setAllValuesToOne) { getRow(rowIndex).emplace_back(element.getColumn(), storm::utility::one()); } else { getRow(rowIndex).emplace_back(element); } } } } template void FlexibleSparseMatrix::reserveInRow(index_type row, index_type numberOfElements) { this->data[row].reserve(numberOfElements); } template typename FlexibleSparseMatrix::row_type& FlexibleSparseMatrix::getRow(index_type index) { return this->data[index]; } template typename FlexibleSparseMatrix::row_type const& FlexibleSparseMatrix::getRow(index_type index) const { return this->data[index]; } template typename FlexibleSparseMatrix::index_type FlexibleSparseMatrix::getRowCount() const { return this->data.size(); } template typename FlexibleSparseMatrix::index_type FlexibleSparseMatrix::getColumnCount() const { return columnCount; } template typename FlexibleSparseMatrix::index_type FlexibleSparseMatrix::getNonzeroEntryCount() const { return nonzeroEntryCount; } template void FlexibleSparseMatrix::updateDimensions() { this->nonzeroEntryCount = 0; this->columnCount = 0; for (auto const& row : this->data) { for (auto const& element : row) { assert(!storm::utility::isZero(element.getValue())); ++this->nonzeroEntryCount; this->columnCount = std::max(element.getColumn() + 1, this->columnCount); } } } template bool FlexibleSparseMatrix::empty() const { for (auto const& row : this->data) { if (!row.empty()) { return false; } } return true; } template bool SparseMatrix::hasNontrivialRowGrouping() const { return nontrivialRowGrouping; } template void FlexibleSparseMatrix::createSubmatrix(storm::storage::BitVector const& rowConstraint, storm::storage::BitVector const& columnConstraint) { for (uint_fast64_t rowIndex = 0; rowIndex < this->data.size(); ++rowIndex) { auto& row = this->data[rowIndex]; if (!rowConstraint.get(rowIndex)) { row.clear(); row.shrink_to_fit(); continue; } row_type newRow; for (auto const& element : row) { if (columnConstraint.get(element.getColumn())) { newRow.push_back(element); } } row = std::move(newRow); } } template storm::storage::SparseMatrix FlexibleSparseMatrix::createSparseMatrix() { storm::storage::SparseMatrixBuilder matrixBuilder(getRowCount(), getColumnCount()); for (uint_fast64_t rowIndex = 0; rowIndex < getRowCount(); ++rowIndex) { auto& row = this->data[rowIndex]; for (auto const& entry : row) { matrixBuilder.addNextValue(rowIndex, entry.getColumn(), entry.getValue()); } } return matrixBuilder.build(); } template bool FlexibleSparseMatrix::rowHasDiagonalElement(storm::storage::sparse::state_type state) { for (auto const& entry : this->getRow(state)) { if (entry.getColumn() < state) { continue; } else if (entry.getColumn() > state) { return false; } else if (entry.getColumn() == state) { return true; } } return false; } template std::ostream& operator<<(std::ostream& out, FlexibleSparseMatrix const& matrix) { for (uint_fast64_t index = 0; index < matrix->data.size(); ++index) { out << index << " - "; for (auto const& element : matrix->getRow(index)) { out << "(" << element.getColumn() << ", " << element.getValue() << ") "; } return out; } } // Explicitly instantiate the matrix. template class FlexibleSparseMatrix; #ifdef STORM_HAVE_CARL template class FlexibleSparseMatrix; #endif } // namespace storage } // namespace storm