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.

422 lines
18 KiB

  1. #include "gtest/gtest.h"
  2. #include "storm-config.h"
  3. #include "src/exceptions/InvalidArgumentException.h"
  4. #include "src/storage/dd/CuddDdManager.h"
  5. #include "src/storage/dd/CuddDd.h"
  6. #include "src/storage/dd/CuddOdd.h"
  7. #include "src/storage/dd/DdMetaVariable.h"
  8. TEST(CuddDdManager, Constants) {
  9. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  10. storm::dd::Dd<storm::dd::DdType::CUDD> zero;
  11. ASSERT_NO_THROW(zero = manager->getZero());
  12. EXPECT_EQ(0, zero.getNonZeroCount());
  13. EXPECT_EQ(1, zero.getLeafCount());
  14. EXPECT_EQ(1, zero.getNodeCount());
  15. EXPECT_EQ(0, zero.getMin());
  16. EXPECT_EQ(0, zero.getMax());
  17. storm::dd::Dd<storm::dd::DdType::CUDD> one;
  18. ASSERT_NO_THROW(one = manager->getOne());
  19. EXPECT_EQ(1, one.getNonZeroCount());
  20. EXPECT_EQ(1, one.getLeafCount());
  21. EXPECT_EQ(1, one.getNodeCount());
  22. EXPECT_EQ(1, one.getMin());
  23. EXPECT_EQ(1, one.getMax());
  24. storm::dd::Dd<storm::dd::DdType::CUDD> two;
  25. ASSERT_NO_THROW(two = manager->getConstant(2));
  26. EXPECT_EQ(1, two.getNonZeroCount());
  27. EXPECT_EQ(1, two.getLeafCount());
  28. EXPECT_EQ(1, two.getNodeCount());
  29. EXPECT_EQ(2, two.getMin());
  30. EXPECT_EQ(2, two.getMax());
  31. }
  32. TEST(CuddDdManager, AddGetMetaVariableTest) {
  33. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  34. ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9));
  35. EXPECT_EQ(2, manager->getNumberOfMetaVariables());
  36. ASSERT_THROW(manager->addMetaVariable("x", 0, 3), storm::exceptions::InvalidArgumentException);
  37. ASSERT_NO_THROW(manager->addMetaVariable("y", 0, 3));
  38. EXPECT_EQ(4, manager->getNumberOfMetaVariables());
  39. EXPECT_TRUE(manager->hasMetaVariable("x'"));
  40. EXPECT_TRUE(manager->hasMetaVariable("y'"));
  41. std::set<std::string> metaVariableSet = {"x", "x'", "y", "y'"};
  42. EXPECT_EQ(metaVariableSet, manager->getAllMetaVariableNames());
  43. }
  44. TEST(CuddDdManager, EncodingTest) {
  45. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  46. std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
  47. storm::dd::Dd<storm::dd::DdType::CUDD> encoding;
  48. ASSERT_THROW(encoding = manager->getEncoding(x.first, 0), storm::exceptions::InvalidArgumentException);
  49. ASSERT_THROW(encoding = manager->getEncoding(x.first, 10), storm::exceptions::InvalidArgumentException);
  50. ASSERT_NO_THROW(encoding = manager->getEncoding(x.first, 4));
  51. EXPECT_EQ(1, encoding.getNonZeroCount());
  52. EXPECT_EQ(6, encoding.getNodeCount());
  53. EXPECT_EQ(2, encoding.getLeafCount());
  54. }
  55. TEST(CuddDdManager, RangeTest) {
  56. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  57. std::pair<storm::expressions::Variable, storm::expressions::Variable> x;
  58. ASSERT_NO_THROW(x = manager->addMetaVariable("x", 1, 9));
  59. storm::dd::Dd<storm::dd::DdType::CUDD> range;
  60. ASSERT_NO_THROW(range = manager->getRange(x.first));
  61. EXPECT_EQ(9, range.getNonZeroCount());
  62. EXPECT_EQ(2, range.getLeafCount());
  63. EXPECT_EQ(6, range.getNodeCount());
  64. }
  65. TEST(CuddDdManager, IdentityTest) {
  66. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  67. std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
  68. storm::dd::Dd<storm::dd::DdType::CUDD> range;
  69. ASSERT_NO_THROW(range = manager->getIdentity(x.first));
  70. EXPECT_EQ(9, range.getNonZeroCount());
  71. EXPECT_EQ(10, range.getLeafCount());
  72. EXPECT_EQ(21, range.getNodeCount());
  73. }
  74. TEST(CuddDd, OperatorTest) {
  75. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  76. std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
  77. EXPECT_TRUE(manager->getZero() == manager->getZero());
  78. EXPECT_FALSE(manager->getZero() == manager->getOne());
  79. EXPECT_FALSE(manager->getZero() != manager->getZero());
  80. EXPECT_TRUE(manager->getZero() != manager->getOne());
  81. storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getOne();
  82. storm::dd::Dd<storm::dd::DdType::CUDD> dd2 = manager->getOne();
  83. storm::dd::Dd<storm::dd::DdType::CUDD> dd3 = dd1 + dd2;
  84. EXPECT_TRUE(dd3 == manager->getConstant(2));
  85. dd3 += manager->getZero();
  86. EXPECT_TRUE(dd3 == manager->getConstant(2));
  87. dd3 = dd1 && manager->getConstant(3);
  88. EXPECT_TRUE(dd1 == manager->getOne());
  89. dd3 = dd1 * manager->getConstant(3);
  90. EXPECT_TRUE(dd3 == manager->getConstant(3));
  91. dd3 *= manager->getConstant(2);
  92. EXPECT_TRUE(dd3 == manager->getConstant(6));
  93. dd3 = dd1 - dd2;
  94. EXPECT_TRUE(dd3 == manager->getZero());
  95. dd3 -= manager->getConstant(-2);
  96. EXPECT_TRUE(dd3 == manager->getConstant(2));
  97. dd3 /= manager->getConstant(2);
  98. EXPECT_TRUE(dd3 == manager->getOne());
  99. dd3.complement();
  100. EXPECT_TRUE(dd3 == manager->getZero());
  101. dd1 = !dd3;
  102. EXPECT_TRUE(dd1 == manager->getOne());
  103. dd3 = dd1 || dd2;
  104. EXPECT_TRUE(dd3 == manager->getOne());
  105. dd1 = manager->getIdentity(x.first);
  106. dd2 = manager->getConstant(5);
  107. dd3 = dd1.equals(dd2);
  108. EXPECT_EQ(1, dd3.getNonZeroCount());
  109. storm::dd::Dd<storm::dd::DdType::CUDD> dd4 = dd1.notEquals(dd2);
  110. EXPECT_TRUE(dd4 == !dd3);
  111. dd3 = dd1.less(dd2);
  112. EXPECT_EQ(11, dd3.getNonZeroCount());
  113. dd3 = dd1.lessOrEqual(dd2);
  114. EXPECT_EQ(12, dd3.getNonZeroCount());
  115. dd3 = dd1.greater(dd2);
  116. EXPECT_EQ(4, dd3.getNonZeroCount());
  117. dd3 = dd1.greaterOrEqual(dd2);
  118. EXPECT_EQ(5, dd3.getNonZeroCount());
  119. dd3 = (manager->getEncoding(x.first, 2)).ite(dd2, dd1);
  120. dd4 = dd3.less(dd2);
  121. EXPECT_EQ(10, dd4.getNonZeroCount());
  122. dd4 = dd3.minimum(dd1);
  123. dd4 *= manager->getEncoding(x.first, 2);
  124. dd4 = dd4.sumAbstract({x.first});
  125. EXPECT_EQ(2, dd4.getValue());
  126. dd4 = dd3.maximum(dd1);
  127. dd4 *= manager->getEncoding(x.first, 2);
  128. dd4 = dd4.sumAbstract({x.first});
  129. EXPECT_EQ(5, dd4.getValue());
  130. dd1 = manager->getConstant(0.01);
  131. dd2 = manager->getConstant(0.01 + 1e-6);
  132. EXPECT_TRUE(dd1.equalModuloPrecision(dd2, 1e-6, false));
  133. EXPECT_FALSE(dd1.equalModuloPrecision(dd2, 1e-6));
  134. }
  135. TEST(CuddDd, AbstractionTest) {
  136. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  137. std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
  138. storm::dd::Dd<storm::dd::DdType::CUDD> dd1;
  139. storm::dd::Dd<storm::dd::DdType::CUDD> dd2;
  140. storm::dd::Dd<storm::dd::DdType::CUDD> dd3;
  141. dd1 = manager->getIdentity(x.first);
  142. dd2 = manager->getConstant(5);
  143. dd3 = dd1.equals(dd2);
  144. EXPECT_EQ(1, dd3.getNonZeroCount());
  145. ASSERT_THROW(dd3 = dd3.existsAbstract({x.second}), storm::exceptions::InvalidArgumentException);
  146. ASSERT_NO_THROW(dd3 = dd3.existsAbstract({x.first}));
  147. EXPECT_EQ(1, dd3.getNonZeroCount());
  148. EXPECT_EQ(1, dd3.getMax());
  149. dd3 = dd1.equals(dd2);
  150. dd3 *= manager->getConstant(3);
  151. EXPECT_EQ(1, dd3.getNonZeroCount());
  152. ASSERT_THROW(dd3 = dd3.existsAbstract({x.second}), storm::exceptions::InvalidArgumentException);
  153. ASSERT_NO_THROW(dd3 = dd3.existsAbstract({x.first}));
  154. EXPECT_TRUE(dd3 == manager->getZero());
  155. dd3 = dd1.equals(dd2);
  156. dd3 *= manager->getConstant(3);
  157. ASSERT_THROW(dd3 = dd3.sumAbstract({x.second}), storm::exceptions::InvalidArgumentException);
  158. ASSERT_NO_THROW(dd3 = dd3.sumAbstract({x.first}));
  159. EXPECT_EQ(1, dd3.getNonZeroCount());
  160. EXPECT_EQ(3, dd3.getMax());
  161. dd3 = dd1.equals(dd2);
  162. dd3 *= manager->getConstant(3);
  163. ASSERT_THROW(dd3 = dd3.minAbstract({x.second}), storm::exceptions::InvalidArgumentException);
  164. ASSERT_NO_THROW(dd3 = dd3.minAbstract({x.first}));
  165. EXPECT_EQ(0, dd3.getNonZeroCount());
  166. EXPECT_EQ(0, dd3.getMax());
  167. dd3 = dd1.equals(dd2);
  168. dd3 *= manager->getConstant(3);
  169. ASSERT_THROW(dd3 = dd3.maxAbstract({x.second}), storm::exceptions::InvalidArgumentException);
  170. ASSERT_NO_THROW(dd3 = dd3.maxAbstract({x.first}));
  171. EXPECT_EQ(1, dd3.getNonZeroCount());
  172. EXPECT_EQ(3, dd3.getMax());
  173. }
  174. TEST(CuddDd, SwapTest) {
  175. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  176. std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
  177. std::pair<storm::expressions::Variable, storm::expressions::Variable> z = manager->addMetaVariable("z", 2, 8);
  178. storm::dd::Dd<storm::dd::DdType::CUDD> dd1;
  179. storm::dd::Dd<storm::dd::DdType::CUDD> dd2;
  180. dd1 = manager->getIdentity(x.first);
  181. ASSERT_THROW(dd1.swapVariables({std::make_pair(x.first, z.first)}), storm::exceptions::InvalidArgumentException);
  182. ASSERT_NO_THROW(dd1.swapVariables({std::make_pair(x.first, x.second)}));
  183. EXPECT_TRUE(dd1 == manager->getIdentity(x.second));
  184. }
  185. TEST(CuddDd, MultiplyMatrixTest) {
  186. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  187. std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
  188. storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getIdentity(x.first).equals(manager->getIdentity(x.second));
  189. storm::dd::Dd<storm::dd::DdType::CUDD> dd2 = manager->getRange(x.second);
  190. storm::dd::Dd<storm::dd::DdType::CUDD> dd3;
  191. dd1 *= manager->getConstant(2);
  192. ASSERT_NO_THROW(dd3 = dd1.multiplyMatrix(dd2, {x.second}));
  193. ASSERT_NO_THROW(dd3.swapVariables({std::make_pair(x.first, x.second)}));
  194. EXPECT_TRUE(dd3 == dd2 * manager->getConstant(2));
  195. }
  196. TEST(CuddDd, GetSetValueTest) {
  197. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  198. std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
  199. storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getOne();
  200. ASSERT_NO_THROW(dd1.setValue(x.first, 4, 2));
  201. EXPECT_EQ(2, dd1.getLeafCount());
  202. std::map<storm::expressions::Variable, int_fast64_t> metaVariableToValueMap;
  203. metaVariableToValueMap.emplace(x.first, 1);
  204. EXPECT_EQ(1, dd1.getValue(metaVariableToValueMap));
  205. metaVariableToValueMap.clear();
  206. metaVariableToValueMap.emplace(x.first, 4);
  207. EXPECT_EQ(2, dd1.getValue(metaVariableToValueMap));
  208. }
  209. TEST(CuddDd, ForwardIteratorTest) {
  210. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  211. std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
  212. std::pair<storm::expressions::Variable, storm::expressions::Variable> y = manager->addMetaVariable("y", 0, 3);
  213. storm::dd::Dd<storm::dd::DdType::CUDD> dd;
  214. ASSERT_NO_THROW(dd = manager->getRange(x.first));
  215. storm::dd::DdForwardIterator<storm::dd::DdType::CUDD> it, ite;
  216. ASSERT_NO_THROW(it = dd.begin());
  217. ASSERT_NO_THROW(ite = dd.end());
  218. std::pair<storm::expressions::SimpleValuation, double> valuationValuePair;
  219. uint_fast64_t numberOfValuations = 0;
  220. while (it != ite) {
  221. ASSERT_NO_THROW(valuationValuePair = *it);
  222. ASSERT_NO_THROW(++it);
  223. ++numberOfValuations;
  224. }
  225. EXPECT_EQ(9, numberOfValuations);
  226. dd = manager->getRange(x.first);
  227. dd = dd.ite(manager->getOne(), manager->getOne());
  228. ASSERT_NO_THROW(it = dd.begin());
  229. ASSERT_NO_THROW(ite = dd.end());
  230. numberOfValuations = 0;
  231. while (it != ite) {
  232. ASSERT_NO_THROW(valuationValuePair = *it);
  233. ASSERT_NO_THROW(++it);
  234. ++numberOfValuations;
  235. }
  236. EXPECT_EQ(16, numberOfValuations);
  237. ASSERT_NO_THROW(it = dd.begin(false));
  238. ASSERT_NO_THROW(ite = dd.end());
  239. numberOfValuations = 0;
  240. while (it != ite) {
  241. ASSERT_NO_THROW(valuationValuePair = *it);
  242. ASSERT_NO_THROW(++it);
  243. ++numberOfValuations;
  244. }
  245. EXPECT_EQ(1, numberOfValuations);
  246. }
  247. // FIXME: make toExpression work again and then fix this test.
  248. //TEST(CuddDd, ToExpressionTest) {
  249. // std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  250. // std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
  251. //
  252. // storm::dd::Dd<storm::dd::DdType::CUDD> dd;
  253. // ASSERT_NO_THROW(dd = manager->getIdentity(x.first));
  254. //
  255. // storm::expressions::Expression ddAsExpression;
  256. // ASSERT_NO_THROW(ddAsExpression = dd.toExpression());
  257. //
  258. // storm::expressions::SimpleValuation valuation;
  259. // for (std::size_t bit = 0; bit < manager->getMetaVariable(x.first).getNumberOfDdVariables(); ++bit) {
  260. // valuation.addBooleanIdentifier("x." + std::to_string(bit));
  261. // }
  262. //
  263. // storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariable = manager->getMetaVariable("x");
  264. //
  265. // for (auto valuationValuePair : dd) {
  266. // for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
  267. // // Check if the i-th bit is set or not and modify the valuation accordingly.
  268. // if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1ull << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
  269. // valuation.setBooleanValue("x." + std::to_string(i), true);
  270. // } else {
  271. // valuation.setBooleanValue("x." + std::to_string(i), false);
  272. // }
  273. // }
  274. //
  275. // // At this point, the constructed valuation should make the expression obtained from the DD evaluate to the very
  276. // // same value as the current value obtained from the DD.
  277. // EXPECT_EQ(valuationValuePair.second, ddAsExpression.evaluateAsDouble(&valuation));
  278. // }
  279. //
  280. // storm::expressions::Expression mintermExpression = dd.getMintermExpression();
  281. //
  282. // // Check whether all minterms are covered.
  283. // for (auto valuationValuePair : dd) {
  284. // for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
  285. // // Check if the i-th bit is set or not and modify the valuation accordingly.
  286. // if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1ull << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
  287. // valuation.setBooleanValue("x." + std::to_string(i), true);
  288. // } else {
  289. // valuation.setBooleanValue("x." + std::to_string(i), false);
  290. // }
  291. // }
  292. //
  293. // // At this point, the constructed valuation should make the expression obtained from the DD evaluate to the very
  294. // // same value as the current value obtained from the DD.
  295. // EXPECT_TRUE(mintermExpression.evaluateAsBool(&valuation));
  296. // }
  297. //
  298. // // Now check no additional minterms are covered.
  299. // dd = !dd;
  300. // for (auto valuationValuePair : dd) {
  301. // for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
  302. // // Check if the i-th bit is set or not and modify the valuation accordingly.
  303. // if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1ull << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
  304. // valuation.setBooleanValue("x." + std::to_string(i), true);
  305. // } else {
  306. // valuation.setBooleanValue("x." + std::to_string(i), false);
  307. // }
  308. // }
  309. //
  310. // // At this point, the constructed valuation should make the expression obtained from the DD evaluate to the very
  311. // // same value as the current value obtained from the DD.
  312. // EXPECT_FALSE(mintermExpression.evaluateAsBool(&valuation));
  313. // }
  314. //}
  315. TEST(CuddDd, OddTest) {
  316. std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
  317. std::pair<storm::expressions::Variable, storm::expressions::Variable> a = manager->addMetaVariable("a");
  318. std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
  319. storm::dd::Dd<storm::dd::DdType::CUDD> dd = manager->getIdentity(x.first);
  320. storm::dd::Odd<storm::dd::DdType::CUDD> odd;
  321. ASSERT_NO_THROW(odd = storm::dd::Odd<storm::dd::DdType::CUDD>(dd));
  322. EXPECT_EQ(9, odd.getTotalOffset());
  323. EXPECT_EQ(12, odd.getNodeCount());
  324. std::vector<double> ddAsVector;
  325. ASSERT_NO_THROW(ddAsVector = dd.toVector<double>());
  326. EXPECT_EQ(9, ddAsVector.size());
  327. for (uint_fast64_t i = 0; i < ddAsVector.size(); ++i) {
  328. EXPECT_TRUE(i+1 == ddAsVector[i]);
  329. }
  330. // Create a non-trivial matrix.
  331. dd = manager->getIdentity(x.first).equals(manager->getIdentity(x.second)) * manager->getRange(x.first);
  332. dd += manager->getEncoding(x.first, 1) * manager->getRange(x.second) + manager->getEncoding(x.second, 1) * manager->getRange(x.first);
  333. // Create the ODDs.
  334. storm::dd::Odd<storm::dd::DdType::CUDD> rowOdd;
  335. ASSERT_NO_THROW(rowOdd = storm::dd::Odd<storm::dd::DdType::CUDD>(manager->getRange(x.first)));
  336. storm::dd::Odd<storm::dd::DdType::CUDD> columnOdd;
  337. ASSERT_NO_THROW(columnOdd = storm::dd::Odd<storm::dd::DdType::CUDD>(manager->getRange(x.second)));
  338. // Try to translate the matrix.
  339. storm::storage::SparseMatrix<double> matrix;
  340. ASSERT_NO_THROW(matrix = dd.toMatrix({x.first}, {x.second}, rowOdd, columnOdd));
  341. EXPECT_EQ(9, matrix.getRowCount());
  342. EXPECT_EQ(9, matrix.getColumnCount());
  343. EXPECT_EQ(25, matrix.getNonzeroEntryCount());
  344. dd = manager->getRange(x.first) * manager->getRange(x.second) * manager->getEncoding(a.first, 0).ite(dd, dd + manager->getConstant(1));
  345. ASSERT_NO_THROW(matrix = dd.toMatrix({x.first}, {x.second}, {a.first}, rowOdd, columnOdd));
  346. EXPECT_EQ(18, matrix.getRowCount());
  347. EXPECT_EQ(9, matrix.getRowGroupCount());
  348. EXPECT_EQ(9, matrix.getColumnCount());
  349. EXPECT_EQ(106, matrix.getNonzeroEntryCount());
  350. }