Commit 3cfe9c2e authored by Taddeus Kroes's avatar Taddeus Kroes

Added integral rules for functions and fractions.

parent fa682fe0
...@@ -26,7 +26,7 @@ from src.rules.logarithmic import match_constant_logarithm, \ ...@@ -26,7 +26,7 @@ from src.rules.logarithmic import match_constant_logarithm, \
match_factor_in_multiplicant match_factor_in_multiplicant
from src.rules.integrals import match_solve_indef, match_constant_integral, \ from src.rules.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_division_integral, match_function_integral
RULES = { RULES = {
OP_ADD: [match_add_numerics, match_add_constant_fractions, OP_ADD: [match_add_numerics, match_add_constant_fractions,
...@@ -57,6 +57,7 @@ RULES = { ...@@ -57,6 +57,7 @@ RULES = {
match_quotient_rule], match_quotient_rule],
OP_LOG: [match_constant_logarithm, match_factor_out_exponent], OP_LOG: [match_constant_logarithm, match_factor_out_exponent],
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],
OP_INT_INDEF: [match_solve_indef], OP_INT_INDEF: [match_solve_indef],
} }
from .utils import find_variables, infinity, replace_variable, find_variable, \ from .utils import find_variables, infinity, replace_variable, find_variable, \
absolute absolute
from .logarithmic import ln from .logarithmic import ln
#from .goniometry import sin, cos from .goniometry import sin, cos
from ..node import ExpressionNode as N, ExpressionLeaf as L, OP_INT, \ from ..node import ExpressionNode as N, ExpressionLeaf as L, OP_INT, \
OP_INT_INDEF, OP_MUL, OP_DIV, Scope OP_INT_INDEF, OP_MUL, OP_DIV, OP_LOG, OP_SIN, OP_COS, Scope
from ..possibilities import Possibility as P, MESSAGES from ..possibilities import Possibility as P, MESSAGES
from ..translate import _ from ..translate import _
...@@ -215,7 +215,7 @@ def division_integral(root, args): ...@@ -215,7 +215,7 @@ def division_integral(root, args):
MESSAGES[division_integral] = \ MESSAGES[division_integral] = \
_('1 / {0[1]} has the standard ant-derivative ln|{0[1]}|.') _('1 / {0[1]} has the standard anti-derivative ln|{0[1]}| + c.')
def extend_division_integral(root, args): def extend_division_integral(root, args):
...@@ -229,3 +229,63 @@ def extend_division_integral(root, args): ...@@ -229,3 +229,63 @@ def extend_division_integral(root, args):
MESSAGES[extend_division_integral] = _('Bring nominator {0[0][0]} out of the' \ MESSAGES[extend_division_integral] = _('Bring nominator {0[0][0]} out of the' \
' fraction to obtain a standard 1 / {0[0][1]} integral.') ' fraction to obtain a standard 1 / {0[0][1]} integral.')
def match_function_integral(node):
"""
int log_g(x) dx -> (xln(x) - x) / log_g(x)
int sin(x) dx -> -cos(x)
int cos(x) dx -> sin(x)
"""
assert node.is_op(OP_INT)
fx, x = node[:2]
if fx.is_leaf or fx[0] != x:
return []
if fx.op == OP_LOG:
return [P(node, logarithm_integral)]
if fx.op == OP_SIN:
return [P(node, sinus_integral)]
if fx.op == OP_COS:
return [P(node, cosinus_integral)]
return []
def logarithm_integral(root, args):
"""
int log_g(x) dx -> (xln(x) - x) / log_g(x)
"""
x, g = root[0]
return solve_integral(root, (x * ln(x) - x) / ln(g))
MESSAGES[logarithm_integral] = _('log_g(x) has the standard anti-derivative ' \
'(xln(x) - x) / log_g(x) + c.')
def sinus_integral(root, args):
"""
int sin(x) dx -> -cos(x)
"""
return solve_integral(root, -cos(root[0][0]))
MESSAGES[sinus_integral] = \
_('{0[0]} has the standard anti-derivative -cos({0[0][0]}) + c.')
def cosinus_integral(root, args):
"""
int cos(x) dx -> sin(x)
"""
return solve_integral(root, sin(root[0][0]))
MESSAGES[cosinus_integral] = \
_('{0[0]} has the standard anti-derivative sin({0[0][0]}) + c.')
...@@ -3,9 +3,11 @@ from src.rules.integrals import indef, choose_constant, solve_integral, \ ...@@ -3,9 +3,11 @@ from src.rules.integrals import indef, choose_constant, solve_integral, \
integrate_variable_root, integrate_variable_exponent, \ integrate_variable_root, integrate_variable_exponent, \
match_constant_integral, constant_integral, \ match_constant_integral, constant_integral, \
match_factor_out_constant, factor_out_constant, \ match_factor_out_constant, factor_out_constant, \
match_division_integral, division_integral, extend_division_integral match_division_integral, division_integral, extend_division_integral, \
match_function_integral, logarithm_integral, sinus_integral, \
cosinus_integral
from src.rules.logarithmic import ln from src.rules.logarithmic import ln
#from .goniometry import sin, cos from src.rules.goniometry import sin, cos
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
...@@ -103,3 +105,24 @@ class TestRulesIntegrals(RulesTestCase): ...@@ -103,3 +105,24 @@ class TestRulesIntegrals(RulesTestCase):
# FIXME: 'a int 1 / x dx', # fix with strategy # FIXME: 'a int 1 / x dx', # fix with strategy
# FIXME: 'aln|x| + c', # FIXME: 'aln|x| + c',
]) ])
def test_match_function_integral(self):
root0, root1, root2 = tree('int ln x, int sin x, int cos x')
self.assertEqualPos(match_function_integral(root0),
[P(root0, logarithm_integral)])
self.assertEqualPos(match_function_integral(root1),
[P(root1, sinus_integral)])
self.assertEqualPos(match_function_integral(root2),
[P(root2, cosinus_integral)])
def test_logarithm_integral(self):
root, expect = tree('int ln x, (xlnx - x) / ln e + c')
self.assertEqual(logarithm_integral(root, ()), expect)
def test_sinus_integral(self):
root, expect = tree('int sin x, -cos x + c')
self.assertEqual(sinus_integral(root, ()), expect)
def test_cosinus_integral(self):
root, expect = tree('int cos x, sin x + c')
self.assertEqual(cosinus_integral(root, ()), 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