You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

611 lines
29 KiB

  1. #include "gtest/gtest.h"
  2. #include "src/storage/SparseMatrix.h"
  3. #include "src/exceptions/InvalidStateException.h"
  4. #include "src/exceptions/OutOfRangeException.h"
  5. TEST(SparseMatrixBuilder, CreationWithDimensions) {
  6. storm::storage::SparseMatrixBuilder<double> matrixBuilder(3, 4, 5);
  7. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  8. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  9. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  10. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  11. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
  12. storm::storage::SparseMatrix<double> matrix;
  13. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  14. ASSERT_EQ(3ul, matrix.getRowCount());
  15. ASSERT_EQ(4ul, matrix.getColumnCount());
  16. ASSERT_EQ(5ul, matrix.getEntryCount());
  17. }
  18. TEST(SparseMatrixBuilder, CreationWithoutNumberOfEntries) {
  19. storm::storage::SparseMatrixBuilder<double> matrixBuilder(3, 4);
  20. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  21. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  22. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  23. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  24. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
  25. storm::storage::SparseMatrix<double> matrix;
  26. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  27. ASSERT_EQ(3ul, matrix.getRowCount());
  28. ASSERT_EQ(4ul, matrix.getColumnCount());
  29. ASSERT_EQ(5ul, matrix.getEntryCount());
  30. }
  31. TEST(SparseMatrixBuilder, CreationWithNumberOfRows) {
  32. storm::storage::SparseMatrixBuilder<double> matrixBuilder(3);
  33. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  34. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  35. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  36. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  37. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
  38. storm::storage::SparseMatrix<double> matrix;
  39. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  40. ASSERT_EQ(3ul, matrix.getRowCount());
  41. ASSERT_EQ(4ul, matrix.getColumnCount());
  42. ASSERT_EQ(5ul, matrix.getEntryCount());
  43. }
  44. TEST(SparseMatrixBuilder, CreationWithoutDimensions) {
  45. storm::storage::SparseMatrixBuilder<double> matrixBuilder;
  46. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  47. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 3, 1.2));
  48. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  49. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  50. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 2, 0.2));
  51. storm::storage::SparseMatrix<double> matrix;
  52. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  53. ASSERT_EQ(2ul, matrix.getRowCount());
  54. ASSERT_EQ(4ul, matrix.getColumnCount());
  55. ASSERT_EQ(5ul, matrix.getEntryCount());
  56. }
  57. TEST(SparseMatrixBuilder, AddNextValue) {
  58. storm::storage::SparseMatrixBuilder<double> matrixBuilder1(3, 4, 5);
  59. ASSERT_NO_THROW(matrixBuilder1.addNextValue(0, 1, 1.0));
  60. ASSERT_NO_THROW(matrixBuilder1.addNextValue(0, 2, 1.2));
  61. ASSERT_THROW(matrixBuilder1.addNextValue(0, 4, 0.5), storm::exceptions::OutOfRangeException);
  62. ASSERT_THROW(matrixBuilder1.addNextValue(3, 1, 0.5), storm::exceptions::OutOfRangeException);
  63. storm::storage::SparseMatrixBuilder<double> matrixBuilder2(3, 4);
  64. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
  65. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
  66. ASSERT_THROW(matrixBuilder2.addNextValue(0, 4, 0.5), storm::exceptions::OutOfRangeException);
  67. ASSERT_THROW(matrixBuilder2.addNextValue(3, 1, 0.5), storm::exceptions::OutOfRangeException);
  68. storm::storage::SparseMatrixBuilder<double> matrixBuilder3(3);
  69. ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 1, 1.0));
  70. ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 2, 1.2));
  71. ASSERT_NO_THROW(matrixBuilder3.addNextValue(2, 4, 0.5));
  72. ASSERT_THROW(matrixBuilder3.addNextValue(3, 1, 0.2), storm::exceptions::OutOfRangeException);
  73. storm::storage::SparseMatrixBuilder<double> matrixBuilder4;
  74. ASSERT_NO_THROW(matrixBuilder4.addNextValue(0, 1, 1.0));
  75. ASSERT_NO_THROW(matrixBuilder4.addNextValue(1, 2, 1.2));
  76. ASSERT_NO_THROW(matrixBuilder4.addNextValue(2, 4, 0.5));
  77. ASSERT_NO_THROW(matrixBuilder4.addNextValue(3, 1, 0.2));
  78. }
  79. TEST(SparseMatrix, Build) {
  80. storm::storage::SparseMatrixBuilder<double> matrixBuilder1(3, 4, 5);
  81. ASSERT_NO_THROW(matrixBuilder1.addNextValue(0, 1, 1.0));
  82. ASSERT_NO_THROW(matrixBuilder1.addNextValue(0, 2, 1.2));
  83. ASSERT_NO_THROW(matrixBuilder1.addNextValue(1, 0, 0.5));
  84. ASSERT_NO_THROW(matrixBuilder1.addNextValue(1, 1, 0.7));
  85. ASSERT_NO_THROW(matrixBuilder1.addNextValue(1, 3, 0.2));
  86. ASSERT_NO_THROW(matrixBuilder1.build());
  87. storm::storage::SparseMatrixBuilder<double> matrixBuilder2(3, 4, 5);
  88. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
  89. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
  90. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
  91. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
  92. ASSERT_THROW(matrixBuilder2.build(), storm::exceptions::InvalidStateException);
  93. storm::storage::SparseMatrixBuilder<double> matrixBuilder3;
  94. ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 1, 1.0));
  95. ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 2, 1.2));
  96. ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 0, 0.5));
  97. ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 1, 0.7));
  98. ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 3, 0.2));
  99. storm::storage::SparseMatrix<double> matrix3;
  100. ASSERT_NO_THROW(matrix3 = matrixBuilder3.build());
  101. ASSERT_EQ(2ul, matrix3.getRowCount());
  102. ASSERT_EQ(4ul, matrix3.getColumnCount());
  103. ASSERT_EQ(5ul, matrix3.getEntryCount());
  104. storm::storage::SparseMatrixBuilder<double> matrixBuilder4;
  105. ASSERT_NO_THROW(matrixBuilder4.addNextValue(0, 1, 1.0));
  106. ASSERT_NO_THROW(matrixBuilder4.addNextValue(0, 2, 1.2));
  107. ASSERT_NO_THROW(matrixBuilder4.addNextValue(1, 0, 0.5));
  108. ASSERT_NO_THROW(matrixBuilder4.addNextValue(1, 1, 0.7));
  109. ASSERT_NO_THROW(matrixBuilder4.addNextValue(1, 3, 0.2));
  110. storm::storage::SparseMatrix<double> matrix4;
  111. ASSERT_NO_THROW(matrix4 = matrixBuilder4.build(4));
  112. ASSERT_EQ(4ul, matrix4.getRowCount());
  113. ASSERT_EQ(4ul, matrix4.getColumnCount());
  114. ASSERT_EQ(5ul, matrix4.getEntryCount());
  115. storm::storage::SparseMatrixBuilder<double> matrixBuilder5;
  116. ASSERT_NO_THROW(matrixBuilder5.addNextValue(0, 1, 1.0));
  117. ASSERT_NO_THROW(matrixBuilder5.addNextValue(0, 2, 1.2));
  118. ASSERT_NO_THROW(matrixBuilder5.addNextValue(1, 0, 0.5));
  119. ASSERT_NO_THROW(matrixBuilder5.addNextValue(1, 1, 0.7));
  120. ASSERT_NO_THROW(matrixBuilder5.addNextValue(1, 3, 0.2));
  121. storm::storage::SparseMatrix<double> matrix5;
  122. ASSERT_NO_THROW(matrix5 = matrixBuilder5.build(0, 6));
  123. ASSERT_EQ(2ul, matrix5.getRowCount());
  124. ASSERT_EQ(6ul, matrix5.getColumnCount());
  125. ASSERT_EQ(5ul, matrix5.getEntryCount());
  126. }
  127. TEST(SparseMatrix, CreationWithMovingContents) {
  128. std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>> columnsAndValues;
  129. columnsAndValues.emplace_back(1, 1.0);
  130. columnsAndValues.emplace_back(2, 1.2);
  131. columnsAndValues.emplace_back(0, 0.5);
  132. columnsAndValues.emplace_back(1, 0.7);
  133. columnsAndValues.emplace_back(3, 0.2);
  134. ASSERT_NO_THROW(storm::storage::SparseMatrix<double> matrix(4, {0, 2, 5, 5}, columnsAndValues, {0, 1, 2, 3}, false));
  135. storm::storage::SparseMatrix<double> matrix(4, {0, 2, 5, 5}, columnsAndValues, {0, 1, 2, 3}, false);
  136. ASSERT_EQ(3ul, matrix.getRowCount());
  137. ASSERT_EQ(4ul, matrix.getColumnCount());
  138. ASSERT_EQ(5ul, matrix.getEntryCount());
  139. ASSERT_EQ(3ul, matrix.getRowGroupCount());
  140. }
  141. TEST(SparseMatrix, CopyConstruct) {
  142. storm::storage::SparseMatrixBuilder<double> matrixBuilder;
  143. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  144. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  145. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  146. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  147. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
  148. storm::storage::SparseMatrix<double> matrix;
  149. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  150. ASSERT_NO_THROW(storm::storage::SparseMatrix<double> copy(matrix));
  151. storm::storage::SparseMatrix<double> copy(matrix);
  152. ASSERT_TRUE(matrix == copy);
  153. }
  154. TEST(SparseMatrix, CopyAssign) {
  155. storm::storage::SparseMatrixBuilder<double> matrixBuilder;
  156. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  157. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  158. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  159. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  160. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
  161. storm::storage::SparseMatrix<double> matrix;
  162. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  163. ASSERT_NO_THROW(storm::storage::SparseMatrix<double> copy = matrix);
  164. storm::storage::SparseMatrix<double> copy = matrix;
  165. ASSERT_TRUE(matrix == copy);
  166. }
  167. TEST(SparseMatrix, MakeAbsorbing) {
  168. storm::storage::SparseMatrixBuilder<double> matrixBuilder(3, 4, 5);
  169. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  170. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  171. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  172. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  173. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.2));
  174. storm::storage::SparseMatrix<double> matrix;
  175. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  176. storm::storage::BitVector absorbingRows(3);
  177. absorbingRows.set(1);
  178. ASSERT_NO_THROW(matrix.makeRowsAbsorbing(absorbingRows));
  179. storm::storage::SparseMatrixBuilder<double> matrixBuilder2(3, 4, 3);
  180. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
  181. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
  182. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 1));
  183. storm::storage::SparseMatrix<double> matrix2;
  184. ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
  185. ASSERT_TRUE(matrix == matrix2);
  186. }
  187. TEST(SparseMatrix, MakeRowGroupAbsorbing) {
  188. storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9, true, true);
  189. ASSERT_NO_THROW(matrixBuilder.newRowGroup(0));
  190. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  191. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  192. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  193. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  194. ASSERT_NO_THROW(matrixBuilder.newRowGroup(2));
  195. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
  196. ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
  197. ASSERT_NO_THROW(matrixBuilder.newRowGroup(4));
  198. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
  199. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
  200. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
  201. storm::storage::SparseMatrix<double> matrix;
  202. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  203. storm::storage::BitVector absorbingRowGroups(3);
  204. absorbingRowGroups.set(1);
  205. ASSERT_NO_THROW(matrix.makeRowGroupsAbsorbing(absorbingRowGroups));
  206. storm::storage::SparseMatrixBuilder<double> matrixBuilder2(0, 0, 0, false, true);
  207. ASSERT_NO_THROW(matrixBuilder2.newRowGroup(0));
  208. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
  209. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
  210. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
  211. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
  212. ASSERT_NO_THROW(matrixBuilder2.newRowGroup(2));
  213. ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 1, 1));
  214. ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 1, 1));
  215. ASSERT_NO_THROW(matrixBuilder2.newRowGroup(4));
  216. ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 0, 0.1));
  217. ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 1, 0.2));
  218. ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 3, 0.3));
  219. storm::storage::SparseMatrix<double> matrix2;
  220. ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
  221. ASSERT_TRUE(matrix == matrix2);
  222. }
  223. TEST(SparseMatrix, ConstrainedRowSumVector) {
  224. storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9);
  225. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  226. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  227. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  228. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  229. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
  230. ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
  231. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
  232. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
  233. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
  234. storm::storage::SparseMatrix<double> matrix;
  235. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  236. storm::storage::BitVector columnConstraint(4);
  237. columnConstraint.set(1);
  238. columnConstraint.set(3);
  239. ASSERT_NO_THROW(std::vector<double> constrainedRowSum = matrix.getConstrainedRowSumVector(storm::storage::BitVector(5, true), columnConstraint));
  240. std::vector<double> constrainedRowSum = matrix.getConstrainedRowSumVector(storm::storage::BitVector(5, true), columnConstraint);
  241. ASSERT_TRUE(constrainedRowSum == std::vector<double>({1.0, 0.7, 0, 0, 0.5}));
  242. storm::storage::SparseMatrixBuilder<double> matrixBuilder2(5, 4, 9, true, true);
  243. ASSERT_NO_THROW(matrixBuilder2.newRowGroup(0));
  244. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
  245. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
  246. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
  247. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
  248. ASSERT_NO_THROW(matrixBuilder2.newRowGroup(2));
  249. ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 0, 0.5));
  250. ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 2, 1.1));
  251. ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 3, 1.2));
  252. ASSERT_NO_THROW(matrixBuilder2.newRowGroup(4));
  253. ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 0, 0.1));
  254. ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 3, 0.3));
  255. storm::storage::SparseMatrix<double> matrix2;
  256. ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
  257. storm::storage::BitVector rowGroupConstraint(3);
  258. rowGroupConstraint.set(1);
  259. storm::storage::BitVector columnConstraint2(4);
  260. columnConstraint2.set(2);
  261. columnConstraint2.set(3);
  262. ASSERT_NO_THROW(std::vector<double> constrainedRowSum2 = matrix2.getConstrainedRowGroupSumVector(rowGroupConstraint, columnConstraint2));
  263. std::vector<double> constrainedRowSum2 = matrix2.getConstrainedRowGroupSumVector(rowGroupConstraint, columnConstraint2);
  264. ASSERT_TRUE(constrainedRowSum2 == std::vector<double>({0, 2.3}));
  265. }
  266. TEST(SparseMatrix, Submatrix) {
  267. storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9, true, true);
  268. ASSERT_NO_THROW(matrixBuilder.newRowGroup(0));
  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.newRowGroup(1));
  272. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  273. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  274. ASSERT_NO_THROW(matrixBuilder.newRowGroup(2));
  275. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
  276. ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
  277. ASSERT_NO_THROW(matrixBuilder.newRowGroup(4));
  278. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
  279. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
  280. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
  281. storm::storage::SparseMatrix<double> matrix;
  282. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  283. std::vector<uint_fast64_t> rowGroupIndices = {0, 1, 2, 4, 5};
  284. storm::storage::BitVector rowGroupConstraint(4);
  285. rowGroupConstraint.set(2);
  286. rowGroupConstraint.set(3);
  287. storm::storage::BitVector columnConstraint(4);
  288. columnConstraint.set(0);
  289. columnConstraint.set(3);
  290. ASSERT_NO_THROW(storm::storage::SparseMatrix<double> matrix2 = matrix.getSubmatrix(true, rowGroupConstraint, columnConstraint, false));
  291. storm::storage::SparseMatrix<double> matrix2 = matrix.getSubmatrix(true, rowGroupConstraint, columnConstraint, false);
  292. storm::storage::SparseMatrixBuilder<double> matrixBuilder3(3, 2, 3, true, true);
  293. ASSERT_NO_THROW(matrixBuilder3.newRowGroup(0));
  294. ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 0, 0.5));
  295. ASSERT_NO_THROW(matrixBuilder3.newRowGroup(2));
  296. ASSERT_NO_THROW(matrixBuilder3.addNextValue(2, 0, 0.1));
  297. ASSERT_NO_THROW(matrixBuilder3.addNextValue(2, 1, 0.3));
  298. storm::storage::SparseMatrix<double> matrix3;
  299. ASSERT_NO_THROW(matrix3 = matrixBuilder3.build());
  300. ASSERT_TRUE(matrix2 == matrix3);
  301. std::vector<uint_fast64_t> rowGroupToIndexMapping = {0, 0, 1, 0};
  302. ASSERT_NO_THROW(storm::storage::SparseMatrix<double> matrix4 = matrix.selectRowsFromRowGroups(rowGroupToIndexMapping));
  303. storm::storage::SparseMatrix<double> matrix4 = matrix.selectRowsFromRowGroups(rowGroupToIndexMapping);
  304. storm::storage::SparseMatrixBuilder<double> matrixBuilder5(4, 4, 8);
  305. ASSERT_NO_THROW(matrixBuilder5.addNextValue(0, 1, 1.0));
  306. ASSERT_NO_THROW(matrixBuilder5.addNextValue(0, 2, 1.2));
  307. ASSERT_NO_THROW(matrixBuilder5.addNextValue(1, 0, 0.5));
  308. ASSERT_NO_THROW(matrixBuilder5.addNextValue(1, 1, 0.7));
  309. ASSERT_NO_THROW(matrixBuilder5.addNextValue(2, 2, 1.1));
  310. ASSERT_NO_THROW(matrixBuilder5.addNextValue(3, 0, 0.1));
  311. ASSERT_NO_THROW(matrixBuilder5.addNextValue(3, 1, 0.2));
  312. ASSERT_NO_THROW(matrixBuilder5.addNextValue(3, 3, 0.3));
  313. storm::storage::SparseMatrix<double> matrix5;
  314. ASSERT_NO_THROW(matrix5 = matrixBuilder5.build());
  315. ASSERT_TRUE(matrix4 == matrix5);
  316. }
  317. TEST(SparseMatrix, Transpose) {
  318. storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9);
  319. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  320. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  321. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  322. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  323. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
  324. ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
  325. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
  326. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
  327. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
  328. storm::storage::SparseMatrix<double> matrix;
  329. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  330. ASSERT_NO_THROW(storm::storage::SparseMatrix<double> transposeResult = matrix.transpose());
  331. storm::storage::SparseMatrix<double> transposeResult = matrix.transpose();
  332. storm::storage::SparseMatrixBuilder<double> matrixBuilder2(4, 5, 9);
  333. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 0.5));
  334. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 0.5));
  335. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 4, 0.1));
  336. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 1.0));
  337. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
  338. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 4, 0.2));
  339. ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 0, 1.2));
  340. ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 3, 1.1));
  341. ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 4, 0.3));
  342. storm::storage::SparseMatrix<double> matrix2;
  343. ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
  344. ASSERT_TRUE(transposeResult == matrix2);
  345. }
  346. TEST(SparseMatrix, EquationSystem) {
  347. storm::storage::SparseMatrixBuilder<double> matrixBuilder(4, 4, 7);
  348. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 0, 1.1));
  349. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.2));
  350. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.5));
  351. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.7));
  352. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
  353. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 2, 0.99));
  354. ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 3, 0.11));
  355. storm::storage::SparseMatrix<double> matrix;
  356. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  357. ASSERT_NO_THROW(matrix.convertToEquationSystem());
  358. storm::storage::SparseMatrixBuilder<double> matrixBuilder2(4, 4, 7);
  359. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 0, 1 - 1.1));
  360. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, -1.2));
  361. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 1 - 0.5));
  362. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 3, -0.7));
  363. ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 0, -0.5));
  364. ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 2, 1 - 0.99));
  365. ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 3, 1 - 0.11));
  366. storm::storage::SparseMatrix<double> matrix2;
  367. ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
  368. ASSERT_TRUE(matrix == matrix2);
  369. }
  370. TEST(SparseMatrix, JacobiDecomposition) {
  371. storm::storage::SparseMatrixBuilder<double> matrixBuilder(4, 4, 7);
  372. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 0, 1.1));
  373. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.2));
  374. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.5));
  375. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 3, 0.7));
  376. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
  377. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 2, 0.99));
  378. ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 3, 0.11));
  379. storm::storage::SparseMatrix<double> matrix;
  380. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  381. ASSERT_NO_THROW(matrix.getJacobiDecomposition());
  382. std::pair<storm::storage::SparseMatrix<double>, std::vector<double>> jacobiDecomposition = matrix.getJacobiDecomposition();
  383. storm::storage::SparseMatrixBuilder<double> luBuilder(4, 4, 3);
  384. ASSERT_NO_THROW(luBuilder.addNextValue(0, 1, 1.2));
  385. ASSERT_NO_THROW(luBuilder.addNextValue(1, 3, 0.7));
  386. ASSERT_NO_THROW(luBuilder.addNextValue(2, 0, 0.5));
  387. storm::storage::SparseMatrix<double> lu;
  388. ASSERT_NO_THROW(lu = luBuilder.build());
  389. std::vector<double> dinv = {1/1.1, 1/0.5, 1/0.99, 1/0.11};
  390. ASSERT_TRUE(lu == jacobiDecomposition.first);
  391. ASSERT_TRUE(dinv == jacobiDecomposition.second);
  392. }
  393. TEST(SparseMatrix, PointwiseMultiplicationVector) {
  394. storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9);
  395. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  396. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  397. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  398. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  399. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
  400. ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
  401. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
  402. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
  403. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
  404. storm::storage::SparseMatrix<double> matrix;
  405. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  406. storm::storage::SparseMatrixBuilder<double> matrixBuilder2(5, 4, 9);
  407. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
  408. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 2, 1.2));
  409. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
  410. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
  411. ASSERT_NO_THROW(matrixBuilder2.addNextValue(2, 0, 0.5));
  412. ASSERT_NO_THROW(matrixBuilder2.addNextValue(3, 2, 1.1));
  413. ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 0, 0.1));
  414. ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 1, 0.2));
  415. ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 3, 0.3));
  416. storm::storage::SparseMatrix<double> matrix2;
  417. ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
  418. ASSERT_NO_THROW(std::vector<double> pointwiseProductRowSums = matrix.getPointwiseProductRowSumVector(matrix2));
  419. std::vector<double> pointwiseProductRowSums = matrix.getPointwiseProductRowSumVector(matrix2);
  420. 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};
  421. ASSERT_TRUE(pointwiseProductRowSums == correctResult);
  422. }
  423. TEST(SparseMatrix, MatrixVectorMultiply) {
  424. storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9);
  425. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  426. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  427. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  428. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  429. ASSERT_NO_THROW(matrixBuilder.addNextValue(2, 0, 0.5));
  430. ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
  431. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
  432. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
  433. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
  434. storm::storage::SparseMatrix<double> matrix;
  435. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  436. std::vector<double> x = {1, 0.3, 1.4, 7.1};
  437. std::vector<double> result(matrix.getRowCount());
  438. ASSERT_NO_THROW(matrix.multiplyWithVector(x, result));
  439. 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};
  440. ASSERT_TRUE(result == correctResult);
  441. }
  442. TEST(SparseMatrix, Iteration) {
  443. storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 9);
  444. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  445. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  446. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  447. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  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.addNextValue(4, 0, 0.1));
  451. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
  452. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
  453. storm::storage::SparseMatrix<double> matrix;
  454. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  455. for (auto const& entry : matrix.getRow(4)) {
  456. if (entry.getColumn() == 0) {
  457. ASSERT_EQ(0.1, entry.getValue());
  458. } else if (entry.getColumn() == 1) {
  459. ASSERT_EQ(0.2, entry.getValue());
  460. } else if (entry.getColumn() == 3) {
  461. ASSERT_EQ(0.3, entry.getValue());
  462. } else {
  463. ASSERT_TRUE(false);
  464. }
  465. }
  466. for (storm::storage::SparseMatrix<double>::iterator it = matrix.begin(4), ite = matrix.end(4); it != ite; ++it) {
  467. if (it->getColumn() == 0) {
  468. ASSERT_EQ(0.1, it->getValue());
  469. } else if (it->getColumn() == 1) {
  470. ASSERT_EQ(0.2, it->getValue());
  471. } else if (it->getColumn() == 3) {
  472. ASSERT_EQ(0.3, it->getValue());
  473. } else {
  474. ASSERT_TRUE(false);
  475. }
  476. }
  477. }
  478. TEST(SparseMatrix, RowSum) {
  479. storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 8);
  480. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  481. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  482. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  483. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  484. ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
  485. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
  486. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
  487. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
  488. storm::storage::SparseMatrix<double> matrix;
  489. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  490. ASSERT_EQ(0, matrix.getRowSum(2));
  491. ASSERT_EQ(0.1+0.2+0.3, matrix.getRowSum(4));
  492. }
  493. TEST(SparseMatrix, IsSubmatrix) {
  494. storm::storage::SparseMatrixBuilder<double> matrixBuilder(5, 4, 8);
  495. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0));
  496. ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 2, 1.2));
  497. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 0, 0.5));
  498. ASSERT_NO_THROW(matrixBuilder.addNextValue(1, 1, 0.7));
  499. ASSERT_NO_THROW(matrixBuilder.addNextValue(3, 2, 1.1));
  500. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 0, 0.1));
  501. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 1, 0.2));
  502. ASSERT_NO_THROW(matrixBuilder.addNextValue(4, 3, 0.3));
  503. storm::storage::SparseMatrix<double> matrix;
  504. ASSERT_NO_THROW(matrix = matrixBuilder.build());
  505. storm::storage::SparseMatrixBuilder<double> matrixBuilder2(5, 4, 5);
  506. ASSERT_NO_THROW(matrixBuilder2.addNextValue(0, 1, 1.0));
  507. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 0, 0.5));
  508. ASSERT_NO_THROW(matrixBuilder2.addNextValue(1, 1, 0.7));
  509. ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 0, 0.1));
  510. ASSERT_NO_THROW(matrixBuilder2.addNextValue(4, 1, 0.2));
  511. storm::storage::SparseMatrix<double> matrix2;
  512. ASSERT_NO_THROW(matrix2 = matrixBuilder2.build());
  513. ASSERT_TRUE(matrix2.isSubmatrixOf(matrix));
  514. storm::storage::SparseMatrixBuilder<double> matrixBuilder3(5, 4, 5);
  515. ASSERT_NO_THROW(matrixBuilder3.addNextValue(0, 3, 1.0));
  516. ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 0, 0.5));
  517. ASSERT_NO_THROW(matrixBuilder3.addNextValue(1, 1, 0.7));
  518. ASSERT_NO_THROW(matrixBuilder3.addNextValue(4, 0, 0.1));
  519. ASSERT_NO_THROW(matrixBuilder3.addNextValue(4, 1, 0.2));
  520. storm::storage::SparseMatrix<double> matrix3;
  521. ASSERT_NO_THROW(matrix3 = matrixBuilder3.build());
  522. ASSERT_FALSE(matrix3.isSubmatrixOf(matrix));
  523. ASSERT_FALSE(matrix3.isSubmatrixOf(matrix2));
  524. }