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.

616 lines
29 KiB

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