You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
255 lines
11 KiB
255 lines
11 KiB
#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<typename ValueType>
|
|
FlexibleSparseMatrix<ValueType>::FlexibleSparseMatrix(index_type rows) : data(rows), columnCount(0), nonzeroEntryCount(0) {
|
|
// Intentionally left empty.
|
|
}
|
|
|
|
template<typename ValueType>
|
|
FlexibleSparseMatrix<ValueType>::FlexibleSparseMatrix(storm::storage::SparseMatrix<ValueType> const& matrix, bool setAllValuesToOne) : data(matrix.getRowCount()), columnCount(matrix.getColumnCount()), nonzeroEntryCount(matrix.getNonzeroEntryCount()), nontrivialRowGrouping(matrix.hasNontrivialRowGrouping()) {
|
|
if (nontrivialRowGrouping) {
|
|
rowGroupIndices = matrix.getRowGroupIndices();
|
|
}
|
|
for (index_type rowIndex = 0; rowIndex < matrix.getRowCount(); ++rowIndex) {
|
|
typename storm::storage::SparseMatrix<ValueType>::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<ValueType>());
|
|
} else {
|
|
getRow(rowIndex).emplace_back(element);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
template<typename ValueType>
|
|
void FlexibleSparseMatrix<ValueType>::reserveInRow(index_type row, index_type numberOfElements) {
|
|
this->data[row].reserve(numberOfElements);
|
|
}
|
|
|
|
template<typename ValueType>
|
|
typename FlexibleSparseMatrix<ValueType>::row_type& FlexibleSparseMatrix<ValueType>::getRow(index_type index) {
|
|
return this->data[index];
|
|
}
|
|
|
|
template<typename ValueType>
|
|
typename FlexibleSparseMatrix<ValueType>::row_type const& FlexibleSparseMatrix<ValueType>::getRow(index_type index) const {
|
|
return this->data[index];
|
|
}
|
|
|
|
template<typename ValueType>
|
|
typename FlexibleSparseMatrix<ValueType>::row_type& FlexibleSparseMatrix<ValueType>::getRow(index_type rowGroup, index_type offset) {
|
|
assert(rowGroup < this->getRowGroupCount());
|
|
assert(offset < this->getRowGroupSize(rowGroup));
|
|
return getRow(rowGroupIndices[rowGroup] + offset);
|
|
}
|
|
|
|
template<typename ValueType>
|
|
typename FlexibleSparseMatrix<ValueType>::row_type const& FlexibleSparseMatrix<ValueType>::getRow(index_type rowGroup, index_type offset) const {
|
|
assert(rowGroup < this->getRowGroupCount());
|
|
assert(offset < this->getRowGroupSize(rowGroup));
|
|
return getRow(rowGroupIndices[rowGroup] + offset);
|
|
}
|
|
|
|
template<typename ValueType>
|
|
std::vector<typename FlexibleSparseMatrix<ValueType>::index_type> const& FlexibleSparseMatrix<ValueType>::getRowGroupIndices() const {
|
|
return rowGroupIndices;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
typename FlexibleSparseMatrix<ValueType>::index_type FlexibleSparseMatrix<ValueType>::getRowCount() const {
|
|
return this->data.size();
|
|
}
|
|
|
|
template<typename ValueType>
|
|
typename FlexibleSparseMatrix<ValueType>::index_type FlexibleSparseMatrix<ValueType>::getColumnCount() const {
|
|
return columnCount;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
typename FlexibleSparseMatrix<ValueType>::index_type FlexibleSparseMatrix<ValueType>::getNonzeroEntryCount() const {
|
|
return nonzeroEntryCount;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
typename FlexibleSparseMatrix<ValueType>::index_type FlexibleSparseMatrix<ValueType>::getRowGroupCount() const {
|
|
return rowGroupIndices.size();
|
|
}
|
|
|
|
template<typename ValueType>
|
|
typename FlexibleSparseMatrix<ValueType>::index_type FlexibleSparseMatrix<ValueType>::getRowGroupSize(index_type group) const {
|
|
if (group == getRowGroupCount() - 1) {
|
|
return getRowCount() - rowGroupIndices[group];
|
|
} else {
|
|
return rowGroupIndices[group + 1] - rowGroupIndices[group];
|
|
}
|
|
}
|
|
|
|
template<typename ValueType>
|
|
ValueType FlexibleSparseMatrix<ValueType>::getRowSum(index_type row) const {
|
|
ValueType sum = storm::utility::zero<ValueType>();
|
|
for (auto const& element : getRow(row)) {
|
|
sum += element.getValue();
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
void FlexibleSparseMatrix<ValueType>::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<typename ValueType>
|
|
bool FlexibleSparseMatrix<ValueType>::empty() const {
|
|
for (auto const& row : this->data) {
|
|
if (!row.empty()) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
bool FlexibleSparseMatrix<ValueType>::hasNontrivialRowGrouping() const {
|
|
return nontrivialRowGrouping;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
void FlexibleSparseMatrix<ValueType>::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<typename ValueType>
|
|
storm::storage::SparseMatrix<ValueType> FlexibleSparseMatrix<ValueType>::createSparseMatrix() {
|
|
storm::storage::SparseMatrixBuilder<ValueType> 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<typename ValueType>
|
|
bool FlexibleSparseMatrix<ValueType>::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<typename ValueType>
|
|
std::ostream& FlexibleSparseMatrix<ValueType>::printRow(std::ostream& out, index_type const& rowIndex) const {
|
|
index_type columnIndex = 0;
|
|
row_type row = this->getRow(rowIndex);
|
|
for (index_type column = 0; column < this->getColumnCount(); ++column) {
|
|
if (columnIndex < row.size() && row[columnIndex].getColumn() == column) {
|
|
// Insert entry
|
|
out << row[columnIndex].getValue() << "\t";
|
|
++columnIndex;
|
|
} else {
|
|
// Insert zero
|
|
out << "0\t";
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
|
|
template<typename ValueType>
|
|
std::ostream& operator<<(std::ostream& out, FlexibleSparseMatrix<ValueType> const& matrix) {
|
|
typedef typename FlexibleSparseMatrix<ValueType>::index_type FlexibleIndex;
|
|
|
|
// Print column numbers in header.
|
|
out << "\t\t";
|
|
for (FlexibleIndex i = 0; i < matrix.getColumnCount(); ++i) {
|
|
out << i << "\t";
|
|
}
|
|
out << std::endl;
|
|
|
|
if (matrix.hasNontrivialRowGrouping()) {
|
|
// Iterate over all row groups
|
|
FlexibleIndex rowGroupCount = matrix.getRowGroupCount();
|
|
for (FlexibleIndex rowGroup = 0; rowGroup < rowGroupCount; ++rowGroup) {
|
|
out << "\t---- group " << rowGroup << "/" << (rowGroupCount - 1) << " ---- " << std::endl;
|
|
FlexibleIndex endRow = rowGroup+1 < rowGroupCount ? matrix.rowGroupIndices[rowGroup + 1] : matrix.getRowCount();
|
|
// Iterate over all rows.
|
|
for (FlexibleIndex row = matrix.rowGroupIndices[rowGroup]; row < endRow; ++row) {
|
|
// Print the actual row.
|
|
out << rowGroup << "\t(\t";
|
|
matrix.printRow(out, row);
|
|
out << "\t)\t" << rowGroup << std::endl;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
// Iterate over all rows
|
|
for (FlexibleIndex row = 0; row < matrix.getRowCount(); ++row) {
|
|
// Print the actual row.
|
|
out << row << "\t(\t";
|
|
matrix.printRow(out, row);
|
|
out << "\t)\t" << row << std::endl;
|
|
}
|
|
}
|
|
|
|
// Print column numbers in footer.
|
|
out << "\t\t";
|
|
for (FlexibleIndex i = 0; i < matrix.getColumnCount(); ++i) {
|
|
out << i << "\t";
|
|
}
|
|
out << std::endl;
|
|
return out;
|
|
}
|
|
|
|
// Explicitly instantiate the matrix.
|
|
template class FlexibleSparseMatrix<double>;
|
|
template std::ostream& operator<<(std::ostream& out, FlexibleSparseMatrix<double> const& matrix);
|
|
|
|
#ifdef STORM_HAVE_CARL
|
|
template class FlexibleSparseMatrix<storm::RationalFunction>;
|
|
template std::ostream& operator<<(std::ostream& out, FlexibleSparseMatrix<storm::RationalFunction> const& matrix);
|
|
#endif
|
|
|
|
} // namespace storage
|
|
} // namespace storm
|