1#include "storm-config.h"
15 std::uniform_real_distribution<double> coin(0.0, 1.0);
16 std::uniform_int_distribution<uint64_t> groupSize(1, 3);
19 for (uint64_t g = 0; g < groups; ++g) {
20 uint64_t
const size = grouped ? groupSize(rng) : 1;
22 builder.newRowGroup(row);
24 for (uint64_t i = 0;
i < size; ++
i, ++row) {
25 for (uint64_t c = 0; c < columns; ++c) {
26 if (coin(rng) < density) {
27 builder.addNextValue(row, c, coin(rng) + 0.5);
32 return builder.build(row, columns, grouped ? groups : 0);
36 std::uniform_real_distribution<double> coin(0.0, 1.0);
38 for (uint64_t i = 0;
i < size; ++
i) {
39 result.set(i, coin(rng) < p);
42 result.set(rng() % size);
52 std::vector<index_type> rowGroupIndices;
57 rowGroupIndices.push_back(i);
63 auto keep = [&](
index_type col) {
return columnConstraint.
get(col) && (makeZeroColumns.
size() == 0 || !makeZeroColumns.
get(col)); };
65 index_type subEntries = 0, subRows = 0, rowGroupCount = 0;
66 for (uint64_t index : rowConstraint) {
67 subRows += rowGroupIndices[index + 1] - rowGroupIndices[index];
68 for (index_type i = rowGroupIndices[index];
i < rowGroupIndices[index + 1]; ++
i) {
69 bool foundDiagonalElement =
false;
70 for (
auto it = matrix.
begin(i); it != matrix.
end(i); ++it) {
71 if (keep(it->getColumn())) {
73 if (columnBitsSetBeforeIndex[it->getColumn()] == rowBitsSetBeforeIndex[index]) {
74 foundDiagonalElement =
true;
78 if (insertDiagonalEntries && !foundDiagonalElement && rowGroupCount < submatrixColumnCount) {
88 for (uint64_t index : rowConstraint) {
90 builder.newRowGroup(rowCount);
92 for (index_type i = rowGroupIndices[index];
i < rowGroupIndices[index + 1]; ++
i) {
93 bool insertedDiagonalElement =
false;
94 for (
auto it = matrix.
begin(i); it != matrix.
end(i); ++it) {
95 if (keep(it->getColumn())) {
96 if (columnBitsSetBeforeIndex[it->getColumn()] == rowBitsSetBeforeIndex[index]) {
97 insertedDiagonalElement =
true;
98 }
else if (insertDiagonalEntries && !insertedDiagonalElement && columnBitsSetBeforeIndex[it->getColumn()] > rowBitsSetBeforeIndex[index]) {
99 builder.addNextValue(rowCount, rowGroupCount, 0.0);
100 insertedDiagonalElement =
true;
102 builder.addNextValue(rowCount, columnBitsSetBeforeIndex[it->getColumn()], it->getValue());
105 if (insertDiagonalEntries && !insertedDiagonalElement && rowGroupCount < submatrixColumnCount) {
106 builder.addNextValue(rowCount, rowGroupCount, 0.0);
112 auto result = builder.build();
113 if (groupedResult && !useGroups) {
115 std::vector<index_type> newGroups{0};
116 auto selectedRowIt = rowConstraint.begin();
119 while (selectedRowIt != rowConstraint.end() && *selectedRowIt < matrix.
getRowGroupIndices()[group + 1]) {
123 if (newRowCount > 0) {
124 newGroups.push_back(newGroups.back() + newRowCount);
127 result.setRowGroupIndices(newGroups);
140 for (uint64_t row = 0; row < expected.
getRowCount(); ++row) {
142 auto it = actual.
begin(row);
143 for (
auto const& entry : expected.
getRow(row)) {
144 EXPECT_EQ(entry.getColumn(), it->getColumn());
145 EXPECT_EQ(entry.getValue(), it->getValue());
153TEST(SubmatrixBuilderTest, AgreesWithGetSubmatrix) {
154 std::mt19937_64 rng(42);
155 for (
bool grouped : {
false,
true}) {
156 for (
int iteration = 0; iteration < 200; ++iteration) {
157 uint64_t
const n = 1 + rng() % 12;
158 auto matrix = createRandomMatrix(rng, n, n, grouped, 0.4);
161 for (
int j = 0; j < 5; ++j) {
162 auto const groupConstraint = randomBitVector(rng, matrix.
getRowGroupCount(), 0.6);
163 auto const rowConstraint = randomBitVector(rng, matrix.
getRowCount(), 0.6);
164 auto const columnConstraint = randomBitVector(rng, matrix.
getColumnCount(), 0.6);
165 auto const zeroColumns = randomBitVector(rng, matrix.
getColumnCount(), 0.3);
166 for (
bool diagonal : {
false,
true}) {
167 expectEqual(referenceSubmatrix(matrix,
true, groupConstraint, columnConstraint, diagonal, {}),
169 expectEqual(referenceSubmatrix(matrix,
true, groupConstraint, columnConstraint, diagonal, zeroColumns),
171 expectEqual(referenceSubmatrix(matrix,
false, rowConstraint, columnConstraint, diagonal, {}),
173 expectEqual(referenceSubmatrix(matrix,
false, rowConstraint, columnConstraint, diagonal, zeroColumns),
181TEST(SubmatrixBuilderTest, VectorConstraints) {
182 std::mt19937_64 rng(7);
183 auto matrix = createRandomMatrix(rng, 10, 10,
true, 0.5);
187 std::vector<uint64_t> groupVector(groups.begin(), groups.end());
188 std::vector<uint64_t> columnVector(columns.begin(), columns.end());
192TEST(SubmatrixBuilderTest, EmptyConstraintThrows) {
193 std::mt19937_64 rng(1);
194 auto matrix = createRandomMatrix(rng, 4, 4,
false, 0.5);
201 expectEqual(referenceSubmatrix(matrix,
false, some, some,
false, {}), builder.
getByRowConstraint(some, some,
false));
TEST(SubmatrixBuilderTest, AgreesWithGetSubmatrix)
A bit vector that is internally represented as a vector of 64-bit values.
std::vector< uint64_t > getNumberOfSetBitsBeforeIndices() const
Retrieves a vector that holds at position i the number of bits set before index i.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
size_t size() const
Retrieves the number of bits this bit vector can store.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
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.
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.
index_type getEntryCount() const
Returns the number of entries in the matrix.
const_iterator begin(index_type row) const
Retrieves an iterator that points to the beginning of the given row.
const_iterator end(index_type row) const
Retrieves an iterator that points past the end of the given row.
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
index_type getColumnCount() const
Returns the number of columns of the matrix.
bool hasTrivialRowGrouping() const
Retrieves whether the matrix has a trivial row grouping.
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.
Helper class to extract submatrices of a fixed sparse matrix.
SparseMatrix< ValueType > getByRowGroupConstraint(RowConstraintType const &rowGroupConstraint, ColumnConstraintType const &columnConstraint, bool const insertDiagonalElement, storm::OptionalRef< storm::storage::BitVector const > makeZeroColumns=storm::NullRef) const
Creates the submatrix that keeps only the given row groups and columns The row group structure of the...
SparseMatrix< ValueType > getByRowConstraint(RowConstraintType const &rowConstraint, ColumnConstraintType const &columnConstraint, bool const insertDiagonalElement, storm::OptionalRef< storm::storage::BitVector const > makeZeroColumns=storm::NullRef) const
Creates the submatrix that keeps only the given rows and columns If the matrix has a non-trivial row ...
#define STORM_SILENT_EXPECT_THROW(statement, expected_exception)