MatrixAugmentationTest.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. <?php
  2. namespace MathPHP\Tests\LinearAlgebra\Matrix;
  3. use MathPHP\Expression\Polynomial;
  4. use MathPHP\LinearAlgebra\MatrixFactory;
  5. use MathPHP\LinearAlgebra\NumericMatrix;
  6. use MathPHP\Exception;
  7. class MatrixAugmentationTest extends \PHPUnit\Framework\TestCase
  8. {
  9. /** @var array */
  10. private $A;
  11. /** @var NumericMatrix */
  12. private $matrix;
  13. /**
  14. * @throws \Exception
  15. */
  16. public function setUp(): void
  17. {
  18. $this->A = [
  19. [1, 2, 3],
  20. [2, 3, 4],
  21. [4, 5, 6],
  22. ];
  23. $this->matrix = MatrixFactory::create($this->A);
  24. }
  25. /**
  26. * @test augment
  27. * @dataProvider dataProviderForAugment
  28. * @param array $A
  29. * @param array $B
  30. * @param array $⟮A∣B⟯
  31. * @throws \Exception
  32. */
  33. public function testAugment(array $A, array $B, array $⟮A∣B⟯)
  34. {
  35. // Given
  36. $A = MatrixFactory::create($A);
  37. $B = MatrixFactory::create($B);
  38. $⟮A∣B⟯ = MatrixFactory::create($⟮A∣B⟯);
  39. // When
  40. $augmented = $A->augment($B);
  41. // Then
  42. $this->assertEquals($⟮A∣B⟯, $augmented);
  43. }
  44. /**
  45. * @return array
  46. */
  47. public function dataProviderForAugment(): array
  48. {
  49. return [
  50. [
  51. [
  52. [1, 2, 3],
  53. [2, 3, 4],
  54. [3, 4, 5],
  55. ],
  56. [
  57. [4],
  58. [5],
  59. [6],
  60. ],
  61. [
  62. [1, 2, 3, 4],
  63. [2, 3, 4, 5],
  64. [3, 4, 5, 6],
  65. ]
  66. ],
  67. [
  68. [
  69. [1, 2, 3],
  70. [2, 3, 4],
  71. [3, 4, 5],
  72. ],
  73. [
  74. [4, 7, 8],
  75. [5, 7, 8],
  76. [6, 7, 8],
  77. ],
  78. [
  79. [1, 2, 3, 4, 7, 8],
  80. [2, 3, 4, 5, 7, 8],
  81. [3, 4, 5, 6, 7, 8],
  82. ]
  83. ],
  84. [
  85. [
  86. [1, 2, 3],
  87. ],
  88. [
  89. [4],
  90. ],
  91. [
  92. [1, 2, 3, 4],
  93. ]
  94. ],
  95. [
  96. [
  97. [1],
  98. ],
  99. [
  100. [4],
  101. ],
  102. [
  103. [1, 4],
  104. ]
  105. ],
  106. [
  107. [
  108. [1, 2, 3],
  109. [2, 3, 4],
  110. [3, 4, 5],
  111. ],
  112. [
  113. [4, 7, 8, 9],
  114. [5, 7, 8, 9],
  115. [6, 7, 8, 9],
  116. ],
  117. [
  118. [1, 2, 3, 4, 7, 8, 9],
  119. [2, 3, 4, 5, 7, 8, 9],
  120. [3, 4, 5, 6, 7, 8, 9],
  121. ]
  122. ],
  123. ];
  124. }
  125. /**
  126. * @test augment matrix with matrix that does not match dimensions
  127. * @throws \Exception
  128. */
  129. public function testAugmentExceptionRowsDoNotMatch()
  130. {
  131. // Given
  132. $A = MatrixFactory::create([
  133. [1, 2, 3],
  134. [2, 3, 4],
  135. [3, 4, 5],
  136. ]);
  137. $B = MatrixFactory::create([
  138. [4, 5],
  139. [5, 6],
  140. ]);
  141. // Then
  142. $this->expectException(Exception\MatrixException::class);
  143. // When
  144. $A->augment($B);
  145. }
  146. /**
  147. * @test Augment with identity
  148. * @dataProvider dataProviderForAugmentIdentity
  149. * @throws \Exception
  150. */
  151. public function testAugmentIdentity(array $C, array $⟮C∣I⟯)
  152. {
  153. // Given
  154. $C = MatrixFactory::create($C);
  155. $⟮C∣I⟯ = MatrixFactory::create($⟮C∣I⟯);
  156. // Then
  157. $this->assertEquals($⟮C∣I⟯, $C->augmentIdentity());
  158. }
  159. public function dataProviderForAugmentIdentity(): array
  160. {
  161. return [
  162. [
  163. [
  164. [1, 2, 3],
  165. [2, 3, 4],
  166. [3, 4, 5],
  167. ],
  168. [
  169. [1, 2, 3, 1, 0, 0],
  170. [2, 3, 4, 0, 1, 0],
  171. [3, 4, 5, 0, 0, 1],
  172. ]
  173. ],
  174. [
  175. [
  176. [1, 2],
  177. [2, 3],
  178. ],
  179. [
  180. [1, 2, 1, 0],
  181. [2, 3, 0, 1],
  182. ]
  183. ],
  184. [
  185. [
  186. [1]
  187. ],
  188. [
  189. [1, 1],
  190. ]
  191. ],
  192. ];
  193. }
  194. /**
  195. * @test Augment with identity exception when not square
  196. * @throws \Exception
  197. */
  198. public function testAugmentIdentityExceptionNotSquare()
  199. {
  200. // Given
  201. $A = MatrixFactory::create([
  202. [1, 2],
  203. [2, 3],
  204. [3, 4],
  205. ]);
  206. // Then
  207. $this->expectException(Exception\MatrixException::class);
  208. // When
  209. $A->augmentIdentity();
  210. }
  211. /**
  212. * @test augmentBelow
  213. * @dataProvider dataProviderForAugmentBelow
  214. * @param array $A
  215. * @param array $B
  216. * @param array $⟮A∣B⟯
  217. * @throws \Exception
  218. */
  219. public function testAugmentBelow(array $A, array $B, array $⟮A∣B⟯)
  220. {
  221. // Given
  222. $A = MatrixFactory::create($A);
  223. $B = MatrixFactory::create($B);
  224. $⟮A∣B⟯ = MatrixFactory::create($⟮A∣B⟯);
  225. // When
  226. $augmented = $A->augmentBelow($B);
  227. // Then
  228. $this->assertEquals($⟮A∣B⟯, $augmented);
  229. }
  230. /**
  231. * @return array
  232. */
  233. public function dataProviderForAugmentBelow(): array
  234. {
  235. return [
  236. [
  237. [
  238. [1],
  239. ],
  240. [
  241. [2],
  242. ],
  243. [
  244. [1],
  245. [2],
  246. ],
  247. ],
  248. [
  249. [
  250. [1],
  251. [2],
  252. ],
  253. [
  254. [3],
  255. ],
  256. [
  257. [1],
  258. [2],
  259. [3],
  260. ],
  261. ],
  262. [
  263. [
  264. [1, 2],
  265. [2, 3],
  266. ],
  267. [
  268. [3, 4],
  269. ],
  270. [
  271. [1, 2],
  272. [2, 3],
  273. [3, 4],
  274. ],
  275. ],
  276. [
  277. [
  278. [1, 2, 3],
  279. [2, 3, 4],
  280. ],
  281. [
  282. [3, 4, 5],
  283. ],
  284. [
  285. [1, 2, 3],
  286. [2, 3, 4],
  287. [3, 4, 5],
  288. ],
  289. ],
  290. [
  291. [
  292. [1, 2, 3],
  293. [2, 3, 4],
  294. ],
  295. [
  296. [3, 4, 5],
  297. [4, 5, 6]
  298. ],
  299. [
  300. [1, 2, 3],
  301. [2, 3, 4],
  302. [3, 4, 5],
  303. [4, 5, 6],
  304. ],
  305. ],
  306. ];
  307. }
  308. /**
  309. * @test It is an error to augment a matrix from below if the column count does not match
  310. * @throws \Exception
  311. */
  312. public function testAugmentBelowExceptionColumnsDoNotMatch()
  313. {
  314. // Given
  315. $A = MatrixFactory::create([
  316. [1, 2, 3],
  317. [2, 3, 4],
  318. [3, 4, 5],
  319. ]);
  320. $B = MatrixFactory::create([
  321. [4, 5],
  322. [5, 6],
  323. ]);
  324. // Then
  325. $this->expectException(Exception\MatrixException::class);
  326. // When
  327. $A->augmentBelow($B);
  328. }
  329. /**
  330. * @test augmentAbove
  331. * @dataProvider dataProviderForAugmentAbove
  332. * @param array $A
  333. * @param array $B
  334. * @param array $⟮A∣B⟯
  335. * @throws \Exception
  336. */
  337. public function testAugmentAbove(array $A, array $B, array $⟮A∣B⟯)
  338. {
  339. // Given
  340. $A = MatrixFactory::create($A);
  341. $B = MatrixFactory::create($B);
  342. $⟮A∣B⟯ = MatrixFactory::create($⟮A∣B⟯);
  343. // When
  344. $augmented = $A->augmentAbove($B);
  345. // Then
  346. $this->assertEquals($⟮A∣B⟯, $augmented);
  347. }
  348. /**
  349. * @return array
  350. */
  351. public function dataProviderForAugmentAbove(): array
  352. {
  353. return [
  354. [
  355. [
  356. [1],
  357. ],
  358. [
  359. [2],
  360. ],
  361. [
  362. [2],
  363. [1],
  364. ],
  365. ],
  366. [
  367. [
  368. [1],
  369. [2],
  370. ],
  371. [
  372. [3],
  373. ],
  374. [
  375. [3],
  376. [1],
  377. [2],
  378. ],
  379. ],
  380. [
  381. [
  382. [1, 2],
  383. [2, 3],
  384. ],
  385. [
  386. [3, 4],
  387. ],
  388. [
  389. [3, 4],
  390. [1, 2],
  391. [2, 3],
  392. ],
  393. ],
  394. [
  395. [
  396. [1, 2, 3],
  397. [2, 3, 4],
  398. ],
  399. [
  400. [3, 4, 5],
  401. ],
  402. [
  403. [3, 4, 5],
  404. [1, 2, 3],
  405. [2, 3, 4],
  406. ],
  407. ],
  408. [
  409. [
  410. [1, 2, 3],
  411. [2, 3, 4],
  412. ],
  413. [
  414. [3, 4, 5],
  415. [4, 5, 6]
  416. ],
  417. [
  418. [3, 4, 5],
  419. [4, 5, 6],
  420. [1, 2, 3],
  421. [2, 3, 4],
  422. ],
  423. ],
  424. ];
  425. }
  426. /**
  427. * @test It is an error to augment a matrix from above if the column count does not match
  428. * @throws \Exception
  429. */
  430. public function testAugmentAboveExceptionColumnsDoNotMatch()
  431. {
  432. // Given
  433. $A = MatrixFactory::create([
  434. [1, 2, 3],
  435. [2, 3, 4],
  436. [3, 4, 5],
  437. ]);
  438. $B = MatrixFactory::create([
  439. [4, 5],
  440. [5, 6],
  441. ]);
  442. // Then
  443. $this->expectException(Exception\MatrixException::class);
  444. // When
  445. $A->augmentAbove($B);
  446. }
  447. /**
  448. * @test augmentLeft
  449. * @dataProvider dataProviderForAugmentLeft
  450. * @param array $A
  451. * @param array $B
  452. * @param array $⟮B∣A⟯
  453. * @throws \Exception
  454. */
  455. public function testAugmentLeft(array $A, array $B, array $⟮B∣A⟯)
  456. {
  457. // Given
  458. $A = MatrixFactory::create($A);
  459. $B = MatrixFactory::create($B);
  460. $⟮B∣A⟯ = MatrixFactory::create($⟮B∣A⟯);
  461. // When
  462. $augmented = $A->augmentLeft($B);
  463. // Then
  464. $this->assertEquals($⟮B∣A⟯, $augmented);
  465. }
  466. /**
  467. * @return array
  468. */
  469. public function dataProviderForAugmentLeft(): array
  470. {
  471. return [
  472. [
  473. [
  474. [1, 2, 3],
  475. [2, 3, 4],
  476. [3, 4, 5],
  477. ],
  478. [
  479. [4],
  480. [5],
  481. [6],
  482. ],
  483. [
  484. [4, 1, 2, 3],
  485. [5, 2, 3, 4],
  486. [6, 3, 4, 5],
  487. ]
  488. ],
  489. [
  490. [
  491. [1, 2, 3],
  492. [2, 3, 4],
  493. [3, 4, 5],
  494. ],
  495. [
  496. [4, 7, 8],
  497. [5, 7, 8],
  498. [6, 7, 8],
  499. ],
  500. [
  501. [4, 7, 8, 1, 2, 3],
  502. [5, 7, 8, 2, 3, 4],
  503. [6, 7, 8, 3, 4, 5],
  504. ]
  505. ],
  506. [
  507. [
  508. [1, 2, 3],
  509. ],
  510. [
  511. [4],
  512. ],
  513. [
  514. [4, 1, 2, 3],
  515. ]
  516. ],
  517. [
  518. [
  519. [1],
  520. ],
  521. [
  522. [4],
  523. ],
  524. [
  525. [4, 1],
  526. ]
  527. ],
  528. [
  529. [
  530. [1, 2, 3],
  531. [2, 3, 4],
  532. [3, 4, 5],
  533. ],
  534. [
  535. [4, 7, 8, 9],
  536. [5, 7, 8, 9],
  537. [6, 7, 8, 9],
  538. ],
  539. [
  540. [4, 7, 8, 9, 1, 2, 3],
  541. [5, 7, 8, 9, 2, 3, 4],
  542. [6, 7, 8, 9, 3, 4, 5],
  543. ]
  544. ],
  545. ];
  546. }
  547. /**
  548. * @test augmentLeft matrix with matrix that does not match dimensions
  549. * @throws \Exception
  550. */
  551. public function testAugmentLeftExceptionRowsDoNotMatch()
  552. {
  553. $A = MatrixFactory::create([
  554. [1, 2, 3],
  555. [2, 3, 4],
  556. [3, 4, 5],
  557. ]);
  558. $B = MatrixFactory::create([
  559. [4, 5],
  560. [5, 6],
  561. ]);
  562. $this->expectException(Exception\MatrixException::class);
  563. $A->augmentLeft($B);
  564. }
  565. /**
  566. * @test augment
  567. * @throws \Exception
  568. */
  569. public function testAugmentExceptionTypeMismatch()
  570. {
  571. // Given
  572. $A = MatrixFactory::create([[1]]);
  573. $B = MatrixFactory::create([[new Polynomial([1,1])]]);
  574. // Then
  575. $this->expectException(Exception\MatrixException::class);
  576. // When
  577. $augmented = $A->augment($B);
  578. }
  579. /**
  580. * @test augmentLeft
  581. * @throws \Exception
  582. */
  583. public function testAugmentLeftExceptionTypeMismatch()
  584. {
  585. // Given
  586. $A = MatrixFactory::create([[1]]);
  587. $B = MatrixFactory::create([[new Polynomial([1,1])]]);
  588. // Then
  589. $this->expectException(Exception\MatrixException::class);
  590. // When
  591. $augmented = $A->augmentLeft($B);
  592. }
  593. /**
  594. * @test augmentAbove
  595. * @throws \Exception
  596. */
  597. public function testAugmentAboveExceptionTypeMismatch()
  598. {
  599. // Given
  600. $A = MatrixFactory::create([[1]]);
  601. $B = MatrixFactory::create([[new Polynomial([1,1])]]);
  602. // Then
  603. $this->expectException(Exception\MatrixException::class);
  604. // When
  605. $augmented = $A->augmentAbove($B);
  606. }
  607. /**
  608. * @test augmentBelow
  609. * @throws \Exception
  610. */
  611. public function testAugmentBelowExceptionTypeMismatch()
  612. {
  613. // Given
  614. $A = MatrixFactory::create([[1]]);
  615. $B = MatrixFactory::create([[new Polynomial([1,1])]]);
  616. // Then
  617. $this->expectException(Exception\MatrixException::class);
  618. // When
  619. $augmented = $A->augmentBelow($B);
  620. }
  621. }