RowEchelonFormTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <?php
  2. namespace MathPHP\Tests\LinearAlgebra\Reduction;
  3. use MathPHP\LinearAlgebra\MatrixFactory;
  4. use MathPHP\LinearAlgebra\NumericMatrix;
  5. use MathPHP\LinearAlgebra\Reduction;
  6. use MathPHP\Tests;
  7. class RowEchelonFormTest extends \PHPUnit\Framework\TestCase
  8. {
  9. use Tests\LinearAlgebra\Fixture\MatrixDataProvider;
  10. /**
  11. * @test isRef on ref matrix should return true
  12. * @dataProvider dataProviderForNonsingularMatrix
  13. * @param $A
  14. * @throws \Exception
  15. */
  16. public function testRefIsRef(array $A)
  17. {
  18. // Given
  19. $A = MatrixFactory::create($A);
  20. // When
  21. $ref = $A->ref();
  22. // Then
  23. $this->assertTrue($ref->isRef());
  24. }
  25. /**
  26. * @test ref lazy load is the same as the computed and returned value.
  27. * @throws \Exception
  28. */
  29. public function testRefAlreadyComputed()
  30. {
  31. // Given
  32. $A = new NumericMatrix([
  33. [ 4, 1, 2, -3],
  34. [-3, 3, -1, 4],
  35. [-1, 2, 5, 1],
  36. [ 5, 4, 3, -1],
  37. ]);
  38. // When
  39. $ref1 = $A->ref(); // computes ref
  40. $ref2 = $A->ref(); // simply gets already-computed ref
  41. // Then
  42. $this->assertEquals($ref1, $ref2);
  43. }
  44. /**
  45. * @test rowReductionToEchelonForm method of ref
  46. * @dataProvider dataProviderForRowReductionToEchelonForm
  47. * @param array $A
  48. * @param array $R
  49. * @throws \Exception
  50. */
  51. public function testRowReductionToEchelonForm(array $A, array $R)
  52. {
  53. // Given
  54. $A = MatrixFactory::create($A);
  55. $R = MatrixFactory::create($R);
  56. // When
  57. [$ref, $swaps] = Reduction\RowEchelonForm::rowReductionToEchelonForm($A);
  58. $ref = MatrixFactory::create($ref);
  59. // Then
  60. $this->assertEqualsWithDelta($R->getMatrix(), $ref->getMatrix(), 0.000001);
  61. $this->assertTrue($ref->isRef());
  62. }
  63. /**
  64. * @return array
  65. */
  66. public function dataProviderForRowReductionToEchelonForm(): array
  67. {
  68. return [
  69. [
  70. [
  71. [1, 2, 0],
  72. [-1, 1, 1],
  73. [1, 2, 3],
  74. ],
  75. [
  76. [1, 2, 0],
  77. [0, 1, 1 / 3],
  78. [0, 0, 1],
  79. ],
  80. ],
  81. [
  82. [
  83. [0, 2, 0],
  84. [-1, 1, 1],
  85. [1, 2, 3],
  86. ],
  87. [
  88. [1, -1, -1],
  89. [0, 1, 0],
  90. [0, 0, 1],
  91. ],
  92. ],
  93. [
  94. [
  95. [0, 2, 0],
  96. [0, 1, 1],
  97. [1, 2, 3],
  98. ],
  99. [
  100. [1, 2, 3],
  101. [0, 1, 1],
  102. [0, 0, 1],
  103. ],
  104. ],
  105. [
  106. [
  107. [1, 2, 0],
  108. [0, 1, 1],
  109. [0, 2, 3],
  110. ],
  111. [
  112. [1, 2, 0],
  113. [0, 1, 1],
  114. [0, 0, 1],
  115. ],
  116. ],
  117. [
  118. [
  119. [2, 5, 4],
  120. [2, 4, 6],
  121. [8, 7, 5],
  122. [6, 4, 5],
  123. [6, 2, 3],
  124. ],
  125. [
  126. [1, 5 / 2, 2],
  127. [0, 1, -2],
  128. [0, 0, 1],
  129. [0, 0, 0],
  130. [0, 0, 0],
  131. ],
  132. ],
  133. [
  134. [
  135. [1, 0, -2, 1, 0],
  136. [0, -1, -3, 1, 3],
  137. [-2, -1, 1, -1, 3],
  138. [0, 3, 9, 0, -12],
  139. ],
  140. [
  141. [1, 0, -2, 1, 0],
  142. [0, 1, 3, -1, -3],
  143. [0, 0, 0, 1, -1],
  144. [0, 0, 0, 0, 0],
  145. ],
  146. ],
  147. [
  148. [
  149. [5, 4, 8],
  150. [7, 7, 5],
  151. [6, 2, 4],
  152. ],
  153. [
  154. [1, 4 / 5, 8 / 5],
  155. [0, 1, -31 / 7],
  156. [0, 0, 1],
  157. ],
  158. ],
  159. [
  160. [
  161. [2, 0, -1, 0, 0],
  162. [1, 0, 0, -1, 0],
  163. [3, 0, 0, -2, -1],
  164. [0, 1, 0, 0, -2],
  165. [0, 1, -1, 0, 0]
  166. ],
  167. [
  168. [1, 0, -1 / 2, 0, 0],
  169. [0, 1, 0, 0, -2],
  170. [0, 0, 1, -4 / 3, -2 / 3],
  171. [0, 0, 0, 1, -1],
  172. [0, 0, 0, 0, 0],
  173. ],
  174. ],
  175. [
  176. [
  177. [2, -1, 4, 3, 2, 3, 4, 4],
  178. [-1, 2, 3, 2, 1, 2, 3, 3],
  179. [4, 3, 2, 1, 2, 3, 4, 4],
  180. [2, 1, 2, 1, 2, 1, 2, 2],
  181. [3, 2, 3, 2, 1, 2, 3, 3],
  182. [3, 2, 3, 2, 1, 2, 1, 2],
  183. [4, 3, 4, 3, 2, 1, 2, 2],
  184. [4, 3, 4, 3, 2, 2, 2, 2],
  185. ],
  186. [
  187. [1, -1 / 2, 2, 3 / 2, 1, 3 / 2, 2, 2],
  188. [0, 1, 10 / 3, 7 / 3, 4 / 3, 7 / 3, 10 / 3, 10 / 3],
  189. [0, 0, 1, 25 / 34, 13 / 34, 11 / 17, 31 / 34, 31 / 34],
  190. [0, 0, 0, 1, -11 / 5, 18 / 5, 13 / 5, 13 / 5],
  191. [0, 0, 0, 0, 1, 2, 2, 2],
  192. [0, 0, 0, 0, 0, 1, 1, 1],
  193. [0, 0, 0, 0, 0, 0, 1, 1 / 2],
  194. [0, 0, 0, 0, 0, 0, 0, 1],
  195. ],
  196. ],
  197. [
  198. [
  199. [0]
  200. ],
  201. [
  202. [0],
  203. ],
  204. ],
  205. [
  206. [
  207. [1]
  208. ],
  209. [
  210. [1],
  211. ],
  212. ],
  213. [
  214. [
  215. [5]
  216. ],
  217. [
  218. [1],
  219. ],
  220. ],
  221. [
  222. [
  223. [0, 0],
  224. [0, 0]
  225. ],
  226. [
  227. [0, 0],
  228. [0, 0],
  229. ],
  230. ],
  231. [
  232. [
  233. [0, 0],
  234. [0, 1]
  235. ],
  236. [
  237. [0, 1],
  238. [0, 0],
  239. ],
  240. ],
  241. [
  242. [
  243. [1, 0],
  244. [0, 0]
  245. ],
  246. [
  247. [1, 0],
  248. [0, 0],
  249. ],
  250. ],
  251. [
  252. [
  253. [0, 0],
  254. [1, 0]
  255. ],
  256. [
  257. [1, 0],
  258. [0, 0],
  259. ],
  260. ],
  261. [
  262. [
  263. [0, 0],
  264. [1, 1]
  265. ],
  266. [
  267. [1, 1],
  268. [0, 0],
  269. ],
  270. ],
  271. [
  272. [
  273. [0, 1],
  274. [0, 1]
  275. ],
  276. [
  277. [0, 1],
  278. [0, 0],
  279. ],
  280. ],
  281. [
  282. [
  283. [1, 0],
  284. [1, 0]
  285. ],
  286. [
  287. [1, 0],
  288. [0, 0],
  289. ],
  290. ],
  291. [
  292. [
  293. [1, 1],
  294. [1, 1]
  295. ],
  296. [
  297. [1, 1],
  298. [0, 0],
  299. ],
  300. ],
  301. [
  302. [
  303. [2, 6],
  304. [1, 3]
  305. ],
  306. [
  307. [1, 3],
  308. [0, 0],
  309. ],
  310. ],
  311. [
  312. [
  313. [3, 6],
  314. [1, 2]
  315. ],
  316. [
  317. [1, 2],
  318. [0, 0],
  319. ],
  320. ],
  321. [
  322. [
  323. [1, 2],
  324. [1, 2]
  325. ],
  326. [
  327. [1, 2],
  328. [0, 0],
  329. ],
  330. ],
  331. [
  332. [
  333. [1, 2, 3],
  334. [2, 3, 4],
  335. [3, 4, 5],
  336. ],
  337. [
  338. [1, 2, 3],
  339. [0, 1, 2],
  340. [0, 0, 0],
  341. ],
  342. ],
  343. [
  344. [
  345. [1, 2, 1],
  346. [-2, -3, 1],
  347. [3, 5, 0],
  348. ],
  349. [
  350. [1, 2, 1],
  351. [0, 1, 3],
  352. [0, 0, 0],
  353. ],
  354. ],
  355. [
  356. [
  357. [1, -1, 2],
  358. [2, 1, 1],
  359. [1, 1, 0],
  360. ],
  361. [
  362. [1, -1, 2],
  363. [0, 1, -1],
  364. [0, 0, 0],
  365. ],
  366. ],
  367. [
  368. [
  369. [1, 0, 1],
  370. [0, 1, -1],
  371. [0, 0, 0],
  372. ],
  373. [
  374. [1, 0, 1],
  375. [0, 1, -1],
  376. [0, 0, 0],
  377. ],
  378. ],
  379. [
  380. [
  381. [1, 2, 3],
  382. [1, 3, 1],
  383. [3, 4, 7],
  384. ],
  385. [
  386. [1, 2, 3],
  387. [0, 1, -2],
  388. [0, 0, 1],
  389. ],
  390. ],
  391. [
  392. [
  393. [1, 0, 0],
  394. [-2, 0, 0],
  395. [4, 6, 1],
  396. ],
  397. [
  398. [1, 0, 0],
  399. [0, 1, 1 / 6],
  400. [0, 0, 0],
  401. ],
  402. ],
  403. [
  404. [
  405. [1, 1, 4, 1, 2],
  406. [0, 1, 2, 1, 1],
  407. [0, 0, 0, 1, 2],
  408. [1, -1, 0, 0, 2],
  409. [2, 1, 6, 0, 1],
  410. ],
  411. [
  412. [1, 1, 4, 1, 2],
  413. [0, 1, 2, 1, 1],
  414. [0, 0, 0, 1, 2],
  415. [0, 0, 0, 0, 0],
  416. [0, 0, 0, 0, 0],
  417. ],
  418. ],
  419. // This is an interesting case because of the minuscule values that are for all intents and purposes zero.
  420. // If the minuscule zero-like values are not handled properly, the zero value will be used as a pivot,
  421. // instead of being interchanged with a non-zero row.
  422. [
  423. [
  424. [0, 1, 4, 2, 3, 3, 4, 4],
  425. [1, 0, 3, 1, 2, 2, 3, 3],
  426. [4, 3, 0, 2, 3, 3, 4, 4],
  427. [3, 2, 1, 1, 2, 2, 3, 3],
  428. [2, 1, 2, 0, 1, 1, 2, 2],
  429. [3, 2, 3, 1, 2, 0, 1, 2],
  430. [4, 3, 4, 2, 3, 1, 0, 2],
  431. [4, 3, 4, 2, 3, 2, 2, 0],
  432. ],
  433. [
  434. [1, 0, 3, 1, 2, 2, 3, 3],
  435. [0, 1, 4, 2, 3, 3, 4, 4],
  436. [0, 0, 1, 1 / 3, 7 / 12, 7 / 12, 5 / 6, 5 / 6],
  437. [0, 0, 0, 1, 1, 1, 1, 1],
  438. [0, 0, 0, 0, 1, 5, 6, 4],
  439. [0, 0, 0, 0, 0, 1, 0, 0],
  440. [0, 0, 0, 0, 0, 0, 1, -1],
  441. [0, 0, 0, 0, 0, 0, 0, 0],
  442. ],
  443. ],
  444. ];
  445. }
  446. }