Skip to content

Commit 2274b91

Browse files
More derivative rules plus a simplify tweak.
1 parent 58e7f7e commit 2274b91

File tree

2 files changed

+96
-29
lines changed

2 files changed

+96
-29
lines changed

src/differentiate.jl

Lines changed: 94 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -115,33 +115,70 @@ end
115115

116116

117117
derivative_rules = [
118-
(:log, :( xp / x ))
119-
(:log10, :( xp / x / log(10) ))
120-
(:exp, :( xp * exp(x) ))
121-
(:sin, :( xp * cos(x) ))
122-
(:cos, :( -xp * sin(x) ))
123-
(:tan, :( xp * (1 + tan(x)^2) ))
124-
(:sec, :( xp * sec(x) * tan(x) ))
125-
(:csc, :( -xp * csc(x) * cot(x) ))
126-
(:cot, :( -xp * (1 + cot(x)^2) ))
127-
(:asin, :( xp / sqrt(1 - x^2) ))
128-
(:acos, :( -xp / sqrt(1 - x^2) ))
129-
(:atan, :( -xp / (1 + x^2) ))
130-
(:asec, :( xp / abs(x) / sqrt(x^2 - 1) ))
131-
(:acsc, :( -xp / abs(x) / sqrt(x^2 - 1) ))
132-
(:acot, :( -xp / (1 + x^2) ))
133-
(:sinh, :( xp * cosh(x) ))
134-
(:cosh, :( xp * sinh(x) ))
135-
(:tanh, :( xp * sech(x)^2 ))
136-
(:sech, :( -xp * tanh(x) * sech(x) ))
137-
(:csch, :( -xp * coth(x) * csch(x) ))
138-
(:coth, :( -xp * csch(x)^2 ))
139-
(:asinh, :( xp / sqrt(x^2 + 1) ))
140-
(:acosh, :( xp / sqrt(x^2 - 1) ))
141-
(:atanh, :( xp / (1 - x^2) ))
142-
(:asech, :( -xp / x / sqrt(1 - x^2) ))
143-
(:acsch, :( -xp / abs(x) / sqrt(1 + x^2) ))
144-
(:acoth, :( xp / (1 - x^2) ))
118+
( :sqrt, :( xp / 2 / sqrt(x) ))
119+
( :cbrt, :( xp / 3 / cbrt(x)^2 ))
120+
( :square, :( xp * 2 * x ))
121+
( :log, :( xp / x ))
122+
( :log10, :( xp / x / log(10) ))
123+
( :log2, :( xp / x / log(2) ))
124+
( :log1p, :( xp / (x + 1) ))
125+
( :exp, :( xp * exp(x) ))
126+
( :exp2, :( xp * log(2) * exp2(x) ))
127+
( :expm1, :( xp * exp(x) ))
128+
( :sin, :( xp * cos(x) ))
129+
( :cos, :( -xp * sin(x) ))
130+
( :tan, :( xp * (1 + tan(x)^2) ))
131+
( :sec, :( xp * sec(x) * tan(x) ))
132+
( :csc, :( -xp * csc(x) * cot(x) ))
133+
( :cot, :( -xp * (1 + cot(x)^2) ))
134+
( :sind, :( xp * cosd(x) ))
135+
( :cosd, :( -xp * sind(x) ))
136+
( :tand, :( xp * (1 + tand(x)^2) ))
137+
( :secd, :( xp * secd(x) * tand(x) ))
138+
( :cscd, :( -xp * cscd(x) * cotd(x) ))
139+
( :cotd, :( -xp * (1 + cotd(x)^2) ))
140+
( :asin, :( xp / sqrt(1 - x^2) ))
141+
( :acos, :( -xp / sqrt(1 - x^2) ))
142+
( :atan, :( xp / (1 + x^2) ))
143+
( :asec, :( xp / abs(x) / sqrt(x^2 - 1) ))
144+
( :acsc, :( -xp / abs(x) / sqrt(x^2 - 1) ))
145+
( :acot, :( -xp / (1 + x^2) ))
146+
( :asind, :( xp * 180 / pi / sqrt(1 - x^2) ))
147+
( :acosd, :( -xp * 180 / pi / sqrt(1 - x^2) ))
148+
( :atand, :( xp * 180 / pi / (1 + x^2) ))
149+
( :asecd, :( xp * 180 / pi / abs(x) / sqrt(x^2 - 1) ))
150+
( :acscd, :( -xp * 180 / pi / abs(x) / sqrt(x^2 - 1) ))
151+
( :acotd, :( -xp * 180 / pi / (1 + x^2) ))
152+
( :sinh, :( xp * cosh(x) ))
153+
( :cosh, :( xp * sinh(x) ))
154+
( :tanh, :( xp * sech(x)^2 ))
155+
( :sech, :( -xp * tanh(x) * sech(x) ))
156+
( :csch, :( -xp * coth(x) * csch(x) ))
157+
( :coth, :( -xp * csch(x)^2 ))
158+
( :asinh, :( xp / sqrt(x^2 + 1) ))
159+
( :acosh, :( xp / sqrt(x^2 - 1) ))
160+
( :atanh, :( xp / (1 - x^2) ))
161+
( :asech, :( -xp / x / sqrt(1 - x^2) ))
162+
( :acsch, :( -xp / abs(x) / sqrt(1 + x^2) ))
163+
( :acoth, :( xp / (1 - x^2) ))
164+
( :erf, :( xp * 2 * exp(-square(x)) / sqrt(pi) ))
165+
( :erfc, :( -xp * 2 * exp(-square(x)) / sqrt(pi) ))
166+
( :erfi, :( xp * 2 * exp(square(x)) / sqrt(pi) ))
167+
( :gamma, :( xp * digamma(x) * gamma(x) ))
168+
( :lgamma, :( xp * digamma(x) ))
169+
( :airy, :( xp * airyprime(x) )) # note: only covers the 1-arg version
170+
( :airyprime, :( xp * airy(2, x) ))
171+
( :airyai, :( xp * airyaiprime(x) ))
172+
( :airybi, :( xp * airybiprime(x) ))
173+
( :airyaiprime, :( xp * x * airyai(x) ))
174+
( :airybiprime, :( xp * x * airybi(x) ))
175+
( :besselj0, :( -xp * besselj1(x) ))
176+
( :besselj1, :( xp * (besselj0(x) - besselj(2, x)) / 2 ))
177+
( :bessely0, :( -xp * bessely1(x) ))
178+
( :bessely1, :( xp * (bessely0(x) - bessely(2, x)) / 2 ))
179+
## ( :erfcx, :( xp * (2 * x * erfcx(x) - 2 / sqrt(pi)) )) # uncertain
180+
## ( :dawson, :( xp * (1 - 2x * dawson(x)) )) # uncertain
181+
145182
]
146183

147184
for (funsym, exp) in derivative_rules
@@ -155,3 +192,33 @@ for (funsym, exp) in derivative_rules
155192
end
156193
end
157194
end
195+
196+
derivative_rules_bessel = [
197+
( :besselj, :( xp * (besselj(nu - 1, x) - besselj(nu + 1, x)) / 2 ))
198+
( :besseli, :( xp * (besseli(nu - 1, x) + besseli(nu + 1, x)) / 2 ))
199+
( :bessely, :( xp * (bessely(nu - 1, x) - bessely(nu + 1, x)) / 2 ))
200+
( :besselk, :( -xp * (besselk(nu - 1, x) + besselk(nu + 1, x)) / 2 ))
201+
( :hankelh1, :( xp * (hankelh1(nu - 1, x) - hankelh1(nu + 1, x)) / 2 ))
202+
( :hankelh2, :( xp * (hankelh2(nu - 1, x) - hankelh2(nu + 1, x)) / 2 ))
203+
]
204+
205+
# 2-argument bessel functions
206+
for (funsym, exp) in derivative_rules_bessel
207+
@eval function differentiate(::SymbolParameter{$(Meta.quot(funsym))}, args, wrt)
208+
nu = args[1]
209+
x = args[2]
210+
xp = differentiate(x, wrt)
211+
if x != 0
212+
return @sexpr($exp)
213+
else
214+
return 0
215+
end
216+
end
217+
end
218+
219+
### Other functions from julia/base/math.jl we might want to define
220+
### derivatives for. Some have two arguments.
221+
222+
## atan2
223+
## hypot
224+
## beta, lbeta, eta, zeta, digamma

src/symbolic.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ simplify(x) = x
8585
simplify(n::Number) = n
8686
simplify(s::SymbolicVariable) = s
8787

88-
# The default is no simplification.
89-
simplify{T}(x::SymbolParameter{T}, args) = Expr(:call, T, args...)
88+
# The default is just to simplify arguments.
89+
simplify{T}(x::SymbolParameter{T}, args) = Expr(:call, T, map(x -> simplify(x), args)...)
9090

9191
function simplify(ex::Expr)
9292
if ex.head != :call

0 commit comments

Comments
 (0)