HypergeometricTest.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. namespace MathPHP\Tests\Probability\Distribution\Multivariate;
  3. use MathPHP\Probability\Distribution\Multivariate\Hypergeometric;
  4. use MathPHP\Exception;
  5. class HypergeometricTest extends \PHPUnit\Framework\TestCase
  6. {
  7. /**
  8. * @test pmf
  9. * @dataProvider dataProviderForTestHypergeometric
  10. */
  11. public function testHypergeometric(array $quantities, array $picks, $expected)
  12. {
  13. $dist = new Hypergeometric($quantities);
  14. $this->assertEqualsWithDelta($expected, $dist->pmf($picks), 0.00000001);
  15. }
  16. /**
  17. * Test data created with R (extraDistr) dmvhyper(picks, quantities, numOfPicks)
  18. * Example: dmvhyper(c(2,2,2), c(5,10,15), 6)
  19. * @return array
  20. */
  21. public function dataProviderForTestHypergeometric()
  22. {
  23. return [
  24. [
  25. [15, 10, 15],
  26. [2, 2, 2],
  27. 496125 / 3838380,
  28. ],
  29. [
  30. [5, 10, 15],
  31. [2, 2, 2],
  32. 47250 / 593775,
  33. ],
  34. [
  35. [5, 10, 15],
  36. [2, 4, 0],
  37. 0.003536693,
  38. ],
  39. [
  40. [5, 10, 15],
  41. [2, 0, 4],
  42. 0.02298851,
  43. ],
  44. [
  45. [5, 10, 15],
  46. [4, 0, 2],
  47. 0.0008841733,
  48. ],
  49. [
  50. [1, 1, 1],
  51. [1, 1, 1],
  52. 1,
  53. ],
  54. [
  55. [1, 1, 1],
  56. [1, 1, 0],
  57. 1 / 3,
  58. ],
  59. [
  60. [1, 1, 1],
  61. [1, 0, 1],
  62. 1 / 3,
  63. ],
  64. [
  65. [1, 1, 1],
  66. [0, 1, 1],
  67. 1 / 3,
  68. ],
  69. [
  70. [14, 11, 50],
  71. [4, 5, 31],
  72. 0.004778598,
  73. ],
  74. ];
  75. }
  76. /**
  77. * @test __construct
  78. * @dataProvider dataProviderForConstructorExceptions
  79. */
  80. public function testConstructorException($quantities)
  81. {
  82. $this->expectException(Exception\BadDataException::class);
  83. $dist = new Hypergeometric($quantities);
  84. }
  85. /**
  86. * @return array
  87. */
  88. public function dataProviderForConstructorExceptions()
  89. {
  90. return [
  91. 'float' => [
  92. [1.5, 1, 6],
  93. ],
  94. 'string' => [
  95. [10, 'k', 6],
  96. ],
  97. 'empty' => [
  98. [],
  99. ],
  100. ];
  101. }
  102. /**
  103. * @test pmf
  104. * @dataProvider dataProviderForPmfExceptions
  105. */
  106. public function testPmfException($ks)
  107. {
  108. $this->expectException(Exception\BadDataException::class);
  109. $dist = new Hypergeometric([10, 10, 10]);
  110. $prob = $dist->pmf($ks);
  111. }
  112. /**
  113. * @return array
  114. */
  115. public function dataProviderForPmfExceptions()
  116. {
  117. return [
  118. 'float' => [
  119. [.5, 1, 6],
  120. ],
  121. 'string' => [
  122. [10, 'k', 6],
  123. ],
  124. 'mismatched' => [
  125. [-1, 6],
  126. ],
  127. ];
  128. }
  129. /**
  130. * @test pmf, __construct
  131. * @dataProvider dataProviderForBoundsExceptions
  132. */
  133. public function testBoundsExceptions($Ks, $ks)
  134. {
  135. $this->expectException(Exception\OutOfBoundsException::class);
  136. $dist = new Hypergeometric($Ks);
  137. $prob = $dist->pmf($ks);
  138. }
  139. /**
  140. * @return array
  141. */
  142. public function dataProviderForBoundsExceptions()
  143. {
  144. return [
  145. 'K too small' => [
  146. [0, 10, 6],
  147. [0, 2, 2]
  148. ],
  149. 'k too small' => [
  150. [5, 10, 15],
  151. [-1, 2, 2],
  152. ],
  153. 'k too big' => [
  154. [5, 10, 15],
  155. [6, 2, 2],
  156. ],
  157. ];
  158. }
  159. }