test_rules_integrals.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. from src.rules.integrals import indef, choose_constant, solve_integral, \
  2. match_solve_indef, solve_indef, match_integrate_variable_power, \
  3. integrate_variable_root, integrate_variable_exponent, \
  4. match_constant_integral, constant_integral, single_variable_integral, \
  5. match_factor_out_constant, split_negation_to_constant, \
  6. factor_out_constant, match_division_integral, division_integral, \
  7. extend_division_integral, match_function_integral, \
  8. logarithm_integral, sinus_integral, cosinus_integral, \
  9. match_sum_rule_integral, sum_rule_integral
  10. from src.node import Scope
  11. from src.possibilities import Possibility as P
  12. from tests.rulestestcase import RulesTestCase, tree
  13. class TestRulesIntegrals(RulesTestCase):
  14. def test_choose_constant(self):
  15. a, b, c = tree('a, b, c')
  16. self.assertEqual(choose_constant(tree('int x ^ n')), c)
  17. self.assertEqual(choose_constant(tree('int x ^ c')), a)
  18. self.assertEqual(choose_constant(tree('int a ^ c da')), b)
  19. def test_match_solve_indef(self):
  20. root = tree('[x ^ 2]_a^b')
  21. self.assertEqualPos(match_solve_indef(root), [P(root, solve_indef)])
  22. def test_solve_integral(self):
  23. root, F, Fc = tree('int x ^ 2 dx, 1 / 3 x ^ 3, 1 / 3 x ^ 3 + c')
  24. self.assertEqual(solve_integral(root, F), Fc)
  25. x2, x, a, b = root = tree('int_a^b x ^ 2 dx')
  26. self.assertEqual(solve_integral(root, F), indef(Fc, a, b))
  27. def test_solve_integral_skip_indef(self):
  28. root, x, c, l1 = tree('int_a^b y ^ x dy, x, c, 1')
  29. F = tree('1 / (x + 1)y ^ (x + 1)')
  30. y, a, b = root[1:4]
  31. Fx = lambda y: l1 / (x + 1) * y ** (x + 1) + c
  32. self.assertEqual(solve_integral(root, F), Fx(b) - Fx(a))
  33. def test_solve_indef(self):
  34. root, expect = tree('[x ^ 2]_a^b, b ^ 2 - a ^ 2')
  35. self.assertEqual(solve_indef(root, ()), expect)
  36. def test_match_integrate_variable_power(self):
  37. root = tree('int x ^ n')
  38. self.assertEqualPos(match_integrate_variable_power(root),
  39. [P(root, integrate_variable_root)])
  40. root = tree('int x ^ n')
  41. self.assertEqualPos(match_integrate_variable_power(root),
  42. [P(root, integrate_variable_root)])
  43. root = tree('int -x ^ n')
  44. self.assertEqualPos(match_integrate_variable_power(root), [])
  45. for root in tree('int g ^ x, int g ^ x'):
  46. self.assertEqualPos(match_integrate_variable_power(root),
  47. [P(root, integrate_variable_exponent)])
  48. def test_integrate_variable_root(self):
  49. root, expect = tree('int x ^ n, 1 / (n + 1) * x ^ (n + 1) + c')
  50. self.assertEqual(integrate_variable_root(root, ()), expect)
  51. def test_integrate_variable_exponent(self):
  52. root, expect = tree('int g ^ x, g ^ x / ln(g) + c')
  53. self.assertEqual(integrate_variable_exponent(root, ()), expect)
  54. def test_match_constant_integral(self):
  55. root = tree('int x dx')
  56. self.assertEqualPos(match_constant_integral(root),
  57. [P(root, single_variable_integral)])
  58. root = tree('int 2')
  59. self.assertEqualPos(match_constant_integral(root),
  60. [P(root, constant_integral)])
  61. root = tree('int c dx')
  62. self.assertEqualPos(match_constant_integral(root),
  63. [P(root, constant_integral)])
  64. def test_single_variable_integral(self):
  65. root, expect = tree('int x, int x ^ 1')
  66. self.assertEqual(single_variable_integral(root, ()), expect)
  67. def test_constant_integral(self):
  68. root, expect = tree('int 2, 2x + c')
  69. self.assertEqual(constant_integral(root, ()), expect)
  70. root, expect = tree('int_0^4 2, [2x + c]_0^4')
  71. self.assertEqual(constant_integral(root, ()), expect)
  72. def test_match_factor_out_constant(self):
  73. root, c, cx = tree('int cx dx, c, cx')
  74. self.assertEqualPos(match_factor_out_constant(root),
  75. [P(root, factor_out_constant, (Scope(cx), c))])
  76. root = tree('int -x2 dx')
  77. self.assertEqualPos(match_factor_out_constant(root),
  78. [P(root, split_negation_to_constant)])
  79. def test_split_negation_to_constant(self):
  80. root, expect = tree('int -x ^ 2 dx, int (-1)x ^ 2 dx')
  81. self.assertEqual(split_negation_to_constant(root, ()), expect)
  82. def test_factor_out_constant(self):
  83. root, expect = tree('int cx dx, c int x dx')
  84. c, x2 = cx2 = root[0]
  85. self.assertEqual(factor_out_constant(root, (Scope(cx2), c)), expect)
  86. def test_match_division_integral(self):
  87. root0, root1 = tree('int 1 / x, int 2 / x')
  88. self.assertEqualPos(match_division_integral(root0),
  89. [P(root0, division_integral)])
  90. self.assertEqualPos(match_division_integral(root1),
  91. [P(root1, extend_division_integral)])
  92. def test_division_integral(self):
  93. root, expect = tree('int 1 / x dx, ln|x| + c')
  94. self.assertEqual(division_integral(root, ()), expect)
  95. def test_extend_division_integral(self):
  96. root, expect = tree('int a / x dx, int a(1 / x) dx')
  97. self.assertEqual(extend_division_integral(root, ()), expect)
  98. def test_match_division_integral_chain(self):
  99. self.assertRewrite([
  100. 'int a / x',
  101. 'int a * 1 / x dx',
  102. 'aint 1 / x dx',
  103. 'a(ln|x| + c)',
  104. 'aln|x| + ac',
  105. # FIXME: 'aln|x| + c', # ac -> c
  106. ])
  107. def test_match_function_integral(self):
  108. root = tree('int ln x')
  109. self.assertEqualPos(match_function_integral(root),
  110. [P(root, logarithm_integral)])
  111. root = tree('int sin x')
  112. self.assertEqualPos(match_function_integral(root),
  113. [P(root, sinus_integral)])
  114. root = tree('int cos x')
  115. self.assertEqualPos(match_function_integral(root),
  116. [P(root, cosinus_integral)])
  117. root = tree('int sqrt x')
  118. self.assertEqualPos(match_function_integral(root), [])
  119. def test_logarithm_integral(self):
  120. root, expect = tree('int ln x, (xlnx - x) / ln e + c')
  121. self.assertEqual(logarithm_integral(root, ()), expect)
  122. def test_sinus_integral(self):
  123. root, expect = tree('int sin x, -cos x + c')
  124. self.assertEqual(sinus_integral(root, ()), expect)
  125. def test_cosinus_integral(self):
  126. root, expect = tree('int cos x, sin x + c')
  127. self.assertEqual(cosinus_integral(root, ()), expect)
  128. def test_match_sum_rule_integral(self):
  129. (f, g), x = root = tree('int 2x + 3x dx')
  130. self.assertEqualPos(match_sum_rule_integral(root),
  131. [P(root, sum_rule_integral, (Scope(root[0]), f))])
  132. ((f, g), h), x = root = tree('int 2x + 3x + 4x dx')
  133. self.assertEqualPos(match_sum_rule_integral(root),
  134. [P(root, sum_rule_integral, (Scope(root[0]), f)),
  135. P(root, sum_rule_integral, (Scope(root[0]), g)),
  136. P(root, sum_rule_integral, (Scope(root[0]), h))])
  137. def test_sum_rule_integral(self):
  138. ((f, g), h), x = root = tree('int 2x + 3x + 4x dx')
  139. self.assertEqual(sum_rule_integral(root, (Scope(root[0]), f)),
  140. tree('int 2x dx + int 3x + 4x dx'))
  141. self.assertEqual(sum_rule_integral(root, (Scope(root[0]), g)),
  142. tree('int 3x dx + int 2x + 4x dx'))
  143. self.assertEqual(sum_rule_integral(root, (Scope(root[0]), h)),
  144. tree('int 4x dx + int 2x + 3x dx'))