Commit 1952f7ba authored by Taddeus Kroes's avatar Taddeus Kroes

Added rules for reducing integrals with constants.

parent 31876fd4
......@@ -24,8 +24,8 @@ from src.rules.derivatives import match_zero_derivative, \
from src.rules.logarithmic import match_constant_logarithm, \
match_add_logarithms, match_raised_base, match_factor_out_exponent, \
match_factor_in_multiplicant
from src.rules.integrals import match_solve_indef, \
match_integrate_variable_power
from src.rules.integrals import match_solve_indef, match_constant_integral, \
match_integrate_variable_power, match_factor_out_constant
RULES = {
OP_ADD: [match_add_numerics, match_add_constant_fractions,
......@@ -55,6 +55,7 @@ RULES = {
match_logarithmic, match_goniometric, match_sum_product_rule,
match_quotient_rule],
OP_LOG: [match_constant_logarithm, match_factor_out_exponent],
OP_INT: [match_integrate_variable_power],
OP_INT: [match_integrate_variable_power, match_constant_integral,
match_factor_out_constant],
OP_INT_INDEF: [match_solve_indef],
}
......@@ -2,7 +2,7 @@ from .utils import find_variables, infinity, replace_variable, find_variable
from .logarithmic import ln
#from .goniometry import sin, cos
from ..node import ExpressionNode as N, ExpressionLeaf as L, OP_INT, \
OP_INT_INDEF
OP_INT_INDEF, OP_MUL, Scope
from ..possibilities import Possibility as P, MESSAGES
from ..translate import _
......@@ -82,7 +82,7 @@ def solve_indef(root, args):
def match_integrate_variable_power(node):
"""
int x ^ n dx -> x ^ (n + 1) / (n + 1) + c
int x ^ n dx -> x ^ (n + 1) / (n + 1)
int g ^ x dx -> g ^ x / ln(g)
"""
assert node.is_op(OP_INT)
......@@ -103,7 +103,7 @@ def match_integrate_variable_power(node):
def integrate_variable_root(root, args):
"""
int x ^ n dx -> x ^ (n + 1) / (n + 1) + c
int x ^ n dx -> x ^ (n + 1) / (n + 1)
"""
x, n = root[0]
......@@ -125,3 +125,64 @@ def integrate_variable_exponent(root, args):
MESSAGES[integrate_variable_exponent] = \
_('Apply standard integral int(g ^ x) = g ^ x / ln(g) + c.')
def match_constant_integral(node):
"""
int c dx -> cx
"""
assert node.is_op(OP_INT)
fx, x = node[:2]
if not fx.contains(x):
return [P(node, constant_integral)]
return []
def constant_integral(root, args):
"""
int c dx -> cx
"""
c, x = root[:2]
return solve_integral(root, c * x)
MESSAGES[constant_integral] = _('{0[0]} does not contain {0[1]}, so its ' \
'integral over {0[1]} is its multiplication with {0[1]}.')
def match_factor_out_constant(node):
"""
int cf(x) dx -> c int f(x) dx
"""
assert node.is_op(OP_INT)
fx, x = node[:2]
if not fx.is_op(OP_MUL):
return []
p = []
scope = Scope(fx)
for n in scope:
if not n.contains(x):
p.append(P(node, factor_out_constant, (scope, n)))
return p
def factor_out_constant(root, args):
"""
int cf(x) dx -> c int f(x) dx
"""
scope, c = args
scope.remove(c)
return c * integral(scope.as_nary_node(), *root[1:])
MESSAGES[factor_out_constant] = _('Factor out {2} from integral {0}.')
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
integrate_variable_root, integrate_variable_exponent, \
match_constant_integral, constant_integral, \
match_factor_out_constant, factor_out_constant
from src.rules.logarithmic import ln
#from .goniometry import sin, cos
from src.node import Scope
from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree
......@@ -52,3 +55,27 @@ class TestRulesIntegrals(RulesTestCase):
def test_integrate_variable_exponent(self):
root, expect = tree('int g ^ x, g ^ x / ln(g) + c')
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)])
def test_constant_integral(self):
root, expect = tree('int 2, 2x + c')
self.assertEqual(constant_integral(root, ()), expect)
root, expect = tree('int_0^4 2, [2x + c]_0^4')
self.assertEqual(constant_integral(root, ()), expect)
def test_match_factor_out_constant(self):
root, c, cx = tree('int cx dx, c, cx')
self.assertEqualPos(match_factor_out_constant(root),
[P(root, factor_out_constant, (Scope(cx), c))])
def test_factor_out_constant(self):
root, expect = tree('int cx2 dx, c int x2 dx')
c, x2 = cx2 = root[0]
self.assertEqual(factor_out_constant(root, (Scope(cx2), c)), expect)
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