ThreePointFormulaTest.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <?php
  2. namespace MathPHP\Tests\NumericalAnalysis\NumericalDifferentiation;
  3. use MathPHP\NumericalAnalysis\NumericalDifferentiation\ThreePointFormula;
  4. class ThreePointFormulaTest extends \PHPUnit\Framework\TestCase
  5. {
  6. /**
  7. * @test differentiate zero error using callback - Check that the endpoint/midpoint/backward endpoint formula agrees with f'(x) at x = $_
  8. * @dataProvider dataProviderForTestDifferentiateZeroError
  9. * @param int $x
  10. * @throws \Exception
  11. *
  12. * f(x) = 13x² -92x + 96
  13. * f’(x) = 26x - 92
  14. *
  15. * h²
  16. * Error term for the Midpoint Formula: - f⁽³⁾(ζ₁)
  17. * 6
  18. *
  19. * where ζ₁ lies between x₀ - h and x₀ + h
  20. *
  21. * h²
  22. * Error term for the Endpoint Formula: - f⁽³⁾(ζ₀)
  23. * 3
  24. *
  25. * where ζ₀ lies between x₀ and x₀ + 2h
  26. *
  27. * f'(x) = 26x - 92
  28. * f''(x) = 26
  29. * f⁽³⁾(x) = 0
  30. * Thus, our error is zero in both formulas for our function $f
  31. */
  32. public function testDifferentiateZeroError(int $x)
  33. {
  34. // Given f(x) = 13x² -92x + 96
  35. $f = function ($x) {
  36. return 13 * $x ** 2 - 92 * $x + 96;
  37. };
  38. // And f’(x) = 26x - 92
  39. $f’ = function ($x) {
  40. return 26 * $x - 92;
  41. };
  42. $expected = $f’($x);
  43. // And
  44. $n = 3;
  45. $a = 0;
  46. $b = 4;
  47. // When
  48. $actual = ThreePointFormula::differentiate($x, $f, $a, $b, $n);
  49. // Then
  50. $this->assertEquals($expected, $actual);
  51. }
  52. /**
  53. * @return array (x)
  54. */
  55. public function dataProviderForTestDifferentiateZeroError(): array
  56. {
  57. return [
  58. [0], // Check that the endpoint formula agrees with f'(x) at x = 0
  59. [2], // Check that the midpoint formula agrees with f'(x) at x = 2
  60. [4], // Check that the (backward) endpoint formula agrees with f'(x) at x = 4
  61. ];
  62. }
  63. /**
  64. * @test differentiate non-zero error using callback - Check that the endpoint/midpoint/backward endpoint formula agrees with f'(x) at x = $_
  65. * @dataProvider dataProviderForTestDifferentiateNonZeroError
  66. * @param int $x
  67. * @param int $tol
  68. * @throws \Exception
  69. *
  70. * f(x) = x³ - 13x² -92x + 96
  71. * f'(x) = 3x² - 26x - 92
  72. *
  73. * h²
  74. * Error term for the Midpoint Formula: - f⁽³⁾(ζ₁)
  75. * 6
  76. *
  77. * where ζ₁ lies between x₀ - h and x₀ + h
  78. *
  79. * h²
  80. * Error term for the Endpoint Formula: - f⁽³⁾(ζ₀)
  81. * 3
  82. *
  83. * where ζ₀ lies between x₀ and x₀ + 2h
  84. *
  85. * f(x) = x³ - 13x² -92x + 96
  86. * f'(x) = 3x² - 26x - 92
  87. * f⁽³⁾(x) = 6
  88. * Error in Midpoint Formula on [0,2] (where h=1) < 1
  89. * Error in Endpoint Formula on [0,2] (where h=1) < 2
  90. */
  91. public function testDifferentiateNonZeroError(int $x, int $tol)
  92. {
  93. // Given f(x) = x³ - 13x² -92x + 96
  94. $f = function ($x) {
  95. return $x ** 3 - 13 * $x ** 2 - 92 * $x + 96;
  96. };
  97. // And
  98. $f’ = function ($x) {
  99. return 3 * $x ** 2 - 26 * $x - 92;
  100. };
  101. $expected = $f’($x);
  102. // And
  103. $n = 3;
  104. $a = 0;
  105. $b = 2;
  106. // When
  107. $actual = ThreePointFormula::differentiate($x, $f, $a, $b, $n);
  108. // Then
  109. $this->assertEqualsWithDelta($expected, $actual, $tol);
  110. }
  111. /**
  112. * @return array (x, tol)
  113. */
  114. public function dataProviderForTestDifferentiateNonZeroError(): array
  115. {
  116. return [
  117. [0, 2],
  118. [1, 1],
  119. [2, 2],
  120. ];
  121. }
  122. /**
  123. * @test differentiate zero error using array of points - Check that the endpoint/midpoint/backward endpoint formula agrees with f'(x) at x = $_
  124. * @dataProvider dataProviderForTestDifferentiateZeroError
  125. * @param int $x
  126. * @throws \Exception
  127. *
  128. * f(x) = 13x² -92x + 96
  129. * f’(x) = 26x - 92
  130. *
  131. * h²
  132. * Error term for the Midpoint Formula: - f⁽³⁾(ζ₁)
  133. * 6
  134. *
  135. * where ζ₁ lies between x₀ - h and x₀ + h
  136. *
  137. * h²
  138. * Error term for the Endpoint Formula: - f⁽³⁾(ζ₀)
  139. * 3
  140. *
  141. * where ζ₀ lies between x₀ and x₀ + 2h
  142. *
  143. * f'(x) = 26x - 92
  144. * f''(x) = 26
  145. * f⁽³⁾(x) = 0
  146. * Thus, our error is zero in both formulas for our function $f
  147. */
  148. public function testDifferentiateZeroErrorUsingPoints(int $x)
  149. {
  150. // Given f(x) = 13x² -92x + 96
  151. $f = function ($x) {
  152. return 13 * $x ** 2 - 92 * $x + 96;
  153. };
  154. $points = [[0, $f(0)], [2, $f(2)], [4, $f(4)]];
  155. // And f’(x) = 26x - 92
  156. $f’ = function ($x) {
  157. return 26 * $x - 92;
  158. };
  159. $expected = $f’($x);
  160. // When
  161. $actual = ThreePointFormula::differentiate($x, $points);
  162. // Then
  163. $this->assertEquals($expected, $actual);
  164. }
  165. }