From 7ad79244d827340258088569271c95e9fc9d0a12 Mon Sep 17 00:00:00 2001 From: Miles Lubin Date: Sat, 19 May 2018 20:41:17 -0400 Subject: [PATCH] remove call to simplify() in differentiate() --- src/differentiate.jl | 3 +- test/symbolic.jl | 85 +++++++++++++++++++++++--------------------- 2 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/differentiate.jl b/src/differentiate.jl index a80c82a..241cd31 100644 --- a/src/differentiate.jl +++ b/src/differentiate.jl @@ -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") diff --git a/test/symbolic.jl b/test/symbolic.jl index f2f7bbd..a40c3ac 100644 --- a/test/symbolic.jl +++ b/test/symbolic.jl @@ -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))) @@ -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) @@ -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))) @@ -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)))