Skip to content
Snippets Groups Projects
Commit 1328764f authored by Taddeus Kroes's avatar Taddeus Kroes
Browse files

Added sum rule for integrals.

parent 808a6241
No related branches found
No related tags found
No related merge requests found
...@@ -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'))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment