SupportTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. <?php
  2. namespace MathPHP\Tests\Functions;
  3. use MathPHP\Functions\Support;
  4. use MathPHP\Exception;
  5. class SupportTest extends \PHPUnit\Framework\TestCase
  6. {
  7. /**
  8. * @test checkLimits on lower limit
  9. * @dataProvider dataProviderForCheckLimitsLowerLimit
  10. * @param array $limits
  11. * @param array $params
  12. * @throws \Exception
  13. */
  14. public function testCheckLimitsLowerLimit(array $limits, array $params)
  15. {
  16. // When
  17. $withinLimits = Support::checkLimits($limits, $params);
  18. // Then
  19. $this->assertTrue($withinLimits);
  20. }
  21. /**
  22. * @return array
  23. */
  24. public function dataProviderForCheckLimitsLowerLimit(): array
  25. {
  26. return [
  27. [
  28. ['x' => '[0,∞]'],
  29. ['x' => 0],
  30. ],
  31. [
  32. ['x' => '[0,∞]'],
  33. ['x' => 0.1],
  34. ],
  35. [
  36. ['x' => '[0,∞]'],
  37. ['x' => 1],
  38. ],
  39. [
  40. ['x' => '[0,∞]'],
  41. ['x' => 4934],
  42. ],
  43. [
  44. ['x' => '(0,∞]'],
  45. ['x' => 0.1],
  46. ],
  47. [
  48. ['x' => '(0,∞]'],
  49. ['x' => 1],
  50. ],
  51. [
  52. ['x' => '(0,∞]'],
  53. ['x' => 4934],
  54. ],
  55. [
  56. ['x' => '[-50,∞]'],
  57. ['x' => -50],
  58. ],
  59. [
  60. ['x' => '(-50,∞]'],
  61. ['x' => -49],
  62. ],
  63. [
  64. ['x' => '[-∞,10]'],
  65. ['x' => -89379837],
  66. ],
  67. [
  68. ['x' => '(-∞,10]'],
  69. ['x' => -95893223452],
  70. ],
  71. [
  72. ['x' => '[0,∞]', 'y' => '[0,∞]'],
  73. ['x' => 0, 'y' => 5],
  74. ],
  75. [
  76. ['x' => '[0,∞]', 'y' => '[0,∞]', 'z' => '[0,1]'],
  77. ['x' => 0, 'y' => 5],
  78. ],
  79. ];
  80. }
  81. /**
  82. * @test checkLimits out of bounds
  83. * @dataProvider dataProviderForCheckLimitsLowerLimitException
  84. * @param array $limits
  85. * @param array $params
  86. * @throws \Exception
  87. */
  88. public function testCheckLimitsLowerLimitException(array $limits, array $params)
  89. {
  90. // Then
  91. $this->expectException(Exception\OutOfBoundsException::class);
  92. // When
  93. Support::checkLimits($limits, $params);
  94. }
  95. /**
  96. * @return array
  97. */
  98. public function dataProviderForCheckLimitsLowerLimitException(): array
  99. {
  100. return [
  101. [
  102. ['x' => '[0,∞]'],
  103. ['x' => -1],
  104. ],
  105. [
  106. ['x' => '[0,∞]'],
  107. ['x' => -4],
  108. ],
  109. [
  110. ['x' => '[5,∞]'],
  111. ['x' => 4],
  112. ],
  113. [
  114. ['x' => '(0,∞]'],
  115. ['x' => -1],
  116. ],
  117. [
  118. ['x' => '(0,∞]'],
  119. ['x' => -4],
  120. ],
  121. [
  122. ['x' => '(5,∞]'],
  123. ['x' => 4],
  124. ],
  125. ];
  126. }
  127. /**
  128. * @test checkLimits on upper limit
  129. * @dataProvider dataProviderForCheckLimitsUpperLimit
  130. * @param array $limits
  131. * @param array $params
  132. * @throws \Exception
  133. */
  134. public function testCheckLimitsUpperLimit(array $limits, array $params)
  135. {
  136. // When
  137. $withinLimits = Support::checkLimits($limits, $params);
  138. // Then
  139. $this->assertTrue($withinLimits);
  140. }
  141. /**
  142. * @return array
  143. */
  144. public function dataProviderForCheckLimitsUpperLimit(): array
  145. {
  146. return [
  147. [
  148. ['x' => '[0,5]'],
  149. ['x' => 0],
  150. ],
  151. [
  152. ['x' => '[0,5]'],
  153. ['x' => 3],
  154. ],
  155. [
  156. ['x' => '[0,5]'],
  157. ['x' => 5],
  158. ],
  159. [
  160. ['x' => '[0,5)'],
  161. ['x' => 0],
  162. ],
  163. [
  164. ['x' => '[0,5)'],
  165. ['x' => 3],
  166. ],
  167. [
  168. ['x' => '[0,5)'],
  169. ['x' => 4.999],
  170. ],
  171. [
  172. ['x' => '[0,∞]'],
  173. ['x' => 9489859893],
  174. ],
  175. [
  176. ['x' => '[0,∞)'],
  177. ['x' => 9489859893],
  178. ],
  179. [
  180. ['x' => '[0,5]', 'y' => '[0,5]'],
  181. ['x' => 0],
  182. ],
  183. [
  184. ['x' => '[0,5]', 'y' => '[0,5]'],
  185. ['x' => 0, 'y' => 3],
  186. ],
  187. [
  188. ['x' => '[0,5]', 'y' => '[0,5]', 'z' => '[0,5]'],
  189. ['x' => 0, 'y' => 3],
  190. ],
  191. ];
  192. }
  193. /**
  194. * @test checkLimits out of bounds
  195. * @dataProvider dataProviderForCheckLimitsUpperLimitException
  196. * @param array $limits
  197. * @param array $params
  198. * @throws \Exception
  199. */
  200. public function testCheckLimitsUpperLimitException(array $limits, array $params)
  201. {
  202. // Then
  203. $this->expectException(Exception\OutOfBoundsException::class);
  204. // When
  205. Support::checkLimits($limits, $params);
  206. }
  207. /**
  208. * @return array
  209. */
  210. public function dataProviderForCheckLimitsUpperLimitException(): array
  211. {
  212. return [
  213. [
  214. ['x' => '[0,5]'],
  215. ['x' => 5.001],
  216. ],
  217. [
  218. ['x' => '[0,5]'],
  219. ['x' => 6],
  220. ],
  221. [
  222. ['x' => '[0,5]'],
  223. ['x' => 98349389],
  224. ],
  225. [
  226. ['x' => '[0,5)'],
  227. ['x' => 5],
  228. ],
  229. [
  230. ['x' => '[0,5)'],
  231. ['x' => 5.1],
  232. ],
  233. [
  234. ['x' => '[0,5)'],
  235. ['x' => 857385738],
  236. ],
  237. ];
  238. }
  239. /**
  240. * @test checkLimits bad data
  241. * @throws \Exception
  242. */
  243. public function testCheckLimitsLowerLimitEndpointException()
  244. {
  245. // Given
  246. $limits = ['x' => '{0,1)'];
  247. $params = ['x' => 0.5];
  248. // Then
  249. $this->expectException(Exception\BadDataException::class);
  250. // When
  251. Support::checkLimits($limits, $params);
  252. }
  253. /**
  254. * @test checkLimits bad data
  255. * @throws \Exception
  256. */
  257. public function testCheckLimitsUpperLimitEndpointException()
  258. {
  259. // Given
  260. $limits = ['x' => '(0,1}'];
  261. $params = ['x' => 0.5];
  262. // Then
  263. $this->expectException(Exception\BadDataException::class);
  264. // When
  265. Support::checkLimits($limits, $params);
  266. }
  267. /**
  268. * @test checkLimits bad parameter
  269. * @dataProvider dataProviderForCheckLimitsUndefinedParameterException
  270. * @param array $limits
  271. * @param array $params
  272. * @throws \Exception
  273. */
  274. public function testCheckLimitsUndefinedParameterException(array $limits, array $params)
  275. {
  276. // Then
  277. $this->expectException(Exception\BadParameterException::class);
  278. // When
  279. Support::checkLimits($limits, $params);
  280. }
  281. /**
  282. * @return array
  283. */
  284. public function dataProviderForCheckLimitsUndefinedParameterException(): array
  285. {
  286. return [
  287. [
  288. ['x' => '[0,1]'],
  289. ['y' => 0.5],
  290. ],
  291. [
  292. ['x' => '[0,1]', 'a' => '[0,10]'],
  293. ['y' => 0.5],
  294. ],
  295. [
  296. ['x' => '[0,1]', 'a' => '[0,10]'],
  297. ['x' => 0.5, 'b' => 4],
  298. ],
  299. [
  300. ['x' => '[0,1]', 'a' => '[0,10]'],
  301. ['x' => 0.5, 'a' => 4, 'z' => 9],
  302. ],
  303. ];
  304. }
  305. /**
  306. * @test isZero returns true for infinitesimal quantities less than the defined epsilon
  307. * @dataProvider dataProviderForZero
  308. * @param float $x
  309. */
  310. public function testIsZeroTrue(float $x)
  311. {
  312. // When
  313. $isZero = Support::isZero($x);
  314. // Then
  315. $this->assertTrue($isZero);
  316. }
  317. /**
  318. * @test isZero returns false for infinitesimal quantities greater than the defined epsilon
  319. * @dataProvider dataProviderForNotZero
  320. * @param float $x
  321. */
  322. public function testIsZeroFalse(float $x)
  323. {
  324. // When
  325. $isZero = Support::isZero($x);
  326. // Then
  327. $this->assertFalse($isZero);
  328. }
  329. /**
  330. * @test isNotZero returns true for infinitesimal quantities greater than the defined epsilon
  331. * @dataProvider dataProviderForNotZero
  332. * @param float $x
  333. */
  334. public function testIsNotZeroTrue(float $x)
  335. {
  336. // When
  337. $isNotZero = Support::isNotZero($x);
  338. // Then
  339. $this->assertTrue($isNotZero);
  340. }
  341. /**
  342. * @test isNotZero returns false for infinitesimal quantities less than the defined epsilon
  343. * @dataProvider dataProviderForZero
  344. * @param float $x
  345. */
  346. public function testIsNotZeroFalse(float $x)
  347. {
  348. // When
  349. $isNotZero = Support::isNotZero($x);
  350. // Then
  351. $this->assertFalse($isNotZero);
  352. }
  353. /**
  354. * @test isZero is true when setting a specific tolerance
  355. */
  356. public function testIsZeroWithinTolerance()
  357. {
  358. // Given
  359. $x = 0.00000001;
  360. $ε = 0.00000001;
  361. // When
  362. $isZero = Support::isZero($x, $ε);
  363. // Then
  364. $this->assertTrue($isZero);
  365. }
  366. /**
  367. * @test isZero is false when setting a specific tolerance
  368. */
  369. public function testIsZeroOutsideOfTolerance()
  370. {
  371. // Given
  372. $x = 0.00000002;
  373. $ε = 0.00000001;
  374. // When
  375. $isZero = Support::isZero($x, $ε);
  376. // Then
  377. $this->assertFalse($isZero);
  378. }
  379. /**
  380. * @test isNotZero is true when setting a specific tolerance
  381. */
  382. public function testIsNotZeroWithinTolerance()
  383. {
  384. // Given
  385. $x = 0.00000002;
  386. $ε = 0.00000001;
  387. // When
  388. $isZero = Support::isNotZero($x, $ε);
  389. // Then
  390. $this->assertTrue($isZero);
  391. }
  392. /**
  393. * @test isNotZero is false when setting a specific tolerance
  394. */
  395. public function testIsNotZeroOutsideOfTolerance()
  396. {
  397. // Given
  398. $x = 0.00000001;
  399. $ε = 0.00000001;
  400. // When
  401. $isZero = Support::isNotZero($x, $ε);
  402. // Then
  403. $this->assertFalse($isZero);
  404. }
  405. /**
  406. * @return array
  407. */
  408. public function dataProviderForZero(): array
  409. {
  410. return [
  411. [0],
  412. [0.0],
  413. [0.00],
  414. [0.000000000000000000000000000000],
  415. [0.000000000000001],
  416. [0.0000000000000001],
  417. [0.00000000000000001],
  418. [0.000000000000000001],
  419. [0.0000000000000000001],
  420. [0.00000000000000000001],
  421. [0.000000000000000000001],
  422. [0.0000000000000000000001],
  423. [0.00000000000000000000001],
  424. [0.000000000000000000000001],
  425. [-0],
  426. [-0.0],
  427. [-0.00],
  428. [-0.000000000000000000000000000000],
  429. [-0.000000000000001],
  430. [-0.0000000000000001],
  431. [-0.00000000000000001],
  432. [-0.000000000000000001],
  433. [-0.0000000000000000001],
  434. [-0.00000000000000000001],
  435. [-0.000000000000000000001],
  436. [-0.0000000000000000000001],
  437. [-0.00000000000000000000001],
  438. [-0.000000000000000000000001],
  439. ];
  440. }
  441. public function dataProviderForNotZero(): array
  442. {
  443. return [
  444. [1],
  445. [1.0],
  446. [1.00],
  447. [1.000000000000000000000000000000],
  448. [0.00000000002],
  449. [0.0000000001],
  450. [0.000000001],
  451. [0.00000001],
  452. [0.0000001],
  453. [0.000001],
  454. [-1],
  455. [-1.0],
  456. [-1.00],
  457. [-1.000000000000000000000000000000],
  458. [-0.00000000002],
  459. [-0.0000000001],
  460. [-0.000000001],
  461. [-0.00000001],
  462. [-0.0000001],
  463. [-0.000001],
  464. ];
  465. }
  466. /**
  467. * @test isEqual returns true for equal values
  468. * @dataProvider dataProviderForEqualValues
  469. * @param int|float $x
  470. * @param int|float $y
  471. */
  472. public function testIsEqual($x, $y)
  473. {
  474. // When
  475. $isEqual = Support::isEqual($x, $y);
  476. // Then
  477. $this->assertTrue($isEqual);
  478. }
  479. /**
  480. * @test isEqual returns false for unequal values
  481. * @dataProvider dataProviderForUnequalValues
  482. * @param int|float $x
  483. * @param int|float $y
  484. */
  485. public function testIsEqualWhenNotEqual($x, $y)
  486. {
  487. // When
  488. $isEqual = Support::isEqual($x, $y);
  489. // Then
  490. $this->assertFalse($isEqual);
  491. }
  492. /**
  493. * @test isNotEqual returns true for unequal values
  494. * @dataProvider dataProviderForUnequalValues
  495. * @param int|float $x
  496. * @param int|float $y
  497. */
  498. public function testIsNotEqual($x, $y)
  499. {
  500. // When
  501. $isNotEqual = Support::isNotEqual($x, $y);
  502. // Then
  503. $this->assertTrue($isNotEqual);
  504. }
  505. /**
  506. * @test isNotEqual returns false for equal values
  507. * @dataProvider dataProviderForEqualValues
  508. * @param int|float $x
  509. * @param int|float $y
  510. */
  511. public function testIsNotEqualWhenEqual($x, $y)
  512. {
  513. // When
  514. $isNotEqual = Support::isNotEqual($x, $y);
  515. // Then
  516. $this->assertFalse($isNotEqual);
  517. }
  518. /**
  519. * @test isEqual is true when setting a specific tolerance
  520. */
  521. public function testIsEqualWithinTolerance()
  522. {
  523. // Given
  524. $x = 1.000001;
  525. $y = 1.000002;
  526. $ε = 0.000002;
  527. // When
  528. $isEqual = Support::isEqual($x, $y, $ε);
  529. // Then
  530. $this->assertTrue($isEqual);
  531. }
  532. /**
  533. * @test isEqual is false when setting a specific tolerance
  534. */
  535. public function testIsEqualOutsideOfTolerance()
  536. {
  537. // Given
  538. $x = 1.000001;
  539. $y = 1.000002;
  540. $ε = 0.0000009;
  541. // When
  542. $isEqual = Support::isEqual($x, $y, $ε);
  543. // Then
  544. $this->assertFalse($isEqual);
  545. }
  546. /**
  547. * @test isNotEqual is true when setting a specific tolerance
  548. */
  549. public function testIsNotEqualWithinTolerance()
  550. {
  551. // Given
  552. $x = 1.000001;
  553. $y = 1.000002;
  554. $ε = 0.000001;
  555. // When
  556. $isEqual = Support::isNotEqual($x, $y, $ε);
  557. // Then
  558. $this->assertTrue($isEqual);
  559. }
  560. /**
  561. * @test isNotEqual is false when setting a specific tolerance
  562. */
  563. public function testIsNotEqualOutsideOfTolerance()
  564. {
  565. // Given
  566. $x = 1.000001;
  567. $y = 1.000002;
  568. $ε = 0.000002;
  569. // When
  570. $isEqual = Support::isNotEqual($x, $y, $ε);
  571. // Then
  572. $this->assertFalse($isEqual);
  573. }
  574. /**
  575. * @return array
  576. */
  577. public function dataProviderForEqualValues(): array
  578. {
  579. return [
  580. [0, 0],
  581. [1, 1],
  582. [2, 2],
  583. [489837, 489837],
  584. [-1, -1],
  585. [-2, -2],
  586. [-489837, -489837],
  587. [1.1, 1.1],
  588. [4.86, 4.86],
  589. [4.4948739874, 4.4948739874],
  590. [-1.1, -1.1],
  591. [-4.86, -4.86],
  592. [-4.4948739874, -4.4948739874],
  593. [0.01, 0.01],
  594. [0.001, 0.001],
  595. [0.0001, 0.0001],
  596. [0.00001, 0.00001],
  597. [0.000001, 0.000001],
  598. [0.0000001, 0.0000001],
  599. [0.00000001, 0.00000001],
  600. [0.000000001, 0.000000001],
  601. [0.0000000001, 0.0000000001],
  602. [0.00000000001, 0.00000000001],
  603. [0.000000000001, 0.000000000001],
  604. [-0.01, -0.01],
  605. [-0.001, -0.001],
  606. [-0.0001, -0.0001],
  607. [-0.00001, -0.00001],
  608. [-0.000001, -0.000001],
  609. [-0.0000001, -0.0000001],
  610. [-0.00000001, -0.00000001],
  611. [-0.000000001, -0.000000001],
  612. [-0.0000000001, -0.0000000001],
  613. [-0.00000000001, -0.00000000001],
  614. [-0.000000000001, -0.000000000001],
  615. ];
  616. }
  617. /**
  618. * @return array
  619. */
  620. public function dataProviderForUnequalValues(): array
  621. {
  622. return [
  623. [0, 1],
  624. [1, 2],
  625. [2, 3],
  626. [489838, 489837],
  627. [-1, -2],
  628. [-2, -3],
  629. [-489838, -489837],
  630. [1.1, 1.2],
  631. [4.86, 4.87],
  632. [4.4948739876, 4.4948739874],
  633. [-1.1, -1.2],
  634. [-4.86, -4.87],
  635. [-4.4948739873, -4.4948739874],
  636. [0.01, 0.02],
  637. [0.001, 0.002],
  638. [0.0001, 0.0002],
  639. [0.00001, 0.00002],
  640. [0.000001, 0.000002],
  641. [0.0000001, 0.0000002],
  642. [0.00000001, 0.00000002],
  643. [0.000000001, 0.000000002],
  644. [0.0000000001, 0.0000000002],
  645. [0.00000000001, 0.00000000002],
  646. [0.00000000002, 0.00000000003],
  647. [-0.01, -0.02],
  648. [-0.001, -0.002],
  649. [-0.0001, -0.0002],
  650. [-0.00001, -0.00002],
  651. [-0.000001, -0.000002],
  652. [-0.0000001, -0.0000002],
  653. [-0.00000001, -0.00000002],
  654. [-0.000000001, -0.000000002],
  655. [-0.0000000001, -0.0000000002],
  656. [-0.00000000001, -0.00000000002],
  657. [-0.00000000002, -0.00000000003],
  658. ];
  659. }
  660. }