Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ SpecialFunctions = "0.10, 1.0, 2"
julia = "1.3"

[extras]
FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "Random"]
test = ["FiniteDifferences", "Test", "Random"]
67 changes: 41 additions & 26 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
using DiffRules
using FiniteDifferences
using Test

import SpecialFunctions, NaNMath, LogExpFunctions
import Random
Random.seed!(1)

function finitediff(f, x)
ϵ = cbrt(eps(typeof(x))) * max(one(typeof(x)), abs(x))
return (f(x + ϵ) - f(x - ϵ)) / (ϵ + ϵ)
end
const finitediff = central_fdm(5, 1)

@testset "DiffRules" begin
@testset "check rules" begin
Expand All @@ -20,22 +18,25 @@ for (M, f, arity) in DiffRules.diffrules(; filter_modules=nothing)
if arity == 1
@test DiffRules.hasdiffrule(M, f, 1)
deriv = DiffRules.diffrule(M, f, :goo)
modifier = if f in (:asec, :acsc, :asecd, :acscd, :acosh, :acoth)
1.0
elseif f === :log1mexp
-1.0
elseif f === :log2mexp
-0.5
else
0.0
end
@eval begin
let
goo = rand() + $modifier
@test isapprox($deriv, finitediff($M.$f, goo), rtol=0.05)
goo = if $(f in (:asec, :acsc, :asecd, :acscd, :acosh, :acoth))
# avoid singularities with finite differencing
rand() + 1.5
elseif $(f === :log)
# avoid singularities with finite differencing
rand() + 0.5
elseif $(f === :log1mexp)
rand() - 1.0
elseif $(f in (:log2mexp, :asin, :acos, :erfinv))
rand() - 0.5
else
rand()
end
@test $deriv ≈ finitediff($M.$f, goo) rtol=1e-9 atol=1e-9
# test for 2pi functions
if "mod2pi" == string($M.$f)
goo = 4pi + $modifier
if $(f === :mod2pi)
goo = 4 * pi
@test NaN === $deriv
end
end
Expand All @@ -45,17 +46,31 @@ for (M, f, arity) in DiffRules.diffrules(; filter_modules=nothing)
derivs = DiffRules.diffrule(M, f, :foo, :bar)
@eval begin
let
if "mod" == string($M.$f)
foo, bar = rand() + 13, rand() + 5 # make sure x/y is not integer
foo, bar = if $(f === :mod)
rand() + 13, rand() + 5 # make sure x/y is not integer
elseif $(f === :polygamma)
rand(1:10), rand() # only supports integers as first arguments
elseif $(f === :bessely)
# avoid singularities with finite differencing
rand(), rand() + 0.5
elseif $(f === :log)
# avoid singularities with finite differencing
rand() + 1.5, rand()
elseif $(f in (:^, :pow))
# avoid singularities with finite differencing
rand() + 0.5, rand()
elseif $(f === :logbeta)
# avoid singularities with finite differencing
rand() + 0.5, rand() + 0.5
else
foo, bar = rand(1:10), rand()
rand(), rand()
end
dx, dy = $(derivs[1]), $(derivs[2])
if !(isnan(dx))
@test isapprox(dx, finitediff(z -> $M.$f(z, bar), float(foo)), rtol=0.05)
if !isnan(dx)
@test dx ≈ finitediff(z -> $M.$f(z, bar), float(foo)) rtol=1e-9 atol=1e-9
end
if !(isnan(dy))
@test isapprox(dy, finitediff(z -> $M.$f(foo, z), bar), rtol=0.05)
if !isnan(dy)
@test dy ≈ finitediff(z -> $M.$f(foo, z), bar) rtol=1e-9 atol=1e-9
end
end
end
Expand Down Expand Up @@ -89,7 +104,7 @@ for xtype in [:Float64, :BigFloat, :Int64]
x = $xtype(rand(1 : 10))
y = $mode
dx, dy = $(derivs[1]), $(derivs[2])
@test isapprox(dx, finitediff(z -> rem2pi(z, y), float(x)), rtol=0.05)
@test dx ≈ finitediff(z -> rem2pi(z, y), float(x)) rtol=1e-9 atol=1e-9
@test isnan(dy)
end
end
Expand All @@ -105,7 +120,7 @@ for xtype in [:Float64, :BigFloat]
x = rand($xtype)
y = $ytype(rand(1 : 10))
dx, dy = $(derivs[1]), $(derivs[2])
@test isapprox(dx, finitediff(z -> ldexp(z, y), x), rtol=0.05)
@test dx ≈ finitediff(z -> ldexp(z, y), x) rtol=1e-9 atol=1e-9
@test isnan(dy)
end
end
Expand Down