Skip to content

Commit c77ee18

Browse files
dlfivefiftymlubin
authored andcommitted
Override SpecialFunctions (#65)
* Add flipsign * Fix bug in inv(::Dual) * Fix deprecations * REQUIRE Julia v0.7
1 parent f9747e3 commit c77ee18

File tree

6 files changed

+46
-17
lines changed

6 files changed

+46
-17
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ os:
44
- linux
55
- osx
66
julia:
7-
- 0.6
87
- 0.7
8+
- 1.0
99
- nightly
1010
notifications:
1111
email: false

REQUIRE

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
julia 0.6
1+
julia 0.7
22
Compat 0.49.0
33
Calculus
44
NaNMath
5+
SpecialFunctions 0.7

src/DualNumbers.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
__precompile__()
2-
31
module DualNumbers
42

5-
using Compat
3+
using Compat, SpecialFunctions
64
import NaNMath
75
import Calculus
86

src/dual.jl

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,6 @@ end
143143

144144
Base.show(io::IO, z::Dual) = dual_show(io, z, get(IOContext(io), :compact, false))
145145

146-
@static if VERSION < v"0.7.0-DEV.4524"
147-
Base.showcompact(io::IO, z::Dual) = dual_show(io, z, true)
148-
end
149-
150146
function Base.read(s::IO, ::Type{Dual{T}}) where T<:ReComp
151147
x = read(s, T)
152148
y = read(s, T)
@@ -212,6 +208,10 @@ function Base.angle(z::Dual{Complex{T}}) where T<:Real
212208
end
213209
end
214210

211+
Base.flipsign(x::Dual,y::Dual) = y == 0 ? flipsign(x, epsilon(y)) : flipsign(x, value(y))
212+
Base.flipsign(x, y::Dual) = y == 0 ? flipsign(x, epsilon(y)) : flipsign(x, value(y))
213+
Base.flipsign(x::Dual, y) = dual(flipsign(value(x), y), flipsign(epsilon(x), y))
214+
215215
# algebraic definitions
216216
conjdual(z::Dual) = Dual(value(z),-epsilon(z))
217217
absdual(z::Dual) = abs(value(z))
@@ -264,6 +264,8 @@ Base.:^(z::Dual, n::Number) = Dual(value(z)^n, epsilon(z)*n*value(z)^(n-1))
264264
NaNMath.pow(z::Dual, n::Number) = Dual(NaNMath.pow(value(z),n), epsilon(z)*n*NaNMath.pow(value(z),n-1))
265265
NaNMath.pow(z::Number, w::Dual) = Dual(NaNMath.pow(z,value(w)), epsilon(w)*NaNMath.pow(z,value(w))*log(z))
266266

267+
inv(z::Dual) = dual(inv(value(z)),-epsilon(z)/value(z)^2)
268+
267269
# force use of NaNMath functions in derivative calculations
268270
function to_nanmath(x::Expr)
269271
if x.head == :call
@@ -275,14 +277,25 @@ function to_nanmath(x::Expr)
275277
end
276278
to_nanmath(x) = x
277279

280+
281+
282+
278283
for (funsym, exp) in Calculus.symbolic_derivatives_1arg()
279284
funsym == :exp && continue
280285
funsym == :abs2 && continue
281-
isdefined(Base, funsym) || continue
282-
@eval function Base.$(funsym)(z::Dual)
283-
x = value(z)
284-
xp = epsilon(z)
285-
Dual($(funsym)(x),xp*$exp)
286+
funsym == :inv && continue
287+
if isdefined(SpecialFunctions, funsym)
288+
@eval function SpecialFunctions.$(funsym)(z::Dual)
289+
x = value(z)
290+
xp = epsilon(z)
291+
Dual($(funsym)(x),xp*$exp)
292+
end
293+
elseif isdefined(Base, funsym)
294+
@eval function Base.$(funsym)(z::Dual)
295+
x = value(z)
296+
xp = epsilon(z)
297+
Dual($(funsym)(x),xp*$exp)
298+
end
286299
end
287300
# extend corresponding NaNMath methods
288301
if funsym in (:sin, :cos, :tan, :asin, :acos, :acosh, :atanh, :log, :log2, :log10,

test/automatic_differentiation_test.jl

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using DualNumbers
1+
using DualNumbers, SpecialFunctions
22
using Compat
3-
using Compat.Test
3+
using Test
44
using Compat.LinearAlgebra
55
import DualNumbers: value
66
import NaNMath
@@ -106,6 +106,10 @@ a = angle(z)
106106

107107
@test angle(Dual(0.0+im,0.0+im)) == π/2
108108

109+
110+
# check bug in inv
111+
@test inv(dual(1.0+1.0im,1.0)) == 1/dual(1.0+1.0im,1.0) == dual(1.0+1.0im,1.0)^(-1)
112+
109113
#
110114
# Tests limit definition. Let z = a + b ɛ, where a and b ∈ C.
111115
#
@@ -145,3 +149,16 @@ test(x, y) = x^2 + y
145149

146150
@test epsilon(Dual(-2.0,1.0)^2.0) == -4
147151
@test epsilon(Dual(-2.0,1.0)^Dual(2.0,0.0)) == -4
152+
153+
154+
# test for flipsign
155+
flipsign(Dual(1.0,1.0),2.0) == Dual(1.0,1.0)
156+
flipsign(Dual(1.0,1.0),-2.0) == Dual(-1.0,-1.0)
157+
flipsign(Dual(1.0,1.0),Dual(1.0,1.0)) == Dual(1.0,1.0)
158+
flipsign(Dual(1.0,1.0),Dual(0.0,-1.0)) == Dual(-1.0,-1.0)
159+
flipsign(-1.0,Dual(1.0,1.0)) == -1.0
160+
161+
162+
# test SpecialFunctions
163+
@test erf(dual(1.0,1.0)) == dual(erf(1.0), 2exp(-1.0^2)/sqrt(π))
164+
@test gamma(dual(1.,1)) == dual(gamma(1.0),polygamma(0,1.0))

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using DualNumbers
22
using Compat
3-
using Compat.Test
3+
using Test
44

55
@test checkindex(Bool, 1:3, dual(2))
66

0 commit comments

Comments
 (0)