MatrixMapTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. <?php
  2. namespace MathPHP\Tests\LinearAlgebra\Matrix\Base;
  3. use MathPHP\LinearAlgebra\MatrixFactory;
  4. use MathPHP\LinearAlgebra\Vector;
  5. class MatrixMapTest extends \PHPUnit\Framework\TestCase
  6. {
  7. /**
  8. * @test map with a callable
  9. * @dataProvider dataProviderForMapCallable
  10. * @param array $A
  11. * @param callable $func
  12. * @param array $expected
  13. * @throws \Exception
  14. */
  15. public function testMapWithCallable(array $A, callable $func, array $expected)
  16. {
  17. // Given
  18. $A = MatrixFactory::create($A);
  19. $expected = MatrixFactory::create($expected);
  20. // When
  21. $R = $A->map($func);
  22. // Then
  23. $this->assertEquals($expected, $R);
  24. }
  25. /**
  26. * @return array (input, func, output)
  27. */
  28. public function dataProviderForMapCallable(): array
  29. {
  30. return [
  31. 'abs' => [
  32. [
  33. [1, -2, 3],
  34. [-4, 5, -6],
  35. [-7, -8, 9],
  36. ],
  37. 'abs',
  38. [
  39. [1, 2, 3],
  40. [4, 5, 6],
  41. [7, 8, 9],
  42. ]
  43. ],
  44. 'round' => [
  45. [
  46. [1.1, 2.2, 3.3],
  47. [4.4, 5.5, 6.6],
  48. [7.7, 8.8, 9.9],
  49. ],
  50. 'round',
  51. [
  52. [1, 2, 3],
  53. [4, 6, 7],
  54. [8, 9, 10],
  55. ]
  56. ],
  57. 'sqrt' => [
  58. [
  59. [1, 4, 9],
  60. [16, 25, 36],
  61. [49, 64, 81],
  62. ],
  63. 'sqrt',
  64. [
  65. [1, 2, 3],
  66. [4, 5, 6],
  67. [7, 8, 9],
  68. ]
  69. ],
  70. ];
  71. }
  72. /**
  73. * @test map with a closure
  74. * @dataProvider dataProviderForMapClosure
  75. * @param array $A
  76. * @param \Closure $func
  77. * @param array $expected
  78. * @throws \Exception
  79. */
  80. public function testMapWithClosure(array $A, \Closure $func, array $expected)
  81. {
  82. // Given
  83. $A = MatrixFactory::create($A);
  84. $expected = MatrixFactory::create($expected);
  85. // When
  86. $R = $A->map($func);
  87. // Then
  88. $this->assertEquals($expected, $R);
  89. }
  90. /**
  91. * @return array (input, func, output)
  92. */
  93. public function dataProviderForMapClosure(): array
  94. {
  95. return [
  96. 'doubler' => [
  97. [
  98. [1, 2, 3],
  99. [4, 5, 6],
  100. [7, 8, 9],
  101. ],
  102. function ($x) {
  103. return $x * 2;
  104. },
  105. [
  106. [2, 4, 6],
  107. [8, 10, 12],
  108. [14, 16, 18],
  109. ]
  110. ],
  111. 'add one' => [
  112. [
  113. [1, 2, 3],
  114. [4, 5, 6],
  115. [7, 8, 9],
  116. ],
  117. function ($x) {
  118. return $x + 1;
  119. },
  120. [
  121. [2, 3, 4],
  122. [5, 6, 7],
  123. [8, 9, 10],
  124. ]
  125. ],
  126. ];
  127. }
  128. /**
  129. * @test applyRows with a callable
  130. * @dataProvider dataProviderForApplyRowsCallable
  131. * @param array $A
  132. * @param callable $func
  133. * @param array $expected
  134. * @throws \Exception
  135. */
  136. public function testApplyRowsWithCallable(array $A, callable $func, array $expected)
  137. {
  138. // Given
  139. $A = MatrixFactory::create($A);
  140. // When
  141. $R = $A->mapRows($func);
  142. // Then
  143. $this->assertEquals($expected, $R);
  144. }
  145. /**
  146. * @return array (input, func, output)
  147. */
  148. public function dataProviderForApplyRowsCallable(): array
  149. {
  150. return [
  151. [
  152. [
  153. [1, 2, 3],
  154. [4, 5, 6],
  155. [7, 8, 9],
  156. ],
  157. 'array_reverse',
  158. [
  159. [3, 2, 1],
  160. [6, 5, 4],
  161. [9, 8, 7],
  162. ]
  163. ],
  164. [
  165. [
  166. [1, 2, 3],
  167. [4, 5, 6],
  168. [7, 8, 9],
  169. ],
  170. 'array_sum',
  171. [
  172. 6,
  173. 15,
  174. 24,
  175. ]
  176. ],
  177. [
  178. [
  179. [1, 2, 3],
  180. [4, 5, 6],
  181. [7, 8, 9],
  182. ],
  183. 'array_product',
  184. [
  185. 6,
  186. 120,
  187. 504,
  188. ]
  189. ],
  190. [
  191. [
  192. [1, 2, 3],
  193. [4, 0, 6],
  194. [0, 0, 9],
  195. ],
  196. 'array_filter',
  197. [
  198. [1, 2, 3],
  199. [0 => 4, 2 => 6],
  200. [2 => 9],
  201. ]
  202. ],
  203. [
  204. [
  205. [1, 2, 3],
  206. [4, 5, 6],
  207. [7, 8, 9],
  208. ],
  209. 'array_flip',
  210. [
  211. [1 => 0, 2 => 1, 3 => 2],
  212. [4 => 0, 5 => 1, 6 => 2],
  213. [7 => 0, 8 => 1, 9 => 2],
  214. ]
  215. ],
  216. [
  217. [
  218. [1, 2, 3],
  219. [4, 5, 6],
  220. [7, 8, 9],
  221. ],
  222. 'array_keys',
  223. [
  224. [0, 1, 2],
  225. [0, 1, 2],
  226. [0, 1, 2],
  227. ]
  228. ],
  229. [
  230. [
  231. [1, 1, 3],
  232. [4, 6, 6],
  233. [7, 7, 7],
  234. ],
  235. 'array_unique',
  236. [
  237. [1, 2 => 3],
  238. [4, 1 => 6],
  239. [0 => 7],
  240. ]
  241. ],
  242. [
  243. [
  244. [3, 2, 1],
  245. [6, 5, 4],
  246. [9, 8, 7],
  247. ],
  248. 'count',
  249. [
  250. 3,
  251. 3,
  252. 3,
  253. ]
  254. ],
  255. [
  256. [
  257. [1, 2, 3],
  258. [4, 5, 6],
  259. [7, 8, 9],
  260. ],
  261. 'min',
  262. [
  263. 1,
  264. 4,
  265. 7,
  266. ]
  267. ],
  268. [
  269. [
  270. [1, 2, 3],
  271. [4, 5, 6],
  272. [7, 8, 9],
  273. ],
  274. 'max',
  275. [
  276. 3,
  277. 6,
  278. 9,
  279. ]
  280. ],
  281. [
  282. [
  283. [1, 2, 3, 1, 2, 3],
  284. [4, 5, 6, 6, 6, 6],
  285. [7, 8, 8, 9, 9, 9],
  286. ],
  287. 'array_count_values',
  288. [
  289. [1 => 2, 2 => 2, 3 => 2],
  290. [4 => 1, 5 => 1, 6 => 4],
  291. [7 => 1, 8 => 2, 9 => 3],
  292. ]
  293. ],
  294. ];
  295. }
  296. /**
  297. * @test applyRows with a closure
  298. * @dataProvider dataProviderForApplyRowsClosure
  299. * @param array $A
  300. * @param \Closure $func
  301. * @param array $expected
  302. * @throws \Exception
  303. */
  304. public function testApplyRowsWithClosure(array $A, \Closure $func, array $expected)
  305. {
  306. // Given
  307. $A = MatrixFactory::create($A);
  308. // When
  309. $R = $A->mapRows($func);
  310. // Then
  311. $this->assertEquals($expected, $R);
  312. }
  313. /**
  314. * @return array (input, func, output)
  315. * @throws \Exception
  316. */
  317. public function dataProviderForApplyRowsClosure(): array
  318. {
  319. return [
  320. 'add one' => [
  321. [
  322. [1, 2, 3],
  323. [4, 5, 6],
  324. [7, 8, 9],
  325. ],
  326. function (array $row) {
  327. return \array_sum($row) + 1;
  328. },
  329. [
  330. 7,
  331. 16,
  332. 25,
  333. ]
  334. ],
  335. 'sort' => [
  336. [
  337. [3, 1, 2],
  338. [4, 6, 5],
  339. [7, 8, 9],
  340. ],
  341. function (array $row) {
  342. sort($row);
  343. return $row;
  344. },
  345. [
  346. [1, 2, 3],
  347. [4, 5, 6],
  348. [7, 8, 9],
  349. ],
  350. ],
  351. 'remove first and last' => [
  352. [
  353. [1, 2, 3],
  354. [4, 5, 6],
  355. [7, 8, 9],
  356. ],
  357. function (array $row) {
  358. \array_shift($row);
  359. \array_pop($row);
  360. return $row;
  361. },
  362. [
  363. [2],
  364. [5],
  365. [8],
  366. ],
  367. ],
  368. 'something strange with reduce' => [
  369. [
  370. [1, 2, 3],
  371. [4, 5, 6],
  372. [7, 8, 9],
  373. ],
  374. function (array $row) {
  375. return \array_reduce(
  376. $row,
  377. function ($carry, $item) {
  378. return $carry * $carry + $item;
  379. },
  380. 1
  381. );
  382. },
  383. [
  384. 39,
  385. 906,
  386. 5193,
  387. ]
  388. ],
  389. 'merge' => [
  390. [
  391. [1, 2, 3],
  392. [4, 5, 6],
  393. [7, 8, 9],
  394. ],
  395. function (array $row) {
  396. return \array_merge($row, [9, 9, 9]);
  397. },
  398. [
  399. [1, 2, 3, 9, 9, 9],
  400. [4, 5, 6, 9, 9, 9],
  401. [7, 8, 9, 9, 9, 9],
  402. ],
  403. ],
  404. 'chunk' => [
  405. [
  406. [1, 2, 3],
  407. [4, 5, 6],
  408. [7, 8, 9],
  409. ],
  410. function (array $row) {
  411. return array_chunk($row, 1);
  412. },
  413. [
  414. [[1], [2], [3]],
  415. [[4], [5], [6]],
  416. [[7], [8], [9]],
  417. ],
  418. ],
  419. 'vectors' => [
  420. [
  421. [1, 2, 3],
  422. [4, 5, 6],
  423. [7, 8, 9],
  424. ],
  425. function (array $row) {
  426. return new Vector($row);
  427. },
  428. [
  429. new Vector([1, 2, 3]),
  430. new Vector([4, 5, 6]),
  431. new Vector([7, 8, 9]),
  432. ],
  433. ],
  434. ];
  435. }
  436. /**
  437. * @test applyRows with shuffle closure
  438. * @throws \Exception
  439. */
  440. public function testApplyRowsClosureShuffle()
  441. {
  442. // Given
  443. $A = MatrixFactory::create([
  444. [1, 2, 3],
  445. [4, 5, 6],
  446. [7, 8, 9],
  447. ]);
  448. $func = function (array $row) {
  449. shuffle($row);
  450. return $row;
  451. };
  452. // When
  453. $R = $A->mapRows($func);
  454. // Then
  455. $this->assertTrue(\in_array(1, $R[0]));
  456. $this->assertTrue(\in_array(2, $R[0]));
  457. $this->assertTrue(\in_array(3, $R[0]));
  458. $this->assertTrue(\in_array(4, $R[1]));
  459. $this->assertTrue(\in_array(5, $R[1]));
  460. $this->assertTrue(\in_array(6, $R[1]));
  461. $this->assertTrue(\in_array(7, $R[2]));
  462. $this->assertTrue(\in_array(8, $R[2]));
  463. $this->assertTrue(\in_array(9, $R[2]));
  464. }
  465. /**
  466. * @test walk
  467. */
  468. public function testWalk()
  469. {
  470. // Given
  471. $A = MatrixFactory::create([
  472. [1, 2, 3],
  473. [4, 5, 6],
  474. [7, 8, 9],
  475. ]);
  476. // Then
  477. $func = function ($item) {
  478. $this->assertTrue(\is_int($item));
  479. $this->assertFalse(\is_float($item));
  480. };
  481. // When
  482. $A->walk($func);
  483. }
  484. }