Commit 1328764f authored by Taddeus Kroes's avatar Taddeus Kroes

Added sum rule for integrals.

parent 808a6241
...@@ -25,7 +25,8 @@ from .logarithmic import match_constant_logarithm, \ ...@@ -25,7 +25,8 @@ from .logarithmic import match_constant_logarithm, \
match_factor_in_multiplicant, match_expand_terms match_factor_in_multiplicant, match_expand_terms
from .integrals import match_solve_indef, match_constant_integral, \ from .integrals import match_solve_indef, match_constant_integral, \
match_integrate_variable_power, match_factor_out_constant, \ match_integrate_variable_power, match_factor_out_constant, \
match_division_integral, match_function_integral match_division_integral, match_function_integral, \
match_sum_rule_integral
from .lineq import match_move_term from .lineq import match_move_term
from .absolute import match_factor_out_abs_term from .absolute import match_factor_out_abs_term
...@@ -60,7 +61,7 @@ RULES = { ...@@ -60,7 +61,7 @@ RULES = {
match_expand_terms], match_expand_terms],
OP_INT: [match_integrate_variable_power, match_constant_integral, OP_INT: [match_integrate_variable_power, match_constant_integral,
match_factor_out_constant, match_division_integral, match_factor_out_constant, match_division_integral,
match_function_integral], match_function_integral, match_sum_rule_integral],
OP_INT_INDEF: [match_solve_indef], OP_INT_INDEF: [match_solve_indef],
OP_EQ: [match_move_term], OP_EQ: [match_move_term],
OP_ABS: [match_factor_out_abs_term], OP_ABS: [match_factor_out_abs_term],
......
from .utils import find_variables, substitute, find_variable from .utils import find_variables, substitute, find_variable
from ..node import ExpressionLeaf as L, OP_INT, OP_INT_INDEF, OP_MUL, OP_DIV, \ from ..node import ExpressionLeaf as L, OP_INT, OP_INT_INDEF, OP_MUL, OP_DIV, \
OP_LOG, OP_SIN, OP_COS, Scope, sin, cos, ln, integral, indef, absolute OP_LOG, OP_SIN, OP_COS, Scope, sin, cos, ln, integral, indef, \
absolute, OP_ADD
from ..possibilities import Possibility as P, MESSAGES from ..possibilities import Possibility as P, MESSAGES
from ..translate import _ from ..translate import _
...@@ -307,3 +308,36 @@ def cosinus_integral(root, args): ...@@ -307,3 +308,36 @@ def cosinus_integral(root, args):
MESSAGES[cosinus_integral] = \ MESSAGES[cosinus_integral] = \
_('{0[0]} has the standard anti-derivative sin({0[0][0]}) + c.') _('{0[0]} has the standard anti-derivative sin({0[0][0]}) + c.')
def match_sum_rule_integral(node):
"""
int f(x) + g(x) dx -> int f(x) dx + int g(x) dx
"""
assert node.is_op(OP_INT)
if not node[0].is_op(OP_ADD):
return []
p = []
scope = Scope(node[0])
if len(scope) == 2:
return [P(node, sum_rule_integral, (scope, scope[0]))]
return [P(node, sum_rule_integral, (scope, n)) for n in scope]
def sum_rule_integral(root, args):
"""
int f(x) + g(x) dx -> int f(x) dx + int g(x) dx
"""
scope, f = args
x = root[1]
scope.remove(f)
addition = integral(f, x) + integral(scope.as_nary_node(), x)
return addition.negate(root.negated)
MESSAGES[sum_rule_integral] = _('Apply the sum rule to {0}.')
...@@ -5,7 +5,8 @@ from src.rules.integrals import indef, choose_constant, solve_integral, \ ...@@ -5,7 +5,8 @@ from src.rules.integrals import indef, choose_constant, solve_integral, \
match_factor_out_constant, split_negation_to_constant, \ match_factor_out_constant, split_negation_to_constant, \
factor_out_constant, match_division_integral, division_integral, \ factor_out_constant, match_division_integral, division_integral, \
extend_division_integral, match_function_integral, \ extend_division_integral, match_function_integral, \
logarithm_integral, sinus_integral, cosinus_integral logarithm_integral, sinus_integral, cosinus_integral, \
match_sum_rule_integral, sum_rule_integral
from src.node import Scope from src.node import Scope
from src.possibilities import Possibility as P from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree from tests.rulestestcase import RulesTestCase, tree
...@@ -158,3 +159,23 @@ class TestRulesIntegrals(RulesTestCase): ...@@ -158,3 +159,23 @@ class TestRulesIntegrals(RulesTestCase):
def test_cosinus_integral(self): def test_cosinus_integral(self):
root, expect = tree('int cos x, sin x + c') root, expect = tree('int cos x, sin x + c')
self.assertEqual(cosinus_integral(root, ()), expect) self.assertEqual(cosinus_integral(root, ()), expect)
def test_match_sum_rule_integral(self):
(f, g), x = root = tree('int 2x + 3x dx')
self.assertEqualPos(match_sum_rule_integral(root),
[P(root, sum_rule_integral, (Scope(root[0]), f))])
((f, g), h), x = root = tree('int 2x + 3x + 4x dx')
self.assertEqualPos(match_sum_rule_integral(root),
[P(root, sum_rule_integral, (Scope(root[0]), f)),
P(root, sum_rule_integral, (Scope(root[0]), g)),
P(root, sum_rule_integral, (Scope(root[0]), h))])
def test_sum_rule_integral(self):
((f, g), h), x = root = tree('int 2x + 3x + 4x dx')
self.assertEqual(sum_rule_integral(root, (Scope(root[0]), f)),
tree('int 2x dx + int 3x + 4x dx'))
self.assertEqual(sum_rule_integral(root, (Scope(root[0]), g)),
tree('int 3x dx + int 2x + 4x dx'))
self.assertEqual(sum_rule_integral(root, (Scope(root[0]), h)),
tree('int 4x dx + int 2x + 3x dx'))
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