Commit a7a2bfaa authored by Taddeus Kroes's avatar Taddeus Kroes

Added/improved some simple rules for integrals.

parent 427c18a5
......@@ -73,7 +73,7 @@ def match_integrate_variable_power(node):
f, x = node[:2]
if f.is_power():
if f.is_power() and not f.negated:
root, exponent = f
if root == x and not exponent.contains(x):
......@@ -113,18 +113,33 @@ MESSAGES[integrate_variable_exponent] = \
def match_constant_integral(node):
"""
int x dx -> int x ^ 1 dx # -> x ^ 2 / 2 + c
int c dx -> cx
"""
assert node.is_op(OP_INT)
fx, x = node[:2]
if fx == x:
return [P(node, single_variable_integral)]
if not fx.contains(x):
return [P(node, constant_integral)]
return []
def single_variable_integral(root, args):
"""
int x dx -> int x ^ 1 dx # -> x ^ 2 / 2 + c
"""
return integral(root[0] ** 1, *root[1:])
MESSAGES[single_variable_integral] = _('Rewrite {0[0]} to {0[0]} ^ 1 and ' \
'apply the standard integral for {0[0]} ^ n.')
def constant_integral(root, args):
"""
int c dx -> cx
......@@ -141,11 +156,15 @@ MESSAGES[constant_integral] = _('{0[0]} does not contain {0[1]}, so its ' \
def match_factor_out_constant(node):
"""
int cf(x) dx -> c int f(x) dx
int -f(x) dx -> -1 int f(x) dx
"""
assert node.is_op(OP_INT)
fx, x = node[:2]
if fx.negated:
return [P(node, split_negation_to_constant)]
if not fx.is_op(OP_MUL):
return []
......@@ -159,6 +178,17 @@ def match_factor_out_constant(node):
return p
def split_negation_to_constant(root, args):
"""
int -f(x) dx -> int -1 * f(x) dx # =>* -int f(x) dx
"""
return integral(-L(1) * root[0].reduce_negation(), *root[1:])
MESSAGES[split_negation_to_constant] = _('Write the negation of {0[0]} as an' \
' explicit -1 and bring it outside of the integral.')
def factor_out_constant(root, args):
"""
int cf(x) dx -> c int f(x) dx
......
from src.rules.integrals import indef, choose_constant, solve_integral, \
match_solve_indef, solve_indef, match_integrate_variable_power, \
integrate_variable_root, integrate_variable_exponent, \
match_constant_integral, constant_integral, \
match_factor_out_constant, factor_out_constant, \
match_division_integral, division_integral, extend_division_integral, \
match_function_integral, logarithm_integral, sinus_integral, \
cosinus_integral
match_constant_integral, constant_integral, single_variable_integral, \
match_factor_out_constant, split_negation_to_constant, \
factor_out_constant, match_division_integral, division_integral, \
extend_division_integral, match_function_integral, \
logarithm_integral, sinus_integral, cosinus_integral
from src.node import Scope
from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree
......@@ -41,9 +41,16 @@ class TestRulesIntegrals(RulesTestCase):
self.assertEqual(solve_indef(root, ()), expect)
def test_match_integrate_variable_power(self):
for root in tree('int x ^ n, int x ^ n'):
self.assertEqualPos(match_integrate_variable_power(root),
[P(root, integrate_variable_root)])
root = tree('int x ^ n')
self.assertEqualPos(match_integrate_variable_power(root),
[P(root, integrate_variable_root)])
root = tree('int x ^ n')
self.assertEqualPos(match_integrate_variable_power(root),
[P(root, integrate_variable_root)])
root = tree('int -x ^ n')
self.assertEqualPos(match_integrate_variable_power(root), [])
for root in tree('int g ^ x, int g ^ x'):
self.assertEqualPos(match_integrate_variable_power(root),
......@@ -58,11 +65,21 @@ class TestRulesIntegrals(RulesTestCase):
self.assertEqual(integrate_variable_exponent(root, ()), expect)
def test_match_constant_integral(self):
root0, root1 = tree('int 2, int c dx')
self.assertEqualPos(match_constant_integral(root0),
[P(root0, constant_integral)])
self.assertEqualPos(match_constant_integral(root1),
[P(root1, constant_integral)])
root = tree('int x dx')
self.assertEqualPos(match_constant_integral(root),
[P(root, single_variable_integral)])
root = tree('int 2')
self.assertEqualPos(match_constant_integral(root),
[P(root, constant_integral)])
root = tree('int c dx')
self.assertEqualPos(match_constant_integral(root),
[P(root, constant_integral)])
def test_single_variable_integral(self):
root, expect = tree('int x, int x ^ 1')
self.assertEqual(single_variable_integral(root, ()), expect)
def test_constant_integral(self):
root, expect = tree('int 2, 2x + c')
......@@ -76,6 +93,14 @@ class TestRulesIntegrals(RulesTestCase):
self.assertEqualPos(match_factor_out_constant(root),
[P(root, factor_out_constant, (Scope(cx), c))])
root = tree('int -x2 dx')
self.assertEqualPos(match_factor_out_constant(root),
[P(root, split_negation_to_constant)])
def test_split_negation_to_constant(self):
root, expect = tree('int -x2 dx, int -1x2 dx')
self.assertEqual(split_negation_to_constant(root, ()), expect)
def test_factor_out_constant(self):
root, expect = tree('int cx2 dx, c int x2 dx')
c, x2 = cx2 = root[0]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment