MatrixFactoryTest.php 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  1. <?php
  2. namespace MathPHP\Tests\LinearAlgebra\Matrix;
  3. use MathPHP\LinearAlgebra\ComplexMatrix;
  4. use MathPHP\LinearAlgebra\NumericDiagonalMatrix;
  5. use MathPHP\LinearAlgebra\NumericMatrix;
  6. use MathPHP\LinearAlgebra\Matrix;
  7. use MathPHP\LinearAlgebra\MatrixFactory;
  8. use MathPHP\LinearAlgebra\NumericSquareMatrix;
  9. use MathPHP\LinearAlgebra\ObjectMatrix;
  10. use MathPHP\LinearAlgebra\ObjectSquareMatrix;
  11. use MathPHP\LinearAlgebra\Vector;
  12. use MathPHP\Exception;
  13. class MatrixFactoryTest extends \PHPUnit\Framework\TestCase
  14. {
  15. use \MathPHP\Tests\LinearAlgebra\Fixture\MatrixDataProvider;
  16. /**
  17. * @test create numeric matrix
  18. * @dataProvider dataProviderForSquareMatrix
  19. * @dataProvider dataProviderForNotSquareMatrix
  20. * @dataProvider dataProviderForSingularMatrix
  21. * @dataProvider dataProviderForNonsingularMatrix
  22. * @dataProvider dataProviderForMatrixWithWeirdNumbers
  23. */
  24. public function testCreateNumericMatrix(array $A)
  25. {
  26. // When
  27. $A = MatrixFactory::create($A);
  28. // Then
  29. $this->assertInstanceOf(NumericMatrix::class, $A);
  30. $this->assertInstanceOf(Matrix::class, $A);
  31. }
  32. /**
  33. * @test createNumeric
  34. * @dataProvider dataProviderForSquareMatrix
  35. * @dataProvider dataProviderForNotSquareMatrix
  36. * @dataProvider dataProviderForSingularMatrix
  37. * @dataProvider dataProviderForNonsingularMatrix
  38. * @dataProvider dataProviderForMatrixWithWeirdNumbers
  39. */
  40. public function testSpecificallyCreateNumericMatrix(array $A)
  41. {
  42. // When
  43. $A = MatrixFactory::createNumeric($A);
  44. // Then
  45. $this->assertInstanceOf(NumericMatrix::class, $A);
  46. $this->assertInstanceOf(Matrix::class, $A);
  47. }
  48. /**
  49. * @test create diagonal matrix
  50. * @dataProvider dataProviderForDiagonalMatrix
  51. */
  52. public function testCreateDiagonalMatrix(array $A)
  53. {
  54. // When
  55. $A = MatrixFactory::diagonal($A);
  56. // Then
  57. $this->assertInstanceOf(NumericDiagonalMatrix::class, $A);
  58. $this->assertInstanceOf(NumericMatrix::class, $A);
  59. $this->assertInstanceOf(Matrix::class, $A);
  60. }
  61. public function dataProviderForDiagonalMatrix()
  62. {
  63. return [
  64. [[1]],
  65. [[1, 2]],
  66. [[1, 2, 3]],
  67. [[1, 2, 3, 4]],
  68. ];
  69. }
  70. /**
  71. * @test create square matrix
  72. * @dataProvider dataProviderForSquareMatrix
  73. */
  74. public function testCreateSquareMatrix(array $A)
  75. {
  76. // When
  77. $A = MatrixFactory::create($A);
  78. // Then
  79. $this->assertInstanceOf(NumericSquareMatrix::class, $A);
  80. $this->assertInstanceOf(NumericMatrix::class, $A);
  81. $this->assertInstanceOf(Matrix::class, $A);
  82. }
  83. /**
  84. * @test create from array of vectors
  85. * @dataProvider dataProviderFromArrayOfVectors
  86. */
  87. public function testCreateArrayOfVectors(array $vectors, array $expected)
  88. {
  89. // Given
  90. $vectors = \array_map(
  91. function ($vector) {
  92. return new Vector($vector);
  93. },
  94. $vectors
  95. );
  96. // When
  97. $A = MatrixFactory::createFromVectors($vectors);
  98. // Then
  99. $this->assertInstanceOf(NumericMatrix::class, $A);
  100. $this->assertEquals($expected, $A->getMatrix());
  101. }
  102. public function dataProviderFromArrayOfVectors(): array
  103. {
  104. return [
  105. [
  106. [
  107. [1, 2],
  108. ],
  109. [
  110. [1],
  111. [2],
  112. ],
  113. ],
  114. [
  115. [
  116. [1, 2],
  117. [3, 4],
  118. ],
  119. [
  120. [1, 3],
  121. [2, 4],
  122. ],
  123. ],
  124. [
  125. [
  126. [1, 2],
  127. [3, 4],
  128. [5, 6],
  129. ],
  130. [
  131. [1, 3, 5],
  132. [2, 4, 6],
  133. ],
  134. ],
  135. [
  136. [
  137. [1, 2, 3],
  138. [3, 4, 5],
  139. [5, 6, 6],
  140. ],
  141. [
  142. [1, 3, 5],
  143. [2, 4, 6],
  144. [3, 5, 6],
  145. ],
  146. ],
  147. ];
  148. }
  149. /**
  150. * @test create from array of vectors exception - different lengths
  151. * @throws \Exception
  152. */
  153. public function testCreateFromArrayOfVectorsExceptionVectorsDifferentLengths()
  154. {
  155. // Given
  156. $A = [
  157. new Vector([1, 2]),
  158. new Vector([4, 5, 6]),
  159. ];
  160. // Then
  161. $this->expectException(Exception\MatrixException::class);
  162. // When
  163. $A = MatrixFactory::createFromVectors($A);
  164. }
  165. /**
  166. * @test createFunctionMatrix
  167. * @dataProvider dataProviderForFunctionSquareMatrix
  168. */
  169. public function testCreateFunctionSquareMatrix(array $A)
  170. {
  171. // When
  172. $A = MatrixFactory::createFunctionMatrix($A);
  173. // Then
  174. $this->assertInstanceOf(\MathPHP\LinearAlgebra\FunctionMatrix::class, $A);
  175. }
  176. public function dataProviderForFunctionSquareMatrix(): array
  177. {
  178. $function = function ($x) {
  179. return $x * 2;
  180. };
  181. return [
  182. [
  183. [
  184. [$function]
  185. ]
  186. ],
  187. [
  188. [
  189. [$function, $function],
  190. [$function, $function],
  191. ],
  192. ],
  193. [
  194. [
  195. [$function, $function, $function],
  196. [$function, $function, $function],
  197. [$function, $function, $function],
  198. ],
  199. ],
  200. ];
  201. }
  202. /**
  203. * @test createFunctionMatrix
  204. * @dataProvider dataProviderForFunctionMatrix
  205. */
  206. public function testCreateFunctionMatrix(array $A)
  207. {
  208. // When
  209. $A = MatrixFactory::createFunctionMatrix($A);
  210. // Then
  211. $this->assertInstanceOf(\MathPHP\LinearAlgebra\FunctionMatrix::class, $A);
  212. }
  213. public function dataProviderForFunctionMatrix(): array
  214. {
  215. $function = function ($x) {
  216. return $x * 2;
  217. };
  218. return [
  219. [
  220. [
  221. [$function, $function]
  222. ]
  223. ],
  224. [
  225. [
  226. [$function, $function],
  227. [$function, $function],
  228. [$function, $function],
  229. ],
  230. ],
  231. [
  232. [
  233. [$function, $function, $function],
  234. [$function, $function, $function],
  235. [$function, $function, $function],
  236. [$function, $function, $function],
  237. ],
  238. ],
  239. ];
  240. }
  241. /**
  242. * @test createFunctionMatrix error when matrix not made of functions
  243. */
  244. public function testCreateFunctionMatrixErrorNotMadeOfFunctions()
  245. {
  246. // Given
  247. $A = [
  248. [1, 2, 3],
  249. [2, 3, 4],
  250. [3, 4, 5],
  251. ];
  252. // Then
  253. $this->expectException(Exception\BadDataException::class);
  254. // When
  255. $A = MatrixFactory::createFunctionMatrix($A);
  256. }
  257. /**
  258. * @test create matrix
  259. * @dataProvider dataProviderForMatrix
  260. */
  261. public function testCreateMatrix(array $A)
  262. {
  263. // When
  264. $A = MatrixFactory::create($A);
  265. // Then
  266. $this->assertInstanceOf(\MathPHP\LinearAlgebra\NumericMatrix::class, $A);
  267. // And
  268. $this->assertNotInstanceOf(\MathPHP\LinearAlgebra\NumericSquareMatrix::class, $A);
  269. $this->assertNotInstanceOf(\MathPHP\LinearAlgebra\FunctionMatrix::class, $A);
  270. $this->assertNotInstanceOf(\MathPHP\LinearAlgebra\NumericDiagonalMatrix::class, $A);
  271. }
  272. public function dataProviderForMatrix(): array
  273. {
  274. return [
  275. [
  276. [
  277. [1, 2, 3],
  278. [2, 3, 4],
  279. ],
  280. ],
  281. [
  282. [
  283. [1, 2, 3],
  284. [2, 3, 4],
  285. [3, 4, 5],
  286. [4, 5, 6],
  287. ],
  288. ],
  289. ];
  290. }
  291. /**
  292. * @test check params exception for empty array
  293. * @throws \Exception
  294. */
  295. public function testCheckParamsExceptionEmptyArray()
  296. {
  297. // Given
  298. $A = [];
  299. // Then
  300. $this->expectException(Exception\BadDataException::class);
  301. // When
  302. $M = MatrixFactory::create($A);
  303. }
  304. /**
  305. * @test check params exception for single dimensional array
  306. * @throws \Exception
  307. */
  308. public function testCheckParamsExceptionSingleDimensionalArray()
  309. {
  310. // Given
  311. $A = [1, 2, 3];
  312. // Then
  313. $this->expectException(Exception\BadDataException::class);
  314. // When
  315. $M = MatrixFactory::create($A);
  316. }
  317. /**
  318. * @test matrix unknown type exception
  319. * @throws \Exception
  320. */
  321. public function testMatrixUnknownTypeException()
  322. {
  323. // Given
  324. $A = [
  325. [[1], [2], [3]],
  326. [[2], [3], [4]],
  327. ];
  328. // Then
  329. $this->expectException(Exception\IncorrectTypeException::class);
  330. // When
  331. MatrixFactory::create($A);
  332. }
  333. /**
  334. * @test identity
  335. * @dataProvider dataProviderForIdentity
  336. * @param int $n
  337. * @param array $R
  338. * @throws \Exception
  339. */
  340. public function testIdentity(int $n, array $R)
  341. {
  342. // Given
  343. $R = new NumericSquareMatrix($R);
  344. // When
  345. $I = MatrixFactory::identity($n);
  346. // Then
  347. $this->assertEquals($R, $I);
  348. }
  349. /**
  350. * @return array
  351. */
  352. public function dataProviderForIdentity(): array
  353. {
  354. return [
  355. [
  356. 1, [[1]],
  357. ],
  358. [
  359. 2, [
  360. [1, 0],
  361. [0, 1],
  362. ]
  363. ],
  364. [
  365. 3, [
  366. [1, 0, 0],
  367. [0, 1, 0],
  368. [0, 0, 1]
  369. ]
  370. ],
  371. [
  372. 4, [
  373. [1, 0, 0, 0],
  374. [0, 1, 0, 0],
  375. [0, 0, 1, 0],
  376. [0, 0, 0, 1],
  377. ]
  378. ],
  379. ];
  380. }
  381. /**
  382. * @test downshiftPermutation
  383. * @dataProvider dataProviderForDownshiftPermutation
  384. * @param int $n
  385. * @param array $R
  386. * @throws \Exception
  387. */
  388. public function testDownshiftPermutation(int $n, array $R)
  389. {
  390. $R = new NumericSquareMatrix($R);
  391. $this->assertEquals($R, MatrixFactory::downshiftPermutation($n));
  392. }
  393. /**
  394. * @return array [n, R]
  395. */
  396. public function dataProviderForDownshiftPermutation(): array
  397. {
  398. return [
  399. [
  400. 1,
  401. [
  402. [1]
  403. ]
  404. ],
  405. [
  406. 2,
  407. [
  408. [0, 1],
  409. [1, 0],
  410. ]
  411. ],
  412. [
  413. 3,
  414. [
  415. [0, 0, 1],
  416. [1, 0, 0],
  417. [0, 1, 0],
  418. ]
  419. ],
  420. [
  421. 4,
  422. [
  423. [0, 0, 0, 1],
  424. [1, 0, 0, 0],
  425. [0, 1, 0, 0],
  426. [0, 0, 1, 0],
  427. ]
  428. ],
  429. ];
  430. }
  431. /**
  432. * @test upshiftPermutation
  433. * @dataProvider dataProviderForUpshiftPermutation
  434. * @param int $n
  435. * @param array $R
  436. * @throws \Exception
  437. */
  438. public function testUpshiftPermutation(int $n, array $R)
  439. {
  440. $R = new NumericSquareMatrix($R);
  441. $this->assertEquals($R, MatrixFactory::upshiftPermutation($n));
  442. }
  443. /**
  444. * @return array [n, R]
  445. */
  446. public function dataProviderForUpshiftPermutation(): array
  447. {
  448. return [
  449. [
  450. 1,
  451. [
  452. [1]
  453. ]
  454. ],
  455. [
  456. 2,
  457. [
  458. [0, 1],
  459. [1, 0],
  460. ]
  461. ],
  462. [
  463. 3,
  464. [
  465. [0, 1, 0],
  466. [0, 0, 1],
  467. [1, 0, 0],
  468. ]
  469. ],
  470. [
  471. 4,
  472. [
  473. [0, 1, 0, 0],
  474. [0, 0, 1, 0],
  475. [0, 0, 0, 1],
  476. [1, 0, 0, 0],
  477. ]
  478. ],
  479. ];
  480. }
  481. /**
  482. * @test identity with n less than zero
  483. * @throws \Exception
  484. */
  485. public function testIdentityExceptionNLessThanZero()
  486. {
  487. // Given
  488. $n = -1;
  489. // Then
  490. $this->expectException(Exception\OutOfBoundsException::class);
  491. // When
  492. MatrixFactory::identity($n);
  493. }
  494. /**
  495. * @test exchange
  496. * @dataProvider dataProviderForExchange
  497. * @param int $n
  498. * @param array $R
  499. * @throws \Exception
  500. */
  501. public function testExchange(int $n, array $R)
  502. {
  503. // Given
  504. $R = new NumericSquareMatrix($R);
  505. // When
  506. $E = MatrixFactory::exchange($n);
  507. // Then
  508. $this->assertEquals($R, $E);
  509. }
  510. /**
  511. * @return array
  512. */
  513. public function dataProviderForExchange(): array
  514. {
  515. return [
  516. [
  517. 1, [[1]],
  518. ],
  519. [
  520. 2, [
  521. [0, 1],
  522. [1, 0],
  523. ]
  524. ],
  525. [
  526. 3, [
  527. [0, 0, 1],
  528. [0, 1, 0],
  529. [1, 0, 0]
  530. ]
  531. ],
  532. [
  533. 4, [
  534. [0, 0, 0, 1],
  535. [0, 0, 1, 0],
  536. [0, 1, 0, 0],
  537. [1, 0, 0, 0],
  538. ]
  539. ],
  540. ];
  541. }
  542. /**
  543. * @test exchange exception - n less than zero
  544. * @throws \Exception
  545. */
  546. public function testExchangeExceptionNLessThanZero()
  547. {
  548. // When
  549. $n = -1;
  550. // Then
  551. $this->expectException(Exception\OutOfBoundsException::class);
  552. // When
  553. MatrixFactory::exchange($n);
  554. }
  555. /**
  556. * @test zero
  557. * @dataProvider dataProviderForZero
  558. * @param int $m
  559. * @param int $n
  560. * @param array $R
  561. * @throws \Exception
  562. */
  563. public function testZero(int $m, int $n, array $R)
  564. {
  565. // Given
  566. $R = MatrixFactory::create($R);
  567. // When
  568. $Z = MatrixFactory::zero($m, $n);
  569. // Then
  570. $this->assertEquals($R, $Z);
  571. }
  572. /**
  573. * @return array
  574. */
  575. public function dataProviderForZero(): array
  576. {
  577. return [
  578. [
  579. 1, 1, [[0]]
  580. ],
  581. [
  582. 2, 2, [
  583. [0, 0],
  584. [0, 0],
  585. ]
  586. ],
  587. [
  588. 3, 3, [
  589. [0, 0, 0],
  590. [0, 0, 0],
  591. [0, 0, 0],
  592. ]
  593. ],
  594. [
  595. 2, 3, [
  596. [0, 0, 0],
  597. [0, 0, 0],
  598. ]
  599. ],
  600. [
  601. 3, 2, [
  602. [0, 0],
  603. [0, 0],
  604. [0, 0],
  605. ]
  606. ]
  607. ];
  608. }
  609. /**
  610. * @test zero with row less than one
  611. * @throws \Exception
  612. */
  613. public function testZeroExceptionRowsLessThanOne()
  614. {
  615. // Given
  616. $m = 0;
  617. $n = 2;
  618. // Then
  619. $this->expectException(Exception\OutOfBoundsException::class);
  620. // When
  621. MatrixFactory::zero($m, $n);
  622. }
  623. /**
  624. * @test one
  625. * @dataProvider dataProviderForOne
  626. */
  627. public function testOne($m, $n, array $R)
  628. {
  629. // Given
  630. $R = MatrixFactory::create($R);
  631. // When
  632. $M = MatrixFactory::one($m, $n);
  633. // Then
  634. $this->assertEquals($R, $M);
  635. }
  636. public function dataProviderForOne(): array
  637. {
  638. return [
  639. [
  640. 1, 1, [[1]]
  641. ],
  642. [
  643. 2, 2, [
  644. [1, 1],
  645. [1, 1],
  646. ]
  647. ],
  648. [
  649. 3, 3, [
  650. [1, 1, 1],
  651. [1, 1, 1],
  652. [1, 1, 1],
  653. ]
  654. ],
  655. [
  656. 2, 3, [
  657. [1, 1, 1],
  658. [1, 1, 1],
  659. ]
  660. ],
  661. [
  662. 3, 2, [
  663. [1, 1],
  664. [1, 1],
  665. [1, 1],
  666. ]
  667. ]
  668. ];
  669. }
  670. /**
  671. * @test one exception - rows less than one
  672. * @throws \Exception
  673. */
  674. public function testOneExceptionRowsLessThanOne()
  675. {
  676. $this->expectException(Exception\OutOfBoundsException::class);
  677. MatrixFactory::one(0, 2);
  678. }
  679. /**
  680. * @test eye
  681. * @dataProvider dataProviderForEye
  682. */
  683. public function testEye(int $m, int $n, int $k, int $x, array $R)
  684. {
  685. // Given
  686. $R = MatrixFactory::create($R);
  687. // When
  688. $A = MatrixFactory::eye($m, $n, $k, $x);
  689. // Then
  690. $this->assertEquals($R, $A);
  691. $this->assertEquals($R->getMatrix(), $A->getMatrix());
  692. // And
  693. $this->assertEquals($m, $R->getM());
  694. $this->assertEquals($n, $R->getN());
  695. }
  696. public function dataProviderForEye(): array
  697. {
  698. return [
  699. [
  700. 1, 1, 0, 1,
  701. [
  702. [1]
  703. ],
  704. ],
  705. [
  706. 1, 1, 0, 9,
  707. [
  708. [9]
  709. ],
  710. ],
  711. [
  712. 2, 2, 0, 1,
  713. [
  714. [1, 0],
  715. [0, 1],
  716. ],
  717. ],
  718. [
  719. 2, 2, 1, 1,
  720. [
  721. [0, 1],
  722. [0, 0],
  723. ],
  724. ],
  725. [
  726. 3, 3, 0, 1,
  727. [
  728. [1, 0, 0],
  729. [0, 1, 0],
  730. [0, 0, 1],
  731. ],
  732. ],
  733. [
  734. 3, 3, 1, 1,
  735. [
  736. [0, 1, 0],
  737. [0, 0, 1],
  738. [0, 0, 0],
  739. ],
  740. ],
  741. [
  742. 3, 3, 2, 1,
  743. [
  744. [0, 0, 1],
  745. [0, 0, 0],
  746. [0, 0, 0],
  747. ],
  748. ],
  749. [
  750. 3, 3, 0, 9,
  751. [
  752. [9, 0, 0],
  753. [0, 9, 0],
  754. [0, 0, 9],
  755. ],
  756. ],
  757. [
  758. 3, 3, 1, 9,
  759. [
  760. [0, 9, 0],
  761. [0, 0, 9],
  762. [0, 0, 0],
  763. ],
  764. ],
  765. [
  766. 3, 3, 0, -9,
  767. [
  768. [-9, 0, 0],
  769. [0, -9, 0],
  770. [0, 0, -9],
  771. ],
  772. ],
  773. [
  774. 3, 4, 0, 1,
  775. [
  776. [1, 0, 0, 0],
  777. [0, 1, 0, 0],
  778. [0, 0, 1, 0],
  779. ],
  780. ],
  781. [
  782. 3, 4, 1, 1,
  783. [
  784. [0, 1, 0, 0],
  785. [0, 0, 1, 0],
  786. [0, 0, 0, 1],
  787. ],
  788. ],
  789. [
  790. 3, 4, 2, 1,
  791. [
  792. [0, 0, 1, 0],
  793. [0, 0, 0, 1],
  794. [0, 0, 0, 0],
  795. ],
  796. ],
  797. [
  798. 3, 4, 3, 1,
  799. [
  800. [0, 0, 0, 1],
  801. [0, 0, 0, 0],
  802. [0, 0, 0, 0],
  803. ],
  804. ],
  805. [
  806. 3, 4, 1, 9,
  807. [
  808. [0, 9, 0, 0],
  809. [0, 0, 9, 0],
  810. [0, 0, 0, 9],
  811. ],
  812. ],
  813. [
  814. 4, 3, 0, 1,
  815. [
  816. [1, 0, 0],
  817. [0, 1, 0],
  818. [0, 0, 1],
  819. [0, 0, 0],
  820. ],
  821. ],
  822. [
  823. 4, 3, 1, 1,
  824. [
  825. [0, 1, 0],
  826. [0, 0, 1],
  827. [0, 0, 0],
  828. [0, 0, 0],
  829. ],
  830. ],
  831. [
  832. 4, 3, 2, 1,
  833. [
  834. [0, 0, 1],
  835. [0, 0, 0],
  836. [0, 0, 0],
  837. [0, 0, 0],
  838. ],
  839. ],
  840. ];
  841. }
  842. /**
  843. * @test eye exceptions
  844. * @dataProvider dataProviderForEyeExceptions
  845. */
  846. public function testEyeExceptions(int $m, int $n, int $k, int $x)
  847. {
  848. $this->expectException(Exception\OutOfBoundsException::class);
  849. $A = MatrixFactory::eye($m, $n, $k, $x);
  850. }
  851. /**
  852. * @return array
  853. */
  854. public function dataProviderForEyeExceptions(): array
  855. {
  856. return [
  857. [-1, 2, 1, 1],
  858. [2, -1, 1, 1],
  859. [2, 2, -1, 1],
  860. [2, 2, 2, 1],
  861. [2, 2, 3, 1],
  862. ];
  863. }
  864. /**
  865. * @test hilbert creates the expected Hilbert matrix
  866. * @dataProvider dataProviderForHilbertMatrix
  867. * @param int $n
  868. * @param array $H
  869. * @throws \Exception
  870. */
  871. public function testHilbertMatrix($n, $H)
  872. {
  873. // Given
  874. $H = MatrixFactory::create($H);
  875. // When
  876. $sut = MatrixFactory::hilbert($n);
  877. // Then
  878. $this->assertEquals($H, $sut);
  879. }
  880. /**
  881. * @test Hilbert exception when n is less than zero
  882. * @throws \Exception
  883. */
  884. public function testHilbertExceptionNLessThanZero()
  885. {
  886. // Given
  887. $n = -1;
  888. // Then
  889. $this->expectException(Exception\OutOfBoundsException::class);
  890. // When
  891. MatrixFactory::hilbert(-1);
  892. }
  893. /**
  894. * @test Creating a random matrix of a specific size
  895. * @throws \Exception
  896. */
  897. public function testRandomMatrix()
  898. {
  899. // Given
  900. for ($m = 1; $m < 5; $m++) {
  901. for ($n = 1; $n < 5; $n++) {
  902. // When
  903. $A = MatrixFactory::random($m, $n);
  904. // Then
  905. $this->assertEquals($m, $A->getM());
  906. $this->assertEquals($n, $A->getN());
  907. // And
  908. $A->walk(function ($element) {
  909. $this->assertTrue(\is_int($element));
  910. });
  911. }
  912. }
  913. }
  914. /**
  915. * @test create ObjectMatrix
  916. * @dataProvider dataProviderForObjectMatrix
  917. * @param array $A
  918. */
  919. public function testCreateObjectMatrix(array $A)
  920. {
  921. // When
  922. $A = MatrixFactory::create($A);
  923. // Then
  924. $this->assertInstanceOf(ObjectMatrix::class, $A);
  925. $this->assertInstanceOf(Matrix::class, $A);
  926. }
  927. /**
  928. * @test create ObjectSquareMatrix
  929. * @dataProvider dataProviderForObjectSquareMatrix
  930. * @param array $A
  931. */
  932. public function testCreateObjectSquareMatrix(array $A)
  933. {
  934. // When
  935. $A = MatrixFactory::create($A);
  936. // Then
  937. $this->assertInstanceOf(ObjectSquareMatrix::class, $A);
  938. $this->assertInstanceOf(ObjectMatrix::class, $A);
  939. $this->assertInstanceOf(Matrix::class, $A);
  940. }
  941. /**
  942. * @test createFromColumnVector
  943. * @dataProvider dataProviderForCreateFromColumnVector
  944. * @param array $V
  945. * @param array $expected
  946. */
  947. public function testConstructor(array $V, array $expected)
  948. {
  949. // Given
  950. $expected = new NumericMatrix($expected);
  951. // When
  952. $A = MatrixFactory::createFromColumnVector($V);
  953. // Then
  954. $this->assertInstanceOf(NumericMatrix::class, $A);
  955. // And
  956. $this->assertEquals($expected->getMatrix(), $A->getMatrix());
  957. }
  958. public function dataProviderForCreateFromColumnVector(): array
  959. {
  960. return [
  961. [
  962. [1, 2, 3, 4],
  963. [
  964. [1],
  965. [2],
  966. [3],
  967. [4],
  968. ]
  969. ],
  970. [
  971. [1],
  972. [
  973. [1],
  974. ]
  975. ],
  976. ];
  977. }
  978. /**
  979. * @test createFromColumnVector failure due to not being a column vector
  980. */
  981. public function testConstructionFailure()
  982. {
  983. // Given
  984. $A = [
  985. [1, 2, 3],
  986. [2, 3, 4],
  987. ];
  988. // Then
  989. $this->expectException(Exception\BadDataException::class);
  990. // When
  991. $R = MatrixFactory::createFromColumnVector($A);
  992. }
  993. /**
  994. * @test createFromRowVector
  995. * @dataProvider dataProviderForConstructor
  996. * @param array $V
  997. * @param array $expected
  998. * @throws \Exception
  999. */
  1000. public function testCreateFromRowVector(array $V, array $expected)
  1001. {
  1002. // Given
  1003. $expected = new NumericMatrix($expected);
  1004. $A = MatrixFactory::createFromRowVector($V);
  1005. // Then
  1006. $this->assertInstanceOf(NumericMatrix::class, $A);
  1007. // And
  1008. $this->assertEquals($expected->getMatrix(), $A->getMatrix());
  1009. }
  1010. public function dataProviderForConstructor(): array
  1011. {
  1012. return [
  1013. [
  1014. [1, 2, 3, 4],
  1015. [ [1, 2, 3, 4] ],
  1016. ],
  1017. [
  1018. [1],
  1019. [ [1] ],
  1020. ],
  1021. ];
  1022. }
  1023. /**
  1024. * @test createFromRowVector failure due to not being a row vector
  1025. */
  1026. public function testCreateFromRowVectorFailure()
  1027. {
  1028. // Given
  1029. $A = [
  1030. [1, 2, 3],
  1031. [2, 3, 4],
  1032. ];
  1033. // Then
  1034. $this->expectException(Exception\BadDataException::class);
  1035. // When
  1036. $R = MatrixFactory::createFromRowVector($A);
  1037. }
  1038. /**
  1039. * @test create ComplexMatrix
  1040. * @dataProvider dataProviderForComplexObjectMatrix
  1041. * @param array $A
  1042. */
  1043. public function testCreateComplexObjectMatrix(array $A)
  1044. {
  1045. // When
  1046. $A = MatrixFactory::create($A);
  1047. // Then
  1048. $this->assertInstanceOf(ComplexMatrix::class, $A);
  1049. $this->assertInstanceOf(ObjectMatrix::class, $A);
  1050. $this->assertInstanceOf(Matrix::class, $A);
  1051. }
  1052. }