Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseMatrixTest.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
10
11TEST(SparseMatrixBuilder, CreationEmpty) {
14 ASSERT_NO_THROW(matrix = matrixBuilder.build());
15
16 ASSERT_EQ(0ul, matrix.getRowCount());
17 ASSERT_EQ(0ul, matrix.getColumnCount());
18 ASSERT_EQ(0ul, matrix.getEntryCount());
19}
20
21TEST(SparseMatrixBuilder, CreationWithDimensions) {
23 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
24 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
25 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
26 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
27 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
28
30 ASSERT_NO_THROW(matrix = matrixBuilder.build());
31
32 ASSERT_EQ(3ul, matrix.getRowCount());
33 ASSERT_EQ(4ul, matrix.getColumnCount());
34 ASSERT_EQ(5ul, matrix.getEntryCount());
35}
36
37TEST(SparseMatrixBuilder, CreationWithoutNumberOfEntries) {
39 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
40 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
41 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
42 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
43 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
44
46 ASSERT_NO_THROW(matrix = matrixBuilder.build());
47
48 ASSERT_EQ(3ul, matrix.getRowCount());
49 ASSERT_EQ(4ul, matrix.getColumnCount());
50 ASSERT_EQ(5ul, matrix.getEntryCount());
51}
52
53TEST(SparseMatrixBuilder, CreationWithNumberOfRows) {
55 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
56 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
57 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
58 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
59 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
60
62 ASSERT_NO_THROW(matrix = matrixBuilder.build());
63
64 ASSERT_EQ(3ul, matrix.getRowCount());
65 ASSERT_EQ(4ul, matrix.getColumnCount());
66 ASSERT_EQ(5ul, matrix.getEntryCount());
67}
68
69TEST(SparseMatrixBuilder, CreationWithoutDimensions) {
71 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
72 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 3, 1.2));
73 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
74 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
75 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 2, 0.2));
76
78 ASSERT_NO_THROW(matrix = matrixBuilder.build());
79
80 ASSERT_EQ(2ul, matrix.getRowCount());
81 ASSERT_EQ(4ul, matrix.getColumnCount());
82 ASSERT_EQ(5ul, matrix.getEntryCount());
83}
84
85TEST(SparseMatrixBuilder, AddNextValue) {
86 storm::storage::SparseMatrixBuilder<double> matrixBuilder1(3, 4, 5);
87 ASSERT_NO_THROW(matrixBuilder1.addNextValue(0, 1, 1.0));
88 ASSERT_NO_THROW(matrixBuilder1.addNextValue(0, 2, 1.2));
89 STORM_SILENT_ASSERT_THROW(matrixBuilder1.addNextValue(0, 4, 0.5), storm::exceptions::OutOfRangeException);
90 STORM_SILENT_ASSERT_THROW(matrixBuilder1.addNextValue(3, 1, 0.5), storm::exceptions::OutOfRangeException);
91
93 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
94 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
95 STORM_SILENT_ASSERT_THROW(matrixBuilder2.addNextValue(0, 4, 0.5), storm::exceptions::OutOfRangeException);
96 STORM_SILENT_ASSERT_THROW(matrixBuilder2.addNextValue(3, 1, 0.5), storm::exceptions::OutOfRangeException);
97
99 ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 1, 1.0));
100 ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 2, 1.2));
101 ASSERT_NO_THROW(matrixBuilder3.addNextValue(2, 4, 0.5));
102 STORM_SILENT_ASSERT_THROW(matrixBuilder3.addNextValue(3, 1, 0.2), storm::exceptions::OutOfRangeException);
103
105 ASSERT_NO_THROW(matrixBuilder4.addNextValue(0, 1, 1.0));
106 ASSERT_NO_THROW(matrixBuilder4.addNextValue(1, 2, 1.2));
107 ASSERT_NO_THROW(matrixBuilder4.addNextValue(2, 4, 0.5));
108 ASSERT_NO_THROW(matrixBuilder4.addNextValue(3, 1, 0.2));
109}
110
111TEST(SparseMatrix, Build) {
112 storm::storage::SparseMatrixBuilder<double> matrixBuilder1(3, 4, 5);
113 ASSERT_NO_THROW(matrixBuilder1.addNextValue(0, 1, 1.0));
114 ASSERT_NO_THROW(matrixBuilder1.addNextValue(0, 2, 1.2));
115 ASSERT_NO_THROW(matrixBuilder1.addNextValue(1, 0, 0.5));
116 ASSERT_NO_THROW(matrixBuilder1.addNextValue(1, 1, 0.7));
117 ASSERT_NO_THROW(matrixBuilder1.addNextValue(1, 3, 0.2));
118 ASSERT_NO_THROW(matrixBuilder1.build());
119
120 storm::storage::SparseMatrixBuilder<double> matrixBuilder2(3, 4, 5);
121 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
122 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
123 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
124 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
125 STORM_SILENT_ASSERT_THROW(matrixBuilder2.build(), storm::exceptions::InvalidStateException);
126
128 ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 1, 1.0));
129 ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 2, 1.2));
130 ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 0, 0.5));
131 ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 1, 0.7));
132 ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 3, 0.2));
134 ASSERT_NO_THROW(matrix3 = matrixBuilder3.build());
135 ASSERT_EQ(2ul, matrix3.getRowCount());
136 ASSERT_EQ(4ul, matrix3.getColumnCount());
137 ASSERT_EQ(5ul, matrix3.getEntryCount());
138
140 ASSERT_NO_THROW(matrixBuilder4.addNextValue(0, 1, 1.0));
141 ASSERT_NO_THROW(matrixBuilder4.addNextValue(0, 2, 1.2));
142 ASSERT_NO_THROW(matrixBuilder4.addNextValue(1, 0, 0.5));
143 ASSERT_NO_THROW(matrixBuilder4.addNextValue(1, 1, 0.7));
144 ASSERT_NO_THROW(matrixBuilder4.addNextValue(1, 3, 0.2));
146 ASSERT_NO_THROW(matrix4 = matrixBuilder4.build(4));
147 ASSERT_EQ(4ul, matrix4.getRowCount());
148 ASSERT_EQ(4ul, matrix4.getColumnCount());
149 ASSERT_EQ(5ul, matrix4.getEntryCount());
150
152 ASSERT_NO_THROW(matrixBuilder5.addNextValue(0, 1, 1.0));
153 ASSERT_NO_THROW(matrixBuilder5.addNextValue(0, 2, 1.2));
154 ASSERT_NO_THROW(matrixBuilder5.addNextValue(1, 0, 0.5));
155 ASSERT_NO_THROW(matrixBuilder5.addNextValue(1, 1, 0.7));
156 ASSERT_NO_THROW(matrixBuilder5.addNextValue(1, 3, 0.2));
158 ASSERT_NO_THROW(matrix5 = matrixBuilder5.build(0, 6));
159 ASSERT_EQ(2ul, matrix5.getRowCount());
160 ASSERT_EQ(6ul, matrix5.getColumnCount());
161 ASSERT_EQ(5ul, matrix5.getEntryCount());
162}
163
164TEST(SparseMatrix, DiagonalEntries) {
165 {
166 // No row groupings
169 for (uint64_t i = 0; i < 4; ++i) {
170 ASSERT_NO_THROW(builder.addDiagonalEntry(i, i));
171 ASSERT_NO_THROW(builder.addNextValue(i, 2, 100.0 + i));
172 if (i < 2) {
173 ASSERT_NO_THROW(builderCmp.addNextValue(i, i, i));
174 ASSERT_NO_THROW(builderCmp.addNextValue(i, 2, 100.0 + i));
175 } else {
176 ASSERT_NO_THROW(builderCmp.addNextValue(i, 2, 100.0 + i));
177 ASSERT_NO_THROW(builderCmp.addNextValue(i, i, i));
178 }
179 }
180 auto matrix = builder.build();
181 auto matrixCmp = builderCmp.build();
182 EXPECT_EQ(matrix, matrixCmp);
183 }
184 {
185 // With row groupings (each row group has 3 rows)
186 storm::storage::SparseMatrixBuilder<double> builder(12, 4, 21, true, true, 4);
187 storm::storage::SparseMatrixBuilder<double> builderCmp(12, 4, 21, true, true, 4);
188 for (uint64_t i = 0; i < 4; ++i) {
189 uint64_t row = 3 * i;
190 builder.newRowGroup(row);
191 builderCmp.newRowGroup(row);
192 for (; row < 3 * (i + 1); ++row) {
193 ASSERT_NO_THROW(builder.addDiagonalEntry(row, row));
194 ASSERT_NO_THROW(builder.addNextValue(row, 2, 100 + row));
195 if (i < 2) {
196 ASSERT_NO_THROW(builderCmp.addNextValue(row, i, row));
197 ASSERT_NO_THROW(builderCmp.addNextValue(row, 2, 100.0 + row));
198 } else {
199 ASSERT_NO_THROW(builderCmp.addNextValue(row, 2, 100.0 + row));
200 ASSERT_NO_THROW(builderCmp.addNextValue(row, i, row));
201 }
202 }
203 }
204 auto matrix = builder.build();
205 auto matrixCmp = builderCmp.build();
206 EXPECT_EQ(matrix, matrixCmp);
207 }
208 {
209 // With row groupings (every second row is empty)
210 storm::storage::SparseMatrixBuilder<double> builder(12, 4, 10, true, true, 4);
211 storm::storage::SparseMatrixBuilder<double> builderCmp(12, 4, 10, true, true, 4);
212 for (uint64_t i = 0; i < 4; ++i) {
213 uint64_t row = 3 * i;
214 builder.newRowGroup(row);
215 builderCmp.newRowGroup(row);
216 for (; row < 3 * (i + 1); ++row) {
217 if (row % 2 == 1) {
218 continue;
219 }
220 ASSERT_NO_THROW(builder.addDiagonalEntry(row, row));
221 ASSERT_NO_THROW(builder.addNextValue(row, 2, 100 + row));
222 if (i < 2) {
223 ASSERT_NO_THROW(builderCmp.addNextValue(row, i, row));
224 ASSERT_NO_THROW(builderCmp.addNextValue(row, 2, 100.0 + row));
225 } else {
226 ASSERT_NO_THROW(builderCmp.addNextValue(row, i, row));
227 ASSERT_NO_THROW(builderCmp.addNextValue(row, 2, 100.0 + row));
228 }
229 }
230 }
231 auto matrix = builder.build();
232 auto matrixCmp = builderCmp.build();
233 EXPECT_EQ(matrix, matrixCmp);
234 }
235}
236
237TEST(SparseMatrix, CreationWithMovingContents) {
238 std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>> columnsAndValues;
239 columnsAndValues.emplace_back(1, 1.0);
240 columnsAndValues.emplace_back(2, 1.2);
241 columnsAndValues.emplace_back(0, 0.5);
242 columnsAndValues.emplace_back(1, 0.7);
243 columnsAndValues.emplace_back(3, 0.2);
244
245 ASSERT_NO_THROW(storm::storage::SparseMatrix<double> matrix(4, {0, 2, 5, 5}, columnsAndValues, boost::optional<std::vector<uint_fast64_t>>({0, 1, 2, 3})));
246 storm::storage::SparseMatrix<double> matrix(4, {0, 2, 5, 5}, columnsAndValues, boost::optional<std::vector<uint_fast64_t>>({0, 1, 2, 3}));
247 ASSERT_EQ(3ul, matrix.getRowCount());
248 ASSERT_EQ(4ul, matrix.getColumnCount());
249 ASSERT_EQ(5ul, matrix.getEntryCount());
250 ASSERT_EQ(3ul, matrix.getRowGroupCount());
251}
252
253TEST(SparseMatrix, CopyConstruct) {
255 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
256 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
257 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
258 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
259 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
260
262 ASSERT_NO_THROW(matrix = matrixBuilder.build());
263
264 ASSERT_NO_THROW(storm::storage::SparseMatrix<double> copy(matrix));
266 ASSERT_TRUE(matrix == copy);
267}
268
269TEST(SparseMatrix, CopyAssign) {
271 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
272 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
273 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
274 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
275 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
276
278 ASSERT_NO_THROW(matrix = matrixBuilder.build());
279
280 ASSERT_NO_THROW(storm::storage::SparseMatrix<double> copy = matrix);
282 ASSERT_TRUE(matrix == copy);
283}
284
285TEST(SparseMatrix, MakeAbsorbing) {
286 storm::storage::SparseMatrixBuilder<double> matrixBuilder(3, 4, 5);
287 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
288 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
289 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
290 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
291 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
293 ASSERT_NO_THROW(matrix = matrixBuilder.build());
294
295 storm::storage::BitVector absorbingRows(3);
296 absorbingRows.set(1);
297
298 ASSERT_NO_THROW(matrix.makeRowsAbsorbing(absorbingRows));
299
300 storm::storage::SparseMatrixBuilder<double> matrixBuilder2(3, 4, 3);
301 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
302 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
303 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 1));
304
306 ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
307
308 ASSERT_TRUE(matrix == matrix2);
309}
310
311TEST(SparseMatrix, MakeRowGroupAbsorbing) {
312 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9, true, true);
313 ASSERT_NO_THROW(matrixBuilder.newRowGroup(0));
314 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
315 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
316 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
317 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
318 ASSERT_NO_THROW(matrixBuilder.newRowGroup(2));
319 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
320 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
321 ASSERT_NO_THROW(matrixBuilder.newRowGroup(4));
322 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
323 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
324 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
326 ASSERT_NO_THROW(matrix = matrixBuilder.build());
327
328 storm::storage::BitVector absorbingRowGroups(3);
329 absorbingRowGroups.set(1);
330
331 ASSERT_NO_THROW(matrix.makeRowGroupsAbsorbing(absorbingRowGroups));
332
333 storm::storage::SparseMatrixBuilder<double> matrixBuilder2(0, 0, 0, false, true);
334 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(0));
335 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
336 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
337 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
338 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
339 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(2));
340 ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 1, 1));
341 ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 1, 1));
342 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(4));
343 ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 0, 0.1));
344 ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 1, 0.2));
345 ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 3, 0.3));
347 ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
348
349 ASSERT_TRUE(matrix == matrix2);
350}
351
352TEST(SparseMatrix, rowGroupIndices) {
353 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9, true, true, 4);
354 ASSERT_NO_THROW(matrixBuilder.newRowGroup(0));
355 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
356 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
357 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
358 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
359 ASSERT_NO_THROW(matrixBuilder.newRowGroup(2));
360 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
361 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
362 ASSERT_NO_THROW(matrixBuilder.newRowGroup(4));
363 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
364 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
365 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
367 ASSERT_NO_THROW(matrix = matrixBuilder.build());
368
369 EXPECT_EQ(4ul, matrix.getRowGroupCount());
370 std::vector<storm::storage::SparseMatrixIndexType> expected, actual;
371 expected.assign({0, 1});
372 auto indices = matrix.getRowGroupIndices(0);
373 actual.assign(indices.begin(), indices.end());
374 EXPECT_EQ(expected, actual);
375 expected.assign({2, 3});
376 indices = matrix.getRowGroupIndices(1);
377 actual.assign(indices.begin(), indices.end());
378 EXPECT_EQ(expected, actual);
379 expected.assign({4});
380 indices = matrix.getRowGroupIndices(2);
381 actual.assign(indices.begin(), indices.end());
382 EXPECT_EQ(expected, actual);
383 expected.assign({});
384 indices = matrix.getRowGroupIndices(3);
385 actual.assign(indices.begin(), indices.end());
386 EXPECT_EQ(expected, actual);
387}
388
389TEST(SparseMatrix, ConstrainedRowSumVector) {
390 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9);
391 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
392 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
393 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
394 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
395 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
396 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
397 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
398 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
399 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
401 ASSERT_NO_THROW(matrix = matrixBuilder.build());
402
403 storm::storage::BitVector columnConstraint(4);
404 columnConstraint.set(1);
405 columnConstraint.set(3);
406
407 ASSERT_NO_THROW(std::vector<double> constrainedRowSum = matrix.getConstrainedRowSumVector(storm::storage::BitVector(5, true), columnConstraint));
408 std::vector<double> constrainedRowSum = matrix.getConstrainedRowSumVector(storm::storage::BitVector(5, true), columnConstraint);
409 ASSERT_TRUE(constrainedRowSum == std::vector<double>({1.0, 0.7, 0, 0, 0.5}));
410
411 storm::storage::SparseMatrixBuilder<double> matrixBuilder2(5, 4, 9, true, true);
412 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(0));
413 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
414 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
415 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
416 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
417 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(2));
418 ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 0, 0.5));
419 ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 2, 1.1));
420 ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 3, 1.2));
421 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(4));
422 ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 0, 0.1));
423 ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 3, 0.3));
425 ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
426
427 storm::storage::BitVector rowGroupConstraint(3);
428 rowGroupConstraint.set(1);
429
430 storm::storage::BitVector columnConstraint2(4);
431 columnConstraint2.set(2);
432 columnConstraint2.set(3);
433
434 ASSERT_NO_THROW(std::vector<double> constrainedRowSum2 = matrix2.getConstrainedRowGroupSumVector(rowGroupConstraint, columnConstraint2));
435 std::vector<double> constrainedRowSum2 = matrix2.getConstrainedRowGroupSumVector(rowGroupConstraint, columnConstraint2);
436 ASSERT_TRUE(constrainedRowSum2 == std::vector<double>({0, 2.3}));
437}
438
439TEST(SparseMatrix, Submatrix) {
440 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9, true, true);
441 ASSERT_NO_THROW(matrixBuilder.newRowGroup(0));
442 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
443 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
444 ASSERT_NO_THROW(matrixBuilder.newRowGroup(1));
445 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
446 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
447 ASSERT_NO_THROW(matrixBuilder.newRowGroup(2));
448 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
449 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
450 ASSERT_NO_THROW(matrixBuilder.newRowGroup(4));
451 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
452 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
453 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
455 ASSERT_NO_THROW(matrix = matrixBuilder.build());
456
457 storm::storage::BitVector rowGroupConstraint(4);
458 storm::storage::BitVector columnConstraint(4);
459
460 STORM_SILENT_ASSERT_THROW(matrix.getSubmatrix(true, rowGroupConstraint, columnConstraint), storm::exceptions::InvalidArgumentException);
461
462 std::vector<uint_fast64_t> rowGroupIndices = {0, 1, 2, 4, 5};
463
464 rowGroupConstraint.set(2);
465 rowGroupConstraint.set(3);
466 columnConstraint.set(0);
467 columnConstraint.set(3);
468
469 ASSERT_NO_THROW(storm::storage::SparseMatrix<double> matrix2 = matrix.getSubmatrix(true, rowGroupConstraint, columnConstraint, false));
470 storm::storage::SparseMatrix<double> matrix2 = matrix.getSubmatrix(true, rowGroupConstraint, columnConstraint, false);
471
472 storm::storage::SparseMatrixBuilder<double> matrixBuilder3(3, 2, 3, true, true);
473 ASSERT_NO_THROW(matrixBuilder3.newRowGroup(0));
474 ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 0, 0.5));
475 ASSERT_NO_THROW(matrixBuilder3.newRowGroup(2));
476 ASSERT_NO_THROW(matrixBuilder3.addNextValue(2, 0, 0.1));
477 ASSERT_NO_THROW(matrixBuilder3.addNextValue(2, 1, 0.3));
479 ASSERT_NO_THROW(matrix3 = matrixBuilder3.build());
480
481 ASSERT_TRUE(matrix2 == matrix3);
482
483 std::vector<uint_fast64_t> rowGroupToIndexMapping = {0, 0, 1, 0};
484
485 ASSERT_NO_THROW(storm::storage::SparseMatrix<double> matrix4 = matrix.selectRowsFromRowGroups(rowGroupToIndexMapping));
486 storm::storage::SparseMatrix<double> matrix4 = matrix.selectRowsFromRowGroups(rowGroupToIndexMapping);
487
488 storm::storage::SparseMatrixBuilder<double> matrixBuilder5(4, 4, 8);
489 ASSERT_NO_THROW(matrixBuilder5.addNextValue(0, 1, 1.0));
490 ASSERT_NO_THROW(matrixBuilder5.addNextValue(0, 2, 1.2));
491 ASSERT_NO_THROW(matrixBuilder5.addNextValue(1, 0, 0.5));
492 ASSERT_NO_THROW(matrixBuilder5.addNextValue(1, 1, 0.7));
493 ASSERT_NO_THROW(matrixBuilder5.addNextValue(2, 2, 1.1));
494 ASSERT_NO_THROW(matrixBuilder5.addNextValue(3, 0, 0.1));
495 ASSERT_NO_THROW(matrixBuilder5.addNextValue(3, 1, 0.2));
496 ASSERT_NO_THROW(matrixBuilder5.addNextValue(3, 3, 0.3));
498 ASSERT_NO_THROW(matrix5 = matrixBuilder5.build());
499
500 ASSERT_TRUE(matrix4 == matrix5);
501}
502
503TEST(SparseMatrix, RestrictRows) {
504 storm::storage::SparseMatrixBuilder<double> matrixBuilder1(7, 4, 9, true, true, 3);
505 ASSERT_NO_THROW(matrixBuilder1.newRowGroup(0));
506 ASSERT_NO_THROW(matrixBuilder1.addNextValue(0, 1, 1.0));
507 ASSERT_NO_THROW(matrixBuilder1.addNextValue(0, 2, 1.2));
508 ASSERT_NO_THROW(matrixBuilder1.addNextValue(1, 0, 0.5));
509 ASSERT_NO_THROW(matrixBuilder1.addNextValue(1, 1, 0.7));
510 ASSERT_NO_THROW(matrixBuilder1.newRowGroup(2));
511 ASSERT_NO_THROW(matrixBuilder1.addNextValue(2, 0, 0.5));
512 ASSERT_NO_THROW(matrixBuilder1.addNextValue(3, 2, 1.1));
513 ASSERT_NO_THROW(matrixBuilder1.newRowGroup(4));
514 ASSERT_NO_THROW(matrixBuilder1.addNextValue(4, 0, 0.1));
515 ASSERT_NO_THROW(matrixBuilder1.addNextValue(4, 1, 0.2));
516 ASSERT_NO_THROW(matrixBuilder1.addNextValue(6, 3, 0.3));
518 ASSERT_NO_THROW(matrix1 = matrixBuilder1.build());
519
520 storm::storage::BitVector constraint1(7);
521 constraint1.set(0);
522 constraint1.set(1);
523 constraint1.set(2);
524 constraint1.set(5);
525
527 ASSERT_NO_THROW(matrix1Prime = matrix1.restrictRows(constraint1));
528
529 storm::storage::SparseMatrixBuilder<double> matrixBuilder2(4, 4, 5, true, true, 3);
530 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(0));
531 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
532 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
533 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
534 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
535 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(2));
536 ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 0, 0.5));
537 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(3));
539 ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
540
541 ASSERT_EQ(matrix2, matrix1Prime);
542
543 storm::storage::BitVector constraint2(4);
544 constraint2.set(1);
545 constraint2.set(2);
546
548 STORM_SILENT_ASSERT_THROW(matrix2Prime = matrix2.restrictRows(constraint2), storm::exceptions::InvalidArgumentException);
549 ASSERT_NO_THROW(matrix2Prime = matrix2.restrictRows(constraint2, true));
550
551 storm::storage::SparseMatrixBuilder<double> matrixBuilder3(2, 4, 3, true, true, 3);
552 ASSERT_NO_THROW(matrixBuilder3.newRowGroup(0));
553 ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 0, 0.5));
554 ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 1, 0.7));
555 ASSERT_NO_THROW(matrixBuilder3.newRowGroup(1));
556 ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 0, 0.5));
558 ASSERT_NO_THROW(matrix3 = matrixBuilder3.build());
559
560 ASSERT_EQ(matrix3, matrix2Prime);
561
562 matrix3.makeRowGroupingTrivial();
563 storm::storage::BitVector constraint3(2);
564 constraint3.set(1);
565
567 STORM_SILENT_ASSERT_THROW(matrix3Prime = matrix3.restrictRows(constraint3), storm::exceptions::InvalidArgumentException);
568 ASSERT_NO_THROW(matrix3Prime = matrix3.restrictRows(constraint3, true));
569
570 storm::storage::SparseMatrixBuilder<double> matrixBuilder4(1, 4, 1, true, true, 2);
571 ASSERT_NO_THROW(matrixBuilder4.newRowGroup(0));
572 ASSERT_NO_THROW(matrixBuilder4.newRowGroup(0));
573 ASSERT_NO_THROW(matrixBuilder4.addNextValue(0, 0, 0.5));
575 ASSERT_NO_THROW(matrix4 = matrixBuilder4.build());
576
577 ASSERT_EQ(matrix4, matrix3Prime);
578}
579
580TEST(SparseMatrix, Transpose) {
581 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9);
582 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
583 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
584 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
585 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
586 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
587 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
588 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
589 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
590 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
592 ASSERT_NO_THROW(matrix = matrixBuilder.build());
593
594 ASSERT_NO_THROW(storm::storage::SparseMatrix<double> transposeResult = matrix.transpose());
595 storm::storage::SparseMatrix<double> transposeResult = matrix.transpose();
596
597 storm::storage::SparseMatrixBuilder<double> matrixBuilder2(4, 5, 9);
598 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 0.5));
599 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 0.5));
600 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 4, 0.1));
601 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 1.0));
602 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
603 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 4, 0.2));
604 ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 0, 1.2));
605 ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 3, 1.1));
606 ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 4, 0.3));
608 ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
609
610 ASSERT_TRUE(transposeResult == matrix2);
611}
612
613TEST(SparseMatrix, EquationSystem) {
614 storm::storage::SparseMatrixBuilder<double> matrixBuilder(4, 4, 7);
615 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 0, 1.1));
616 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.2));
617 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.5));
618 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.7));
619 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
620 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 2, 0.99));
621 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 3, 0.11));
623 ASSERT_NO_THROW(matrix = matrixBuilder.build());
624
625 ASSERT_NO_THROW(matrix.convertToEquationSystem());
626
627 storm::storage::SparseMatrixBuilder<double> matrixBuilder2(4, 4, 7);
628 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 0, 1 - 1.1));
629 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, -1.2));
630 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 1 - 0.5));
631 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 3, -0.7));
632 ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 0, -0.5));
633 ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 2, 1 - 0.99));
634 ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 3, 1 - 0.11));
636 ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
637
638 ASSERT_TRUE(matrix == matrix2);
639}
640
641TEST(SparseMatrix, JacobiDecomposition) {
642 storm::storage::SparseMatrixBuilder<double> matrixBuilder(4, 4, 7);
643 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 0, 1.1));
644 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.2));
645 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.5));
646 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.7));
647 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
648 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 2, 0.99));
649 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 3, 0.11));
651 ASSERT_NO_THROW(matrix = matrixBuilder.build());
652
653 ASSERT_NO_THROW(matrix.getJacobiDecomposition());
654 std::pair<storm::storage::SparseMatrix<double>, std::vector<double>> jacobiDecomposition = matrix.getJacobiDecomposition();
655
657 ASSERT_NO_THROW(luBuilder.addNextValue(0, 1, 1.2));
658 ASSERT_NO_THROW(luBuilder.addNextValue(1, 3, 0.7));
659 ASSERT_NO_THROW(luBuilder.addNextValue(2, 0, 0.5));
661 ASSERT_NO_THROW(lu = luBuilder.build());
662
663 std::vector<double> dinv = {1 / 1.1, 1 / 0.5, 1 / 0.99, 1 / 0.11};
664 ASSERT_TRUE(lu == jacobiDecomposition.first);
665 ASSERT_TRUE(dinv == jacobiDecomposition.second);
666}
667
668TEST(SparseMatrix, PointwiseMultiplicationVector) {
669 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9);
670 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
671 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
672 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
673 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
674 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
675 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
676 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
677 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
678 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
680 ASSERT_NO_THROW(matrix = matrixBuilder.build());
681
682 storm::storage::SparseMatrixBuilder<double> matrixBuilder2(5, 4, 9);
683 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
684 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
685 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
686 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
687 ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 0, 0.5));
688 ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 2, 1.1));
689 ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 0, 0.1));
690 ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 1, 0.2));
691 ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 3, 0.3));
693 ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
694
695 ASSERT_NO_THROW(std::vector<double> pointwiseProductRowSums = matrix.getPointwiseProductRowSumVector(matrix2));
696 std::vector<double> pointwiseProductRowSums = matrix.getPointwiseProductRowSumVector(matrix2);
697
698 std::vector<double> correctResult = {1.0 * 1.0 + 1.2 * 1.2, 0.5 * 0.5 + 0.7 * 0.7, 0.5 * 0.5, 1.1 * 1.1, 0.1 * 0.1 + 0.2 * 0.2 + 0.3 * 0.3};
699 ASSERT_TRUE(pointwiseProductRowSums == correctResult);
700}
701
702TEST(SparseMatrix, MatrixVectorMultiply) {
703 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9);
704 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
705 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
706 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
707 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
708 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
709 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
710 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
711 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
712 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
714 ASSERT_NO_THROW(matrix = matrixBuilder.build());
715
716 std::vector<double> x = {1, 0.3, 1.4, 7.1};
717 std::vector<double> result(matrix.getRowCount());
718
719 ASSERT_NO_THROW(matrix.multiplyWithVector(x, result));
720
721 std::vector<double> correctResult = {1.0 * 0.3 + 1.2 * 1.4, 0.5 * 1 + 0.7 * 0.3, 0.5 * 1, 1.1 * 1.4, 0.1 * 1 + 0.2 * 0.3 + 0.3 * 7.1};
722
723 for (std::size_t index = 0; index < correctResult.size(); ++index) {
724 ASSERT_NEAR(result[index], correctResult[index], 1e-12);
725 }
726}
727
728TEST(SparseMatrix, Iteration) {
729 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9);
730 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
731 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
732 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
733 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
734 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
735 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
736 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
737 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
738 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
740 ASSERT_NO_THROW(matrix = matrixBuilder.build());
741
742 for (auto const& entry : matrix.getRow(4)) {
743 if (entry.getColumn() == 0) {
744 ASSERT_EQ(0.1, entry.getValue());
745 } else if (entry.getColumn() == 1) {
746 ASSERT_EQ(0.2, entry.getValue());
747 } else if (entry.getColumn() == 3) {
748 ASSERT_EQ(0.3, entry.getValue());
749 } else {
750 ASSERT_TRUE(false);
751 }
752 }
753
754 for (storm::storage::SparseMatrix<double>::iterator it = matrix.begin(4), ite = matrix.end(4); it != ite; ++it) {
755 if (it->getColumn() == 0) {
756 ASSERT_EQ(0.1, it->getValue());
757 } else if (it->getColumn() == 1) {
758 ASSERT_EQ(0.2, it->getValue());
759 } else if (it->getColumn() == 3) {
760 ASSERT_EQ(0.3, it->getValue());
761 } else {
762 ASSERT_TRUE(false);
763 }
764 }
765}
766
767TEST(SparseMatrix, RowSum) {
768 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 8);
769 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
770 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
771 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
772 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
773 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
774 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
775 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
776 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
778 ASSERT_NO_THROW(matrix = matrixBuilder.build());
779
780 ASSERT_EQ(0, matrix.getRowSum(2));
781 ASSERT_EQ(0.1 + 0.2 + 0.3, matrix.getRowSum(4));
782}
783
784TEST(SparseMatrix, IsSubmatrix) {
785 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 8);
786 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
787 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
788 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
789 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
790 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
791 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
792 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
793 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
795 ASSERT_NO_THROW(matrix = matrixBuilder.build());
796
797 storm::storage::SparseMatrixBuilder<double> matrixBuilder2(5, 4, 5);
798 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
799 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
800 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
801 ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 0, 0.1));
802 ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 1, 0.2));
804 ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
805
806 ASSERT_TRUE(matrix2.isSubmatrixOf(matrix));
807
808 storm::storage::SparseMatrixBuilder<double> matrixBuilder3(5, 4, 5);
809 ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 3, 1.0));
810 ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 0, 0.5));
811 ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 1, 0.7));
812 ASSERT_NO_THROW(matrixBuilder3.addNextValue(4, 0, 0.1));
813 ASSERT_NO_THROW(matrixBuilder3.addNextValue(4, 1, 0.2));
815 ASSERT_NO_THROW(matrix3 = matrixBuilder3.build());
816
817 ASSERT_FALSE(matrix3.isSubmatrixOf(matrix));
818 ASSERT_FALSE(matrix3.isSubmatrixOf(matrix2));
819}
820
821TEST(SparseMatrix, PermuteRows) {
822 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 8);
823 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
824 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
825 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
826 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
827 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
828 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
829 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
830 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
832 ASSERT_NO_THROW(matrix = matrixBuilder.build());
833
834 std::vector<uint64_t> inversePermutation = {1, 4, 0, 3, 2};
835 storm::storage::SparseMatrix<double> matrixperm = matrix.permuteRows(inversePermutation);
836 EXPECT_EQ(5ul, matrixperm.getRowCount());
837 EXPECT_EQ(4ul, matrixperm.getColumnCount());
838 EXPECT_EQ(8ul, matrixperm.getEntryCount());
839 EXPECT_EQ(matrix.getRowSum(1), matrixperm.getRowSum(0));
840 EXPECT_EQ(matrix.getRowSum(4), matrixperm.getRowSum(1));
841 EXPECT_EQ(matrix.getRowSum(0), matrixperm.getRowSum(2));
842 EXPECT_EQ(matrix.getRowSum(3), matrixperm.getRowSum(3));
843 EXPECT_EQ(matrix.getRowSum(2), matrixperm.getRowSum(4));
844}
845
846TEST(SparseMatrix, PermuteRowGroupsAndColumns) {
847 storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9, true, true, 4);
848 ASSERT_NO_THROW(matrixBuilder.newRowGroup(0));
849 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0)); // Group 0
850 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
851 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
852 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
853 ASSERT_NO_THROW(matrixBuilder.newRowGroup(2));
854 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5)); // Group 1
855 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
856 ASSERT_NO_THROW(matrixBuilder.newRowGroup(4));
857 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1)); // Group 2
858 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
859 ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
860 // Group 3 is empty
862 ASSERT_NO_THROW(matrix = matrixBuilder.build());
863
864 std::vector<uint64_t> permutation = {3, 0, 2, 1};
865 std::vector<uint64_t> invertedPermutation = {1, 3, 2, 0};
866 EXPECT_EQ(invertedPermutation, storm::utility::permutation::invertPermutation(permutation));
867 auto matrixPerm = matrix.permuteRowGroupsAndColumns(invertedPermutation, permutation);
868
869 storm::storage::SparseMatrixBuilder<double> expectedBuilder(5, 4, 9, true, true, 4);
870 ASSERT_NO_THROW(expectedBuilder.newRowGroup(0));
871 ASSERT_NO_THROW(expectedBuilder.addNextValue(0, 3, 0.5));
872 ASSERT_NO_THROW(expectedBuilder.addNextValue(1, 2, 1.1));
873 ASSERT_NO_THROW(expectedBuilder.newRowGroup(2));
874 ASSERT_NO_THROW(expectedBuilder.newRowGroup(2));
875 ASSERT_NO_THROW(expectedBuilder.addNextValue(2, 3, 0.1));
876 ASSERT_NO_THROW(expectedBuilder.addNextValue(2, 0, 0.2));
877 ASSERT_NO_THROW(expectedBuilder.addNextValue(2, 1, 0.3));
878 ASSERT_NO_THROW(expectedBuilder.newRowGroup(3));
879 ASSERT_NO_THROW(expectedBuilder.addNextValue(3, 0, 1.0));
880 ASSERT_NO_THROW(expectedBuilder.addNextValue(3, 2, 1.2));
881 ASSERT_NO_THROW(expectedBuilder.addNextValue(4, 3, 0.5));
882 ASSERT_NO_THROW(expectedBuilder.addNextValue(4, 0, 0.7));
884 ASSERT_NO_THROW(expectedMatrix = expectedBuilder.build());
885 EXPECT_EQ(expectedMatrix, matrixPerm);
886
887 auto matrixPerm2 = matrixPerm.permuteRowGroupsAndColumns(permutation, invertedPermutation);
888 EXPECT_EQ(matrix, matrixPerm2);
889}
890
891TEST(SparseMatrix, DropZeroEntries) {
892 storm::storage::SparseMatrixBuilder<double> matrixBuilder(4, 3, 8, true, true);
893 ASSERT_NO_THROW(matrixBuilder.newRowGroup(0));
894 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
895 ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
896 ASSERT_NO_THROW(matrixBuilder.newRowGroup(1));
897 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
898 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 1.1));
899 ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 2, 0.5));
900 ASSERT_NO_THROW(matrixBuilder.newRowGroup(2));
901 ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.1));
902 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 1, 0.2));
903 ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 0.3));
905 ASSERT_NO_THROW(matrix = matrixBuilder.build());
906
907 storm::storage::BitVector absorbingRows(3);
908 absorbingRows.set(0);
909
910 ASSERT_NO_THROW(matrix.makeRowsAbsorbing(absorbingRows, true));
911
912 storm::storage::SparseMatrixBuilder<double> matrixBuilderX(4, 3, 8, true, true);
913 ASSERT_NO_THROW(matrixBuilderX.newRowGroup(0));
914 ASSERT_NO_THROW(matrixBuilderX.addNextValue(0, 1, 1.0));
915 ASSERT_NO_THROW(matrixBuilderX.addNextValue(0, 2, 1.2));
916 ASSERT_NO_THROW(matrixBuilderX.newRowGroup(1));
917 ASSERT_NO_THROW(matrixBuilderX.addNextValue(1, 0, 0.5));
918 ASSERT_NO_THROW(matrixBuilderX.addNextValue(1, 1, 1.1));
919 ASSERT_NO_THROW(matrixBuilderX.addNextValue(1, 2, 0.5));
920 ASSERT_NO_THROW(matrixBuilderX.newRowGroup(2));
921 ASSERT_NO_THROW(matrixBuilderX.addNextValue(2, 0, 0.1));
922 ASSERT_NO_THROW(matrixBuilderX.addNextValue(3, 1, 0.2));
923 ASSERT_NO_THROW(matrixBuilderX.addNextValue(3, 2, 0.3));
925 ASSERT_NO_THROW(matrixX = matrixBuilderX.build());
926
927 ASSERT_NO_THROW(matrixX.makeRowsAbsorbing(absorbingRows, false));
928
929 storm::storage::SparseMatrixBuilder<double> matrixBuilder2(4, 3, 7, true, true);
930 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(0));
931 ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 0, 1.0));
932 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(1));
933 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
934 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 1.1));
935 ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 2, 0.5));
936 ASSERT_NO_THROW(matrixBuilder2.newRowGroup(2));
937 ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 0, 0.1));
938 ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 1, 0.2));
939 ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 2, 0.3));
941 ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
942
943 ASSERT_TRUE(matrix == matrix2);
944 ASSERT_TRUE(matrix.getEntryCount() == matrix2.getEntryCount());
945
946 ASSERT_TRUE(matrixX == matrix2);
947 ASSERT_FALSE(matrixX.getEntryCount() == matrix2.getEntryCount());
948
949 ASSERT_NO_THROW(matrix.makeRowDirac(1, 1, true));
950 ASSERT_NO_THROW(matrixX.dropZeroEntries());
951 ASSERT_NO_THROW(matrixX.makeRowDirac(1, 1, false));
952
953 storm::storage::SparseMatrixBuilder<double> matrixBuilder3(4, 3, 5, true, true);
954 ASSERT_NO_THROW(matrixBuilder3.newRowGroup(0));
955 ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 0, 1.0));
956 ASSERT_NO_THROW(matrixBuilder3.newRowGroup(1));
957 ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 1, 1.0));
958 ASSERT_NO_THROW(matrixBuilder3.newRowGroup(2));
959 ASSERT_NO_THROW(matrixBuilder3.addNextValue(2, 0, 0.1));
960 ASSERT_NO_THROW(matrixBuilder3.addNextValue(3, 1, 0.2));
961 ASSERT_NO_THROW(matrixBuilder3.addNextValue(3, 2, 0.3));
963 ASSERT_NO_THROW(matrix3 = matrixBuilder3.build());
964
965 ASSERT_TRUE(matrix == matrix3);
966 ASSERT_TRUE(matrix.getEntryCount() == matrix3.getEntryCount());
967
968 ASSERT_TRUE(matrixX == matrix3);
969 ASSERT_FALSE(matrixX.getEntryCount() == matrix3.getEntryCount());
970
971 storm::storage::BitVector absorbingRowGroups(3);
972 absorbingRowGroups.set(2);
973
974 ASSERT_NO_THROW(matrix.makeRowGroupsAbsorbing(absorbingRowGroups, true));
975 ASSERT_NO_THROW(matrixX.dropZeroEntries());
976 ASSERT_NO_THROW(matrixX.makeRowGroupsAbsorbing(absorbingRowGroups, false));
977
978 storm::storage::SparseMatrixBuilder<double> matrixBuilder4(4, 3, 4, true, true);
979 ASSERT_NO_THROW(matrixBuilder4.newRowGroup(0));
980 ASSERT_NO_THROW(matrixBuilder4.addNextValue(0, 0, 1.0));
981 ASSERT_NO_THROW(matrixBuilder4.newRowGroup(1));
982 ASSERT_NO_THROW(matrixBuilder4.addNextValue(1, 1, 1.0));
983 ASSERT_NO_THROW(matrixBuilder4.newRowGroup(2));
984 ASSERT_NO_THROW(matrixBuilder4.addNextValue(2, 2, 1.0));
985 ASSERT_NO_THROW(matrixBuilder4.addNextValue(3, 2, 1.0));
987 ASSERT_NO_THROW(matrix4 = matrixBuilder4.build());
988
989 ASSERT_TRUE(matrix == matrix4);
990 ASSERT_TRUE(matrix.getEntryCount() == matrix4.getEntryCount());
991
992 ASSERT_TRUE(matrixX == matrix4);
993 ASSERT_FALSE(matrixX.getEntryCount() == matrix4.getEntryCount());
994}
TEST(SparseMatrixBuilder, CreationEmpty)
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
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.
void addDiagonalEntry(index_type row, ValueType const &value)
Makes sure that a diagonal entry will be inserted at the given row.
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.
void convertToEquationSystem()
Transforms the matrix into an equation system.
const_rows getRow(index_type row) const
Returns an object representing the given row.
SparseMatrix selectRowsFromRowGroups(std::vector< index_type > const &rowGroupToRowIndexMapping, bool insertDiagonalEntries=true) const
Selects exactly one row from each row group of this matrix and returns the resulting matrix.
index_type getEntryCount() const
Returns the number of entries in the matrix.
void makeRowsAbsorbing(storm::storage::BitVector const &rows, bool dropZeroEntries=false)
This function makes the given rows absorbing.
std::vector< ResultValueType > getPointwiseProductRowSumVector(storm::storage::SparseMatrix< OtherValueType > const &otherMatrix) const
Performs a pointwise matrix multiplication of the matrix with the given matrix and returns a vector c...
void multiplyWithVector(std::vector< value_type > const &vector, std::vector< value_type > &result, std::vector< value_type > const *summand=nullptr) const
Multiplies the matrix with the given vector and writes the result to the given result vector.
SparseMatrix getSubmatrix(bool useGroups, storm::storage::BitVector const &rowConstraint, storm::storage::BitVector const &columnConstraint, bool insertDiagonalEntries=false, storm::storage::BitVector const &makeZeroColumns=storm::storage::BitVector()) const
Creates a submatrix of the current matrix by dropping all rows and columns whose bits are not set to ...
const_iterator begin(index_type row) const
Retrieves an iterator that points to the beginning of the given row.
std::vector< value_type > getConstrainedRowSumVector(storm::storage::BitVector const &rowConstraint, storm::storage::BitVector const &columnConstraint) const
Computes a vector whose i-th entry is the sum of the entries in the i-th selected row where only thos...
SparseMatrix permuteRows(std::vector< index_type > const &inversePermutation) const
Permute rows of the matrix according to the vector.
SparseMatrix restrictRows(storm::storage::BitVector const &rowsToKeep, bool allowEmptyRowGroups=false) const
Restrict rows in grouped rows matrix.
value_type getRowSum(index_type row) const
Computes the sum of the entries in a given row.
const_iterator end(index_type row) const
Retrieves an iterator that points past the end of the given row.
SparseMatrix permuteRowGroupsAndColumns(std::vector< index_type > const &inverseRowGroupPermutation, std::vector< index_type > const &columnPermutation) const
Permutes row groups and columns of the matrix according to the given permutations.
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
void dropZeroEntries()
Removes all zero entries from this.
bool isSubmatrixOf(SparseMatrix< OtherValueType > const &matrix) const
Checks if the current matrix is a submatrix of the given matrix, where a matrix A is called a submatr...
void makeRowGroupsAbsorbing(storm::storage::BitVector const &rowGroupConstraint, bool dropZeroEntries=false)
This function makes the groups of rows given by the bit vector absorbing.
index_type getColumnCount() const
Returns the number of columns of the matrix.
std::pair< storm::storage::SparseMatrix< value_type >, std::vector< value_type > > getJacobiDecomposition() const
Calculates the Jacobi decomposition of this sparse matrix.
void makeRowDirac(index_type row, index_type column, bool dropZeroEntries=false)
This function makes the given row Dirac.
void makeRowGroupingTrivial()
Makes the row grouping of this matrix trivial.
std::vector< index_type > const & getRowGroupIndices() const
Returns the grouping of rows of this matrix.
std::vector< MatrixEntry< index_type, value_type > >::iterator iterator
std::vector< value_type > getConstrainedRowGroupSumVector(storm::storage::BitVector const &rowGroupConstraint, storm::storage::BitVector const &columnConstraint) const
Computes a vector whose entries represent the sums of selected columns for all rows in selected row g...
storm::storage::SparseMatrix< value_type > transpose(bool joinGroups=false, bool keepZeros=false) const
Transposes the matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
std::vector< index_type > invertPermutation(std::vector< index_type > const &permutation)
Inverts the given permutation.
#define STORM_SILENT_ASSERT_THROW(statement, expected_exception)
Definition storm_gtest.h:26