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