MatrixArithmeticOperationsTest.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395
  1. <?php
  2. namespace MathPHP\Tests\LinearAlgebra\MatrixNumeric;
  3. use MathPHP\LinearAlgebra\MatrixFactory;
  4. use MathPHP\LinearAlgebra\NumericMatrix;
  5. use MathPHP\LinearAlgebra\NumericSquareMatrix;
  6. use MathPHP\LinearAlgebra\Vector;
  7. use MathPHP\Exception;
  8. class MatrixArithmeticOperationsTest extends \PHPUnit\Framework\TestCase
  9. {
  10. /**
  11. * @test add
  12. * @dataProvider dataProviderForAdd
  13. */
  14. public function testAdd(array $A, array $B, array $R)
  15. {
  16. // Given
  17. $A = MatrixFactory::create($A);
  18. $B = MatrixFactory::create($B);
  19. $R = MatrixFactory::create($R);
  20. // When
  21. $R2 = $A->add($B);
  22. // Then
  23. $this->assertEquals($R, $R2);
  24. }
  25. public function dataProviderForAdd(): array
  26. {
  27. return [
  28. [
  29. [
  30. [1, 2, 3],
  31. [2, 3, 4],
  32. [3, 4, 5],
  33. ],
  34. [
  35. [1, 1, 1],
  36. [1, 1, 1],
  37. [1, 1, 1],
  38. ],
  39. [
  40. [2, 3, 4],
  41. [3, 4, 5],
  42. [4, 5, 6],
  43. ],
  44. ],
  45. [
  46. [
  47. [0, 1, 2],
  48. [9, 8, 7],
  49. ],
  50. [
  51. [6, 5, 4],
  52. [3, 4, 5],
  53. ],
  54. [
  55. [ 6, 6, 6],
  56. [12, 12, 12],
  57. ],
  58. ],
  59. ];
  60. }
  61. /**
  62. * @test add exception for rows
  63. * @throws \Exception
  64. */
  65. public function testAddExceptionRows()
  66. {
  67. // Given
  68. $A = MatrixFactory::create([
  69. [1, 2],
  70. [2, 3],
  71. ]);
  72. $B = MatrixFactory::create([
  73. [1, 2]
  74. ]);
  75. // Then
  76. $this->expectException(Exception\MatrixException::class);
  77. // WHen
  78. $A->add($B);
  79. }
  80. /**
  81. * @test add exception for columns
  82. * @throws \Exception
  83. */
  84. public function testAddExceptionColumns()
  85. {
  86. // Given
  87. $A = MatrixFactory::create([
  88. [1, 2, 3],
  89. [2, 3, 4],
  90. ]);
  91. $B = MatrixFactory::create([
  92. [1, 2],
  93. [2, 3],
  94. ]);
  95. // Then
  96. $this->expectException(Exception\MatrixException::class);
  97. // When
  98. $A->add($B);
  99. }
  100. /**
  101. * @test directSum
  102. * @dataProvider dataProviderForDirectSum
  103. */
  104. public function testDirectSum(array $A, array $B, array $R)
  105. {
  106. // Given
  107. $A = MatrixFactory::create($A);
  108. $B = MatrixFactory::create($B);
  109. $R = MatrixFactory::create($R);
  110. // When
  111. $R2 = $A->directSum($B);
  112. // Then
  113. $this->assertEquals($R, $R2);
  114. }
  115. public function dataProviderForDirectSum(): array
  116. {
  117. return [
  118. [
  119. [
  120. [1, 3, 2],
  121. [2, 3, 1],
  122. ],
  123. [
  124. [1, 6],
  125. [0, 1],
  126. ],
  127. [
  128. [1, 3, 2, 0, 0],
  129. [2, 3, 1, 0, 0],
  130. [0, 0, 0, 1, 6],
  131. [0, 0, 0, 0, 1],
  132. ],
  133. ],
  134. ];
  135. }
  136. /**
  137. * @test kroneckerSum returns the expected SquareMatrix
  138. * @dataProvider dataProviderKroneckerSum
  139. * @param array A
  140. * @param array B
  141. * @param array $expected
  142. */
  143. public function testKroneckerSum(array $A, array $B, array $expected)
  144. {
  145. // Given
  146. $A = new NumericSquareMatrix($A);
  147. $B = new NumericSquareMatrix($B);
  148. $R = new NumericSquareMatrix($expected);
  149. // When
  150. $A⊕B = $A->kroneckerSum($B);
  151. // Then
  152. $this->assertEquals($R, $A⊕B);
  153. $this->assertEquals($R->getMatrix(), $A⊕B->getMatrix());
  154. $this->assertInstanceOf(NumericSquareMatrix::class, $A⊕B);
  155. }
  156. public function dataProviderKroneckerSum(): array
  157. {
  158. return [
  159. [
  160. [
  161. [1, 2],
  162. [3, 4],
  163. ],
  164. [
  165. [1, 2, 3],
  166. [4, 5, 6],
  167. [7, 8, 9],
  168. ],
  169. [
  170. [2, 2, 3, 2, 0, 0],
  171. [4, 6, 6, 0, 2, 0],
  172. [7, 8,10, 0, 0, 2],
  173. [3, 0, 0, 5, 2, 3],
  174. [0, 3, 0, 4, 9, 6],
  175. [0, 0, 3, 7, 8,13],
  176. ],
  177. ],
  178. [
  179. [
  180. [1, 1],
  181. [1, 1],
  182. ],
  183. [
  184. [1, 1],
  185. [1, 1],
  186. ],
  187. [
  188. [2, 1, 1, 0],
  189. [1, 2, 0, 1],
  190. [1, 0, 2, 1],
  191. [0, 1, 1, 2],
  192. ],
  193. ],
  194. [
  195. [
  196. [1, 1],
  197. [1, 1],
  198. ],
  199. [
  200. [2, 3],
  201. [4, 5],
  202. ],
  203. [
  204. [3, 3, 1, 0],
  205. [4, 6, 0, 1],
  206. [1, 0, 3, 3],
  207. [0, 1, 4, 6],
  208. ],
  209. ],
  210. [
  211. [
  212. [2, 3],
  213. [4, 5],
  214. ],
  215. [
  216. [1, 1],
  217. [1, 1],
  218. ],
  219. [
  220. [3, 1, 3, 0],
  221. [1, 3, 0, 3],
  222. [4, 0, 6, 1],
  223. [0, 4, 1, 6],
  224. ],
  225. ],
  226. ];
  227. }
  228. /**
  229. * @test kronecerSum throws a MatrixException if one of the matrices is not square
  230. * @dataProvider dataProviderForKroneckerSumSquareMatrixException
  231. * @param array A
  232. * @param array B
  233. */
  234. public function testKroneckerSumSquareMatrixException($A, $B)
  235. {
  236. // Given
  237. $A = new NumericMatrix($A);
  238. $B = new NumericMatrix($B);
  239. // Then
  240. $this->expectException(Exception\MatrixException::class);
  241. // When
  242. $A⊕B = $A->kroneckerSum($B);
  243. }
  244. public function dataProviderForKroneckerSumSquareMatrixException(): array
  245. {
  246. return [
  247. [
  248. [
  249. [1, 2, 3],
  250. [2, 3, 4],
  251. ],
  252. [
  253. [1, 2],
  254. [2, 3],
  255. ]
  256. ],
  257. [
  258. [
  259. [1, 2],
  260. [2, 3],
  261. ],
  262. [
  263. [1, 2, 3],
  264. [2, 3, 4],
  265. ],
  266. ],
  267. [
  268. [
  269. [1, 2],
  270. [2, 3],
  271. [4, 5],
  272. ],
  273. [
  274. [1, 2, 3],
  275. [2, 3, 4],
  276. ],
  277. ],
  278. ];
  279. }
  280. /**
  281. * @test subtract
  282. * @dataProvider dataProviderForSubtract
  283. */
  284. public function testSubtract(array $A, array $B, array $R)
  285. {
  286. // Given
  287. $A = MatrixFactory::create($A);
  288. $B = MatrixFactory::create($B);
  289. $R = MatrixFactory::create($R);
  290. // When
  291. $R2 = $A->subtract($B);
  292. // Then
  293. $this->assertEquals($R, $R2);
  294. }
  295. public function dataProviderForSubtract(): array
  296. {
  297. return [
  298. [
  299. [
  300. [1, 2, 3],
  301. [2, 3, 4],
  302. [3, 4, 5],
  303. ],
  304. [
  305. [1, 1, 1],
  306. [1, 1, 1],
  307. [1, 1, 1],
  308. ],
  309. [
  310. [ 0, 1, 2 ],
  311. [ 1, 2, 3 ],
  312. [ 2, 3, 4 ],
  313. ],
  314. ],
  315. [
  316. [
  317. [0, 1, 2],
  318. [9, 8, 7],
  319. ],
  320. [
  321. [6, 5, 4],
  322. [3, 4, 5],
  323. ],
  324. [
  325. [ -6, -4, -2 ],
  326. [ 6, 4, 2 ],
  327. ],
  328. ],
  329. ];
  330. }
  331. /**
  332. * @test subtract exception for rows
  333. * @throws \Exception
  334. */
  335. public function testSubtractExceptionRows()
  336. {
  337. // Given
  338. $A = MatrixFactory::create([
  339. [1, 2],
  340. [2, 3],
  341. ]);
  342. $B = MatrixFactory::create([
  343. [1, 2]
  344. ]);
  345. // Then
  346. $this->expectException(Exception\MatrixException::class);
  347. // When
  348. $A->subtract($B);
  349. }
  350. /**
  351. * @test subtract exception for columns
  352. * @throws \Exception
  353. */
  354. public function testSubtractExceptionColumns()
  355. {
  356. // Given
  357. $A = MatrixFactory::create([
  358. [1, 2, 3],
  359. [2, 3, 4],
  360. ]);
  361. $B = MatrixFactory::create([
  362. [1, 2],
  363. [2, 3],
  364. ]);
  365. // Then
  366. $this->expectException(Exception\MatrixException::class);
  367. // When
  368. $A->subtract($B);
  369. }
  370. /**
  371. * @test multiplication
  372. * @dataProvider dataProviderForMultiply
  373. * @param array $A
  374. * @param array $B
  375. * @param array $expected
  376. * @throws \Exception
  377. */
  378. public function testMultiply(array $A, array $B, array $expected)
  379. {
  380. // Given
  381. $A = MatrixFactory::create($A);
  382. $B = MatrixFactory::create($B);
  383. $expected = MatrixFactory::create($expected);
  384. // When
  385. $R = $A->multiply($B);
  386. // Then
  387. $this->assertEqualsWithDelta($expected, $R, 0.00001);
  388. $this->assertTrue($R->isEqual($expected));
  389. }
  390. public function dataProviderForMultiply(): array
  391. {
  392. return [
  393. [
  394. [
  395. [0]
  396. ],
  397. [
  398. [0]
  399. ],
  400. [
  401. [0]
  402. ],
  403. ],
  404. [
  405. [
  406. [0]
  407. ],
  408. [
  409. [1]
  410. ],
  411. [
  412. [0]
  413. ],
  414. ],
  415. [
  416. [
  417. [1]
  418. ],
  419. [
  420. [0]
  421. ],
  422. [
  423. [0]
  424. ],
  425. ],
  426. [
  427. [
  428. [1]
  429. ],
  430. [
  431. [2]
  432. ],
  433. [
  434. [2]
  435. ],
  436. ],
  437. [
  438. [
  439. [2]
  440. ],
  441. [
  442. [1]
  443. ],
  444. [
  445. [2]
  446. ],
  447. ],
  448. [
  449. [
  450. [2]
  451. ],
  452. [
  453. [3]
  454. ],
  455. [
  456. [6]
  457. ],
  458. ],
  459. [
  460. [
  461. [3]
  462. ],
  463. [
  464. [2]
  465. ],
  466. [
  467. [6]
  468. ],
  469. ],
  470. [
  471. [
  472. [1]
  473. ],
  474. [
  475. [1, 2, 3]
  476. ],
  477. [
  478. [1, 2, 3]
  479. ],
  480. ],
  481. [
  482. [
  483. [0]
  484. ],
  485. [
  486. [1, 2, 3]
  487. ],
  488. [
  489. [0, 0, 0]
  490. ],
  491. ],
  492. [
  493. [
  494. [4]
  495. ],
  496. [
  497. [1, 2, 3]
  498. ],
  499. [
  500. [4, 8, 12]
  501. ],
  502. ],
  503. [
  504. [
  505. [4]
  506. ],
  507. [
  508. [1, -3, 2]
  509. ],
  510. [
  511. [4, -12, 8]
  512. ],
  513. ],
  514. [
  515. [
  516. [1, -3, 2]
  517. ],
  518. [
  519. [2],
  520. [-1],
  521. [0],
  522. ],
  523. [
  524. [5],
  525. ],
  526. ],
  527. [
  528. [
  529. [1],
  530. [-3],
  531. [2],
  532. ],
  533. [
  534. [-1, -2],
  535. ],
  536. [
  537. [-1, -2],
  538. [3, 6],
  539. [-2, -4],
  540. ],
  541. ],
  542. [
  543. [
  544. [0, 1, 0]
  545. ],
  546. [
  547. [1, -2, 2],
  548. [4, 2, 0],
  549. [1, 2, 3],
  550. ],
  551. [
  552. [4, 2, 0],
  553. ],
  554. ],
  555. [
  556. [
  557. [1, 2],
  558. [3, 4],
  559. ],
  560. [
  561. [0, 0],
  562. [0, 0],
  563. ],
  564. [
  565. [0, 0],
  566. [0, 0],
  567. ],
  568. ],
  569. [
  570. [
  571. [0, 0],
  572. [0, 0],
  573. ],
  574. [
  575. [1, 2],
  576. [3, 4],
  577. ],
  578. [
  579. [0, 0],
  580. [0, 0],
  581. ],
  582. ],
  583. [
  584. [
  585. [0, 1],
  586. [0, 0],
  587. ],
  588. [
  589. [0, 0],
  590. [1, 0],
  591. ],
  592. [
  593. [1, 0],
  594. [0, 0],
  595. ],
  596. ],
  597. [
  598. [
  599. [0, 0],
  600. [1, 0],
  601. ],
  602. [
  603. [0, 1],
  604. [0, 0],
  605. ],
  606. [
  607. [0, 0],
  608. [0, 1],
  609. ],
  610. ],
  611. [
  612. [
  613. [1, 2],
  614. [3, 4],
  615. ],
  616. [
  617. [5, 6],
  618. [7, 8],
  619. ],
  620. [
  621. [19, 22],
  622. [43, 50],
  623. ],
  624. ],
  625. [
  626. [
  627. [1, 2],
  628. [3, 4],
  629. ],
  630. [
  631. [2, 0],
  632. [1, 2],
  633. ],
  634. [
  635. [4, 4],
  636. [10, 8],
  637. ],
  638. ],
  639. [
  640. [
  641. [2, 0],
  642. [1, 2],
  643. ],
  644. [
  645. [1, 2],
  646. [3, 4],
  647. ],
  648. [
  649. [2, 4],
  650. [7, 10],
  651. ],
  652. ],
  653. [
  654. [
  655. [ 1, 0, -2 ],
  656. [ 0, 3, -1 ],
  657. ],
  658. [
  659. [ 0, 3 ],
  660. [ -2, -1 ],
  661. [ 0, 4 ],
  662. ],
  663. [
  664. [ 0, -5 ],
  665. [ -6, -7 ],
  666. ],
  667. ],
  668. [
  669. [
  670. [ 2, 3 ],
  671. [ 1, -5 ],
  672. ],
  673. [
  674. [ 4, 3, 6 ],
  675. [ 1, -2, 3 ],
  676. ],
  677. [
  678. [ 11, 0, 21 ],
  679. [ -1, 13, -9 ],
  680. ],
  681. ],
  682. [
  683. [
  684. [1, 2, 3],
  685. [4, 5, 6],
  686. ],
  687. [
  688. [7, 8],
  689. [9, 10],
  690. [11, 12],
  691. ],
  692. [
  693. [58, 64],
  694. [139, 154],
  695. ],
  696. ],
  697. [
  698. [
  699. [3, 4, 2],
  700. ],
  701. [
  702. [13, 9, 7, 15],
  703. [8, 7, 4, 6],
  704. [6, 4, 0, 3],
  705. ],
  706. [
  707. [83, 63, 37, 75],
  708. ],
  709. ],
  710. [
  711. [
  712. [0, 1, 2],
  713. [3, 4, 5],
  714. ],
  715. [
  716. [6, 7],
  717. [8, 9],
  718. [10, 11],
  719. ],
  720. [
  721. [28, 31],
  722. [100, 112],
  723. ],
  724. ],
  725. [
  726. [
  727. [1, 2, 3],
  728. [4, 5, 6],
  729. [7, 8, 9],
  730. ],
  731. [
  732. [1, 2, 3],
  733. [4, 5, 6],
  734. [7, 8, 9],
  735. ],
  736. [
  737. [30, 36, 42],
  738. [66, 81, 96],
  739. [102, 126, 150],
  740. ],
  741. ],
  742. [
  743. [
  744. [1, 2, 3, 4, 5, 6, 7, 8],
  745. [2, 3, 4, 5, 6, 7, 8, 9],
  746. [3, 4, 5, 6, 7, 8, 9, 1],
  747. [4, 5, 6, 7, 8, 9, 1, 2],
  748. [5, 6, 7, 8, 9, 1, 2, 3],
  749. [6, 7, 8, 9, 1, 2, 3, 4],
  750. [7, 8, 9, 1, 2, 3, 4, 5],
  751. [8, 9, 1, 2, 3, 4, 5, 6],
  752. [9, 1, 2, 3, 4, 5, 6, 7],
  753. ],
  754. [
  755. [7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8],
  756. [8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9],
  757. [9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1],
  758. [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2],
  759. [2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3],
  760. [3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4],
  761. [4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5],
  762. [5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6],
  763. ],
  764. [
  765. [150, 159, 177, 204, 240, 204, 177, 159, 150, 150 ,159],
  766. [189, 197, 214, 240, 284, 247, 219, 200, 190, 189, 197],
  767. [183, 181, 188, 204, 247, 281, 243, 214, 194, 183, 181],
  768. [186, 174, 171, 177, 219, 243, 276, 237, 207, 186, 174],
  769. [198, 176, 163, 159, 200, 214, 237, 269, 229, 198, 176],
  770. [219, 187, 164, 150, 190, 194, 207, 229, 260, 219, 187],
  771. [249, 207, 174, 150, 189, 183, 186, 198, 219, 249, 207],
  772. [207, 236, 193, 159, 197, 181, 174, 176, 187, 207, 236],
  773. [174, 193, 221, 177, 214, 188, 171, 163, 164, 174, 193],
  774. ],
  775. ],
  776. [
  777. [
  778. [1.4, 5.3, 4.8],
  779. [3.2, 2.3, 9.05],
  780. [9.54, 0.2, 1.85],
  781. ],
  782. [
  783. [3.5, 5.6, 6.7],
  784. [6.5, 4.2, 9.05],
  785. [0.6, 0.236, 4.5],
  786. ],
  787. [
  788. [42.23, 31.2328, 78.945],
  789. [31.58, 29.7158, 82.980],
  790. [35.80, 54.7006, 74.053],
  791. ],
  792. ],
  793. ];
  794. }
  795. /**
  796. * @test multiply vector
  797. * @dataProvider dataProviderForMultiplyVector
  798. */
  799. public function testMultiplyVector(array $A, array $B, array $R)
  800. {
  801. // Given
  802. $A = MatrixFactory::create($A);
  803. $B = new Vector($B);
  804. $R = MatrixFactory::create($R);
  805. // When
  806. $R2 = $A->multiply($B);
  807. // Then
  808. $this->assertEquals($R, $R2);
  809. }
  810. public function dataProviderForMultiplyVector(): array
  811. {
  812. return [
  813. [
  814. [
  815. [1],
  816. ],
  817. [1],
  818. [
  819. [1],
  820. ],
  821. ],
  822. [
  823. [
  824. [2],
  825. ],
  826. [3],
  827. [
  828. [6],
  829. ],
  830. ],
  831. [
  832. [
  833. [1, 2],
  834. [2, 3],
  835. ],
  836. [4, 5],
  837. [
  838. [14],
  839. [23],
  840. ],
  841. ],
  842. [
  843. [
  844. [1, 2, 3],
  845. [2, 3, 4],
  846. [3, 4, 5],
  847. ],
  848. [1, 2, 3],
  849. [
  850. [14],
  851. [20],
  852. [26],
  853. ],
  854. ],
  855. [
  856. [
  857. [3, 6, 5],
  858. [1, 7, 5],
  859. [2, 3, 2],
  860. ],
  861. [1, 5, 4],
  862. [
  863. [53],
  864. [56],
  865. [25],
  866. ],
  867. ],
  868. [
  869. [
  870. [1, 1, 1],
  871. [2, 2, 2],
  872. ],
  873. [1, 2, 3],
  874. [
  875. [6],
  876. [12],
  877. ],
  878. ],
  879. [
  880. [
  881. [1, 1, 1],
  882. [2, 2, 2],
  883. [3, 3, 3],
  884. [4, 4, 4]
  885. ],
  886. [1, 2, 3],
  887. [
  888. [6],
  889. [12],
  890. [18],
  891. [24],
  892. ],
  893. ],
  894. ];
  895. }
  896. /**
  897. * @test multiple exception
  898. * @throws \Exception
  899. */
  900. public function testMultiplyExceptionDimensionsDoNotMatch()
  901. {
  902. // Given
  903. $A = MatrixFactory::create([
  904. [1, 2, 3],
  905. [2, 3, 4],
  906. ]);
  907. $B = MatrixFactory::create([
  908. [1, 2, 3],
  909. [2, 3, 4],
  910. ]);
  911. // Then
  912. $this->expectException(Exception\MatrixException::class);
  913. // When
  914. $A->multiply($B);
  915. }
  916. /**
  917. * @test multiple exception
  918. * @throws \Exception
  919. */
  920. public function testMultiplyExceptionNotMatrixOrVector()
  921. {
  922. // Given
  923. $A = MatrixFactory::create([
  924. [1, 2, 3],
  925. [2, 3, 4],
  926. [3, 4, 5],
  927. ]);
  928. $B = [
  929. [1, 2, 3],
  930. [2, 3, 4],
  931. [3, 4, 5],
  932. ];
  933. // Then
  934. $this->expectException(Exception\IncorrectTypeException::class);
  935. // When
  936. $A->multiply($B);
  937. }
  938. /**
  939. * @test scalarMultiply
  940. * @dataProvider dataProviderForScalarMultiply
  941. */
  942. public function testScalarMultiply(array $A, $k, array $R)
  943. {
  944. // Given
  945. $A = MatrixFactory::create($A);
  946. $R = MatrixFactory::create($R);
  947. // When
  948. $kA = $A->scalarMultiply($k);
  949. // Then
  950. $this->assertEquals($R, $kA);
  951. }
  952. public function dataProviderForScalarMultiply(): array
  953. {
  954. return [
  955. [
  956. [
  957. [1, 2, 3],
  958. [2, 3, 4],
  959. [3, 4, 5],
  960. ], 3,
  961. [
  962. [3, 6, 9],
  963. [6, 9, 12],
  964. [9, 12, 15],
  965. ],
  966. ],
  967. [
  968. [
  969. [1, 2, 3],
  970. ], 3,
  971. [
  972. [3, 6, 9],
  973. ],
  974. ],
  975. [
  976. [
  977. [1],
  978. [2],
  979. [3],
  980. ], 3,
  981. [
  982. [3],
  983. [6],
  984. [9],
  985. ],
  986. ],
  987. [
  988. [
  989. [1],
  990. ], 3,
  991. [
  992. [3],
  993. ],
  994. ],
  995. ];
  996. }
  997. /**
  998. * @test negate
  999. * @dataProvider dataProviderForNegate
  1000. * @param array $A
  1001. * @param array $expected
  1002. * @throws \Exception
  1003. */
  1004. public function testNegate(array $A, array $expected)
  1005. {
  1006. // Given
  1007. $A = MatrixFactory::create($A);
  1008. $expected = MatrixFactory::create($expected);
  1009. // When
  1010. $−A = $A->negate();
  1011. // Then
  1012. $this->assertEquals($expected, $−A);
  1013. }
  1014. /**
  1015. * @return array [A, −A]
  1016. */
  1017. public function dataProviderForNegate(): array
  1018. {
  1019. return [
  1020. [
  1021. [
  1022. [0]
  1023. ],
  1024. [
  1025. [0]
  1026. ],
  1027. ],
  1028. [
  1029. [
  1030. [1]
  1031. ],
  1032. [
  1033. [-1]
  1034. ],
  1035. ],
  1036. [
  1037. [
  1038. [-1]
  1039. ],
  1040. [
  1041. [1]
  1042. ],
  1043. ],
  1044. [
  1045. [
  1046. [1, 2],
  1047. [3, 4],
  1048. ],
  1049. [
  1050. [-1, -2],
  1051. [-3, -4],
  1052. ],
  1053. ],
  1054. [
  1055. [
  1056. [1, -2, 3],
  1057. [-4, 5, -6],
  1058. [7, -8, 9],
  1059. ],
  1060. [
  1061. [-1, 2, -3],
  1062. [4, -5, 6],
  1063. [-7, 8, -9],
  1064. ]
  1065. ],
  1066. ];
  1067. }
  1068. /**
  1069. * @test scalarDivide
  1070. * @dataProvider dataProviderForScalarDivide
  1071. */
  1072. public function testScalarDivide(array $A, $k, array $R)
  1073. {
  1074. // Given
  1075. $A = MatrixFactory::create($A);
  1076. $R = MatrixFactory::create($R);
  1077. // When
  1078. $divided = $A->scalarDivide($k);
  1079. // Then
  1080. $this->assertEquals($R, $divided);
  1081. }
  1082. public function dataProviderForScalarDivide(): array
  1083. {
  1084. return [
  1085. [
  1086. [
  1087. [1, 2, 3],
  1088. [2, 3, 4],
  1089. [3, 4, 5],
  1090. ], 3,
  1091. [
  1092. [1 / 3, 2 / 3, 1],
  1093. [2 / 3, 1, 4 / 3],
  1094. [1, 4 / 3, 5 / 3],
  1095. ],
  1096. ],
  1097. [
  1098. [
  1099. [3, 6, 9],
  1100. ], 3,
  1101. [
  1102. [1, 2, 3],
  1103. ],
  1104. ],
  1105. [
  1106. [
  1107. [1],
  1108. [2],
  1109. [3],
  1110. ], 3,
  1111. [
  1112. [1 / 3],
  1113. [2 / 3],
  1114. [1],
  1115. ],
  1116. ],
  1117. [
  1118. [
  1119. [1],
  1120. ], 3,
  1121. [
  1122. [1 / 3],
  1123. ],
  1124. ],
  1125. ];
  1126. }
  1127. /**
  1128. * @test scalarDivide by zero
  1129. * @throws \Exception
  1130. */
  1131. public function testScalarDivideByZero()
  1132. {
  1133. // Given
  1134. $A = MatrixFactory::create([
  1135. [1, 2, 3],
  1136. [2, 3, 4],
  1137. ]);
  1138. // Then
  1139. $this->expectException(Exception\BadParameterException::class);
  1140. // When
  1141. $A->scalarDivide(0);
  1142. }
  1143. /**
  1144. * @test hadamardProduct
  1145. * @dataProvider dataProviderForHadamardProduct
  1146. */
  1147. public function testHadamardProduct(array $A, array $B, array $expected)
  1148. {
  1149. // Given
  1150. $A = MatrixFactory::create($A);
  1151. $B = MatrixFactory::create($B);
  1152. $expected = MatrixFactory::create($expected);
  1153. // When
  1154. $A∘B = $A->hadamardProduct($B);
  1155. // Then
  1156. $this->assertEquals($expected, $A∘B);
  1157. }
  1158. public function dataProviderForHadamardProduct(): array
  1159. {
  1160. return [
  1161. [
  1162. [
  1163. [1, 2, 3],
  1164. [2, 3, 4],
  1165. [3, 4, 5],
  1166. ],
  1167. [
  1168. [1, 2, 3],
  1169. [2, 3, 4],
  1170. [3, 4, 5],
  1171. ],
  1172. [
  1173. [1, 4, 9],
  1174. [4, 9, 16],
  1175. [9, 16, 25],
  1176. ]
  1177. ],
  1178. [
  1179. [
  1180. [1, 2, 3],
  1181. [2, 3, 4],
  1182. [3, 4, 5],
  1183. ],
  1184. [
  1185. [6, 6, 4],
  1186. [8, 7, 8],
  1187. [3, 1, 7],
  1188. ],
  1189. [
  1190. [6, 12, 12],
  1191. [16, 21, 32],
  1192. [9, 4, 35],
  1193. ]
  1194. ],
  1195. ];
  1196. }
  1197. /**
  1198. * @test hadamardProduct dimensions don't match
  1199. * @throws \Exception
  1200. */
  1201. public function testHadamardProductDimensionsDoNotMatch()
  1202. {
  1203. // Given
  1204. $A = MatrixFactory::create([
  1205. [1, 2, 3],
  1206. [2, 3, 4],
  1207. ]);
  1208. $B = MatrixFactory::create([
  1209. [1, 2, 3, 4],
  1210. [2, 3, 4, 5],
  1211. ]);
  1212. // Then
  1213. $this->expectException(Exception\MatrixException::class);
  1214. // When
  1215. $A->hadamardProduct($B);
  1216. }
  1217. /**
  1218. * @test kroneckerProduct
  1219. * @dataProvider dataProviderForKroneckerProduct
  1220. */
  1221. public function testKroneckerProduct(array $A, array $B, array $expected)
  1222. {
  1223. // Given
  1224. $A = new NumericMatrix($A);
  1225. $B = new NumericMatrix($B);
  1226. $expected = new NumericMatrix($expected);
  1227. // When
  1228. $A⊗B = $A->kroneckerProduct($B);
  1229. // Then
  1230. $this->assertEquals($expected->getMatrix(), $A⊗B->getMatrix());
  1231. }
  1232. public function dataProviderForKroneckerProduct(): array
  1233. {
  1234. return [
  1235. [
  1236. [
  1237. [1, 2],
  1238. [3, 4],
  1239. ],
  1240. [
  1241. [0, 5],
  1242. [6, 7],
  1243. ],
  1244. [
  1245. [0, 5, 0, 10],
  1246. [6, 7, 12, 14],
  1247. [0, 15, 0, 20],
  1248. [18, 21, 24, 28],
  1249. ],
  1250. ],
  1251. [
  1252. [
  1253. [1, 1],
  1254. [1, -1],
  1255. ],
  1256. [
  1257. [1, 1],
  1258. [1, -1],
  1259. ],
  1260. [
  1261. [1, 1, 1, 1],
  1262. [1, -1, 1, -1],
  1263. [1, 1, -1, -1],
  1264. [1, -1, -1, 1],
  1265. ],
  1266. ],
  1267. [
  1268. [
  1269. [1, 2, 3],
  1270. [4, 5, 6],
  1271. ],
  1272. [
  1273. [7, 8],
  1274. [9, 10],
  1275. ],
  1276. [
  1277. [7, 8, 14, 16, 21, 24],
  1278. [9, 10, 18, 20, 27, 30],
  1279. [28, 32, 35, 40, 42, 48],
  1280. [36, 40, 45, 50, 54, 60],
  1281. ],
  1282. ],
  1283. [
  1284. [
  1285. [2, 3],
  1286. [5, 4],
  1287. ],
  1288. [
  1289. [5, 5],
  1290. [4, 4],
  1291. [2, 9]
  1292. ],
  1293. [
  1294. [10, 10, 15, 15],
  1295. [8, 8, 12, 12],
  1296. [4, 18, 6, 27],
  1297. [25, 25, 20, 20],
  1298. [20, 20, 16, 16],
  1299. [10, 45, 8, 36],
  1300. ],
  1301. ],
  1302. [
  1303. [
  1304. [2, 3],
  1305. [5, 4],
  1306. ],
  1307. [
  1308. [5, 4, 2],
  1309. [5, 4, 9],
  1310. ],
  1311. [
  1312. [10, 8, 4, 15, 12, 6],
  1313. [10, 8, 18, 15, 12, 27],
  1314. [25, 20, 10, 20, 16, 8],
  1315. [25, 20, 45, 20, 16, 36],
  1316. ],
  1317. ],
  1318. ];
  1319. }
  1320. }