Commit 895c81d7 authored by Taddeus Kroes's avatar Taddeus Kroes

Added derivation rule for logarithm.

parent 0f086a69
from ..node import OP_ADD, OP_MUL, OP_DIV, OP_POW, OP_NEG, OP_SIN, OP_COS, \
OP_TAN, OP_DERIV
OP_TAN, OP_DER
from .groups import match_combine_groups
from .factors import match_expand
from .powers import match_add_exponents, match_subtract_exponents, \
......@@ -19,7 +19,7 @@ from .goniometry import match_add_quadrants, match_negated_parameter, \
match_half_pi_subtraction, match_standard_radian
from src.rules.derivatives import match_zero_derivative, \
match_one_derivative, match_variable_power, \
match_const_deriv_multiplication
match_const_deriv_multiplication, match_logarithm
RULES = {
OP_ADD: [match_add_numerics, match_add_constant_fractions,
......@@ -41,6 +41,7 @@ RULES = {
OP_COS: [match_negated_parameter, match_half_pi_subtraction,
match_standard_radian],
OP_TAN: [match_standard_radian],
OP_DERIV: [match_zero_derivative, match_one_derivative,
match_variable_power, match_const_deriv_multiplication],
OP_DER: [match_zero_derivative, match_one_derivative,
match_variable_power, match_const_deriv_multiplication,
match_logarithm],
}
......@@ -2,8 +2,8 @@ from itertools import combinations
from .utils import find_variables
from .logarithmic import ln
from ..node import ExpressionNode as N, ExpressionLeaf as L, Scope, OP_DERIV, \
OP_MUL
from ..node import ExpressionNode as N, ExpressionLeaf as L, Scope, OP_DER, \
OP_MUL, OP_LOG
from ..possibilities import Possibility as P, MESSAGES
from ..translate import _
......@@ -58,7 +58,7 @@ def match_zero_derivative(node):
der(x, y) -> 0
der(n) -> 0
"""
assert node.is_op(OP_DERIV)
assert node.is_op(OP_DER)
variables = find_variables(node[0])
var = get_derivation_variable(node, variables)
......@@ -74,7 +74,7 @@ def match_one_derivative(node):
der(x) -> 1 # Implicit x
der(x, x) -> 1 # Explicit x
"""
assert node.is_op(OP_DERIV)
assert node.is_op(OP_DER)
var = get_derivation_variable(node)
......@@ -110,7 +110,7 @@ def match_const_deriv_multiplication(node):
"""
der(c * f(x), x) -> c * der(f(x), x)
"""
assert node.is_op(OP_DERIV)
assert node.is_op(OP_DER)
p = []
......@@ -146,7 +146,7 @@ def match_variable_power(node):
der(x ^ n, x) -> n * x ^ (n - 1)
der(f(x) ^ n) -> n * f(x) ^ (n - 1) * der(f(x)) # Chain rule
"""
assert node.is_op(OP_DERIV)
assert node.is_op(OP_DER)
if not node[0].is_power():
return []
......@@ -199,3 +199,38 @@ def variable_exponent(root, args):
MESSAGES[variable_exponent] = \
_('Apply standard derivative d/dx g ^ x = g ^ x * ln g.')
def match_logarithm(node):
"""
der(log(x, g), x) -> 1 / (x * ln(g))
der(log(f(x), g), x) -> 1 / (f(x) * ln(g)) * der(f(x), x)
"""
assert node.is_op(OP_DER)
x = get_derivation_variable(node)
if x and node[0].is_op(OP_LOG):
f = node[0][0]
x = L(x)
if f == x:
return [P(node, logarithm, ())]
if f.contains(x):
return [P(node, chain_rule, (f, logarithm, ()))]
return []
def logarithm(root, args):
"""
der(log(x, g), x) -> 1 / (x * ln(g))
"""
x, g = root[0]
return L(1) / (x * ln(g))
MESSAGES[logarithm] = \
_('Apply standard derivative d/dx log(x, g) = 1 / (x * ln(g)).')
from ..node import ExpressionNode as N, ExpressionLeaf as L, OP_LOG, OP_LN
from ..node import ExpressionNode as N, ExpressionLeaf as L, OP_LOG, E
from ..possibilities import Possibility as P, MESSAGES
from ..translate import _
......@@ -11,4 +11,4 @@ def log(exponent, base=10):
def ln(exponent):
return N('ln', exponent)
return log(exponent, base=E)
......@@ -2,7 +2,7 @@ from src.rules.derivatives import der, get_derivation_variable, \
match_zero_derivative, match_one_derivative, one_derivative, \
zero_derivative, match_variable_power, variable_root, \
variable_exponent, match_const_deriv_multiplication, \
const_deriv_multiplication, chain_rule
const_deriv_multiplication, chain_rule, match_logarithm, logarithm
from src.rules.logarithmic import ln
from src.node import Scope
from src.possibilities import Possibility as P
......@@ -109,3 +109,16 @@ class TestRulesDerivatives(RulesTestCase):
x, l3 = x3
self.assertEqual(chain_rule(root, (x3, variable_exponent, ())),
l2 ** x3 * ln(l2) * der(x3))
def test_match_logarithm(self):
root = tree('der(log(x))')
self.assertEqualPos(match_logarithm(root), [P(root, logarithm)])
def test_match_logarithm_chain_rule(self):
root, f = tree('der(log(x ^ 2)), x ^ 2')
self.assertEqualPos(match_logarithm(root),
[P(root, chain_rule, (f, logarithm, ()))])
def test_logarithm(self):
root, x, l1, l10 = tree('der(log(x)), x, 1, 10')
self.assertEqual(logarithm(root, ()), l1 / (x * ln(l10)))
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