Skip to content

Commit

Permalink
Merge pull request #124 from mlubin/ml/fixeval
Browse files Browse the repository at this point in the history
remove call to simplify() in differentiate()
  • Loading branch information
mlubin committed May 22, 2018
2 parents e71569d + 7ad7924 commit 95b48b2
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 41 deletions.
3 changes: 2 additions & 1 deletion src/differentiate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ function differentiate(ex::Expr,wrt)
if ex.head != :call
error("Unrecognized expression $ex")
end
simplify(differentiate(SymbolParameter(ex.args[1]), ex.args[2:end], wrt))
# TODO: When simplify no longer calls eval, simplify the result.
differentiate(SymbolParameter(ex.args[1]), ex.args[2:end], wrt)
end

differentiate(x::SymbolParameter{T}, args, wrt) where {T} = error("Derivative of function " * string(T) * " not supported")
Expand Down
85 changes: 45 additions & 40 deletions test/symbolic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,51 @@
# Univariate Calculus
#

macro test_simplified_isequal(lhs, rhs)
quote
@test isequal(simplify($(esc(lhs))), $(esc(rhs)))
end
end

@test isequal(differentiate(:(2), :x), 0)
@test isequal(differentiate(:(x), :x), 1)
@test isequal(differentiate(:(x + x), :x), 2)
@test isequal(differentiate(:(x - x), :x), 0)
@test isequal(differentiate(:(2 * x), :x), 2)
@test isequal(differentiate(:(2 / x), :x), :(-2 / x^2))
@test isequal(differentiate(:(x / 2), :x), 0.5)
@test isequal(differentiate(:(sin(x) / x), :x), :((cos(x) * x - sin(x)) / x^2))
@test isequal(differentiate(:(x * 2), :x), 2)
@test isequal(differentiate(:(a * x), :x), :a)
@test isequal(differentiate(:(x * a), :x), :a)
@test isequal(differentiate(:(x ^ 2), :x), :(2 * x))
@test isequal(differentiate(:(a * x ^ 2), :x), :(a * (2 * x)))
@test isequal(differentiate(:(2 ^ x), :x), :(*(0.6931471805599453, ^(2, x))))
@test isequal(differentiate(:(sin(x)), :x), :(cos(x)))
@test isequal(differentiate(:(cos(x)), :x), :(-sin(x)))
@test isequal(differentiate(:(tan(x)), :x), :(1 + tan(x)^2))
@test isequal(differentiate(:(exp(x)), :x), :(exp(x)))
@test isequal(differentiate(:(log(x)), :x), :(1 / x))
@test isequal(differentiate(:(sin(x) + sin(x)), :x), :(cos(x) + cos(x)))
@test isequal(differentiate(:(sin(x) - cos(x)), :x), :(cos(x) + sin(x)))
@test isequal(differentiate(:(x * sin(x)), :x), :(sin(x) + x * cos(x)))
@test isequal(differentiate(:(x / sin(x)), :x), :((sin(x) - x * cos(x)) / (sin(x)^2)))
@test isequal(differentiate(:(sin(sin(x))), :x), :(*(cos(x),cos(sin(x)))))
@test isequal(differentiate(:(sin(cos(x) + sin(x))), :x), :(*(+(-sin(x),cos(x)),cos(+(cos(x),sin(x))))))
@test isequal(differentiate(:(exp(-x)), :x), :(-exp(-x)))
@test isequal(differentiate(:(log(x^2)), :x), :((2x) * (1 / x^2)))
@test isequal(differentiate(:(abs2(x)), :x), :(2x))
@test isequal(differentiate(:(inv(x)), :x), :(-abs2(inv(x))))
@test isequal(differentiate(:(x^n), :x), :(*(n, ^(x, -(n, 1)))))
@test isequal(differentiate(:(n^x), :x), :(*(^(n, x), log(n))))
@test isequal(differentiate(:(n^n), :x), 0)
@test_simplified_isequal differentiate(:(x + x), :x) 2
@test_simplified_isequal differentiate(:(x - x), :x) 0
@test_simplified_isequal differentiate(:(2 * x), :x) 2
@test_simplified_isequal differentiate(:(2 / x), :x) :(-2 / x^2)
@test_simplified_isequal differentiate(:(x / 2), :x) 0.5
@test_simplified_isequal differentiate(:(sin(x) / x), :x) :((cos(x) * x - sin(x)) / x^2)
@test_simplified_isequal differentiate(:(x * 2), :x) 2
@test_simplified_isequal differentiate(:(a * x), :x) :a
@test_simplified_isequal differentiate(:(x * a), :x) :a
@test_simplified_isequal differentiate(:(x ^ 2), :x) :(2 * x)
@test_simplified_isequal differentiate(:(a * x ^ 2), :x) :(a * (2 * x))
@test_simplified_isequal differentiate(:(2 ^ x), :x) :(*(0.6931471805599453, ^(2, x)))
@test_simplified_isequal differentiate(:(sin(x)), :x) :(cos(x))
@test_simplified_isequal differentiate(:(cos(x)), :x) :(-sin(x))
@test_simplified_isequal differentiate(:(tan(x)), :x) :(1 + tan(x)^2)
@test_simplified_isequal differentiate(:(exp(x)), :x) :(exp(x))
@test_simplified_isequal differentiate(:(log(x)), :x) :(1 / x)
@test_simplified_isequal differentiate(:(sin(x) + sin(x)), :x) :(cos(x) + cos(x))
@test_simplified_isequal differentiate(:(sin(x) - cos(x)), :x) :(cos(x) + sin(x))
@test_simplified_isequal differentiate(:(x * sin(x)), :x) :(sin(x) + x * cos(x))
@test_simplified_isequal differentiate(:(x / sin(x)), :x) :((sin(x) - x * cos(x)) / (sin(x)^2))
@test_simplified_isequal differentiate(:(sin(sin(x))), :x) :(*(cos(x),cos(sin(x))))
@test_simplified_isequal differentiate(:(sin(cos(x) + sin(x))), :x) :(*(+(-sin(x),cos(x)),cos(+(cos(x),sin(x)))))
@test_simplified_isequal differentiate(:(exp(-x)), :x) :(-exp(-x))
@test_simplified_isequal differentiate(:(log(x^2)), :x) :((2x) * (1 / x^2))
@test_simplified_isequal differentiate(:(abs2(x)), :x) :(2x)
@test_simplified_isequal differentiate(:(inv(x)), :x) :(-abs2(inv(x)))
@test_simplified_isequal differentiate(:(x^n), :x) :(*(n, ^(x, -(n, 1))))
@test_simplified_isequal differentiate(:(n^x), :x) :(*(^(n, x), log(n)))
@test_simplified_isequal differentiate(:(n^n), :x) 0

#
# Multivariate Calculus
#

@test isequal(differentiate(:(sin(x) + sin(y)), [:x, :y]), [:(cos(x)), :(cos(y))])
@test isequal(differentiate(:(x^2), [:x, :y]), Any[:(2*x), 0])
@test isequal(simplify.(differentiate(:(sin(x) + sin(y)), [:x, :y])), [:(cos(x)), :(cos(y))])
@test isequal(simplify.(differentiate(:(x^2), [:x, :y])), Any[:(2*x), 0])

# TODO: Get the generalized power rule right.
# @test isequal(differentiate(:(sin(x)^2), :x), :(2 * sin(x) * cos(x)))
Expand All @@ -50,7 +56,7 @@
#

# @test isequal(differentiate("sin(x) + cos(x)^2"), :(+(cos(x),*(2,cos(x)))))
@test isequal(differentiate("x + exp(-x) + sin(exp(x))", :x), :(+(1,-exp(-x),*(exp(x),cos(exp(x))))))
@test_simplified_isequal differentiate("x + exp(-x) + sin(exp(x))", :x) :(+(1,-exp(-x),*(exp(x),cos(exp(x)))))

# TODO: Make these work
# differentiate(:(sin(x)), :x)(0.0)
Expand All @@ -65,13 +71,13 @@ x = BasicVariable(:x)
y = BasicVariable(:y)

@test isequal(@sexpr(x + y), :($x + $y))
@test isequal(differentiate(@sexpr(3 * x), x), 3)
@test isequal(differentiate(:(sin(sin(x))), :x), :(*(cos(x),cos(sin(x)))))
@test isequal(differentiate(@sexpr(sin(sin(x))), x), :(*(cos($x),cos(sin($x)))))
@test_simplified_isequal differentiate(@sexpr(3 * x), x) 3
@test_simplified_isequal differentiate(:(sin(sin(x))), :x) :(*(cos(x),cos(sin(x))))
@test_simplified_isequal differentiate(@sexpr(sin(sin(x))), x) :(*(cos($x),cos(sin($x))))

function testfun(x)
z = BasicVariable(:z)
differentiate(@sexpr(3*x + x^2*z), z)
simplify(differentiate(@sexpr(3*x + x^2*z), z))
end

@test isequal(testfun(x), :(^($(x),2)))
Expand Down Expand Up @@ -100,6 +106,5 @@ end
#
# Tests with ifelse
#
@test isequal(differentiate(:(ifelse(x < 1, exp(x^2), 1/x)), :x), :(ifelse(x < 1,2x * exp(x^2), -1/x^2)))
@test isequal(differentiate(:(ifelse(x <= 0, 0, ifelse(x > 1, 1, x))), :x),
:(ifelse(x <= 0, 0, ifelse(x > 1, 0, 1))))
@test_simplified_isequal differentiate(:(ifelse(x < 1, exp(x^2), 1/x)), :x) :(ifelse(x < 1,2x * exp(x^2), -1/x^2))
@test_simplified_isequal differentiate(:(ifelse(x <= 0, 0, ifelse(x > 1, 1, x))), :x) :(ifelse(x <= 0, 0, ifelse(x > 1, 0, 1)))

0 comments on commit 95b48b2

Please sign in to comment.