From b641c72d87f8c0ce1078ffd9abcb41fbeb37cd72 Mon Sep 17 00:00:00 2001 From: David Hofmann <1681922+david-hofmann@users.noreply.github.com> Date: Tue, 30 Nov 2021 16:41:15 +0100 Subject: [PATCH 1/6] Update rules.jl Added a rule for the function ldexp https://docs.julialang.org/en/v1/base/math/#Base.Math.ldexp --- src/rules.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rules.jl b/src/rules.jl index 88cb5af..54506c0 100644 --- a/src/rules.jl +++ b/src/rules.jl @@ -90,6 +90,7 @@ else end @define_diffrule Base.hypot(x, y) = :( $x / hypot($x, $y) ), :( $y / hypot($x, $y) ) @define_diffrule Base.log(b, x) = :( log($x) * inv(-log($b)^2 * $b) ), :( inv($x) / log($b) ) +@define_diffrule Base.ldexp(x, y) = :( 2^$y ), :(log(2) * $x * 2^$y) @define_diffrule Base.mod(x, y) = :( first(promote(ifelse(isinteger($x / $y), NaN, 1), NaN)) ), :( z = $x / $y; first(promote(ifelse(isinteger(z), NaN, -floor(z)), NaN)) ) @define_diffrule Base.rem(x, y) = :( first(promote(ifelse(isinteger($x / $y), NaN, 1), NaN)) ), :( z = $x / $y; first(promote(ifelse(isinteger(z), NaN, -trunc(z)), NaN)) ) From 139a5547346672275a0c3ebb19c56c38e8840023 Mon Sep 17 00:00:00 2001 From: David Hofmann <1681922+david-hofmann@users.noreply.github.com> Date: Wed, 1 Dec 2021 00:33:23 +0100 Subject: [PATCH 2/6] Update src/rules.jl use exp2 instead of 2^x to avoid overflows, indicate the derivative w.r.t. the second argument of ldexp as not defined since that argument is of integer type. Co-authored-by: David Widmann --- src/rules.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules.jl b/src/rules.jl index 54506c0..16ef295 100644 --- a/src/rules.jl +++ b/src/rules.jl @@ -90,7 +90,7 @@ else end @define_diffrule Base.hypot(x, y) = :( $x / hypot($x, $y) ), :( $y / hypot($x, $y) ) @define_diffrule Base.log(b, x) = :( log($x) * inv(-log($b)^2 * $b) ), :( inv($x) / log($b) ) -@define_diffrule Base.ldexp(x, y) = :( 2^$y ), :(log(2) * $x * 2^$y) +@define_diffrule Base.ldexp(x, y) = :( exp2($y) ), :NaN @define_diffrule Base.mod(x, y) = :( first(promote(ifelse(isinteger($x / $y), NaN, 1), NaN)) ), :( z = $x / $y; first(promote(ifelse(isinteger(z), NaN, -floor(z)), NaN)) ) @define_diffrule Base.rem(x, y) = :( first(promote(ifelse(isinteger($x / $y), NaN, 1), NaN)) ), :( z = $x / $y; first(promote(ifelse(isinteger(z), NaN, -trunc(z)), NaN)) ) From 74193c383c07b4e0cfa81a0e2bfd5b15d0fdf439 Mon Sep 17 00:00:00 2001 From: David Hofmann Date: Wed, 8 Dec 2021 00:23:51 +0100 Subject: [PATCH 3/6] added special test for ldexp since its second argument is required to be an integer and thus non-differentiable. Changed variable name from "non_numeric_arg_functions" to "non_diffable_arg_functions" to be more general and account for the numeric but non-differentiable nature of the second argument of ldexp. --- .vscode/settings.json | 3 +++ src/rules.jl | 2 +- test/runtests.jl | 21 +++++++++++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c774ed3 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "julia.environmentPath": "/home/david/Projects/0Codes/DiffRules.jl" +} \ No newline at end of file diff --git a/src/rules.jl b/src/rules.jl index 16ef295..3899bf3 100644 --- a/src/rules.jl +++ b/src/rules.jl @@ -90,7 +90,7 @@ else end @define_diffrule Base.hypot(x, y) = :( $x / hypot($x, $y) ), :( $y / hypot($x, $y) ) @define_diffrule Base.log(b, x) = :( log($x) * inv(-log($b)^2 * $b) ), :( inv($x) / log($b) ) -@define_diffrule Base.ldexp(x, y) = :( exp2($y) ), :NaN +@define_diffrule Base.ldexp(x, y) = :( exp2($y) ), :NaN @define_diffrule Base.mod(x, y) = :( first(promote(ifelse(isinteger($x / $y), NaN, 1), NaN)) ), :( z = $x / $y; first(promote(ifelse(isinteger(z), NaN, -floor(z)), NaN)) ) @define_diffrule Base.rem(x, y) = :( first(promote(ifelse(isinteger($x / $y), NaN, 1), NaN)) ), :( z = $x / $y; first(promote(ifelse(isinteger(z), NaN, -trunc(z)), NaN)) ) diff --git a/test/runtests.jl b/test/runtests.jl index 533cf93..ce1750a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -13,10 +13,10 @@ end @testset "DiffRules" begin @testset "check rules" begin -non_numeric_arg_functions = [(:Base, :rem2pi, 2), (:Base, :ifelse, 3)] +non_diffeable_arg_functions = [(:Base, :rem2pi, 2), (:Base, :ldexp, 2), (:Base, :ifelse, 3)] for (M, f, arity) in DiffRules.diffrules(; filter_modules=nothing) - (M, f, arity) ∈ non_numeric_arg_functions && continue + (M, f, arity) ∈ non_diffeable_arg_functions && continue if arity == 1 @test DiffRules.hasdiffrule(M, f, 1) deriv = DiffRules.diffrule(M, f, :goo) @@ -91,6 +91,23 @@ for xtype in [:Float64, :BigFloat, :Int64] end end end + +# Treat ldexp separately because of its integer second argument: +derivs = DiffRules.diffrule(:Base, :ldexp, :x, :y) +for xtype in [:Float64, :BigFloat] + for ytype in [:Integer, :UInt64, :Int64] + @eval begin + let + x = $xtype(rand(1 : 10)) + y = $ytype(rand(1 : 10)) + dx, dy = $(derivs[1]), $(derivs[2]) + @test isapprox(dx, finitediff(z -> ldexp(z, y), x), rtol=0.05) + @test isnan(dy) + end + end + end +end + end @testset "diffrules" begin From dc1c0046c3bba65ed2fa172ad09986ac8d1b3e8c Mon Sep 17 00:00:00 2001 From: David Hofmann <1681922+david-hofmann@users.noreply.github.com> Date: Wed, 8 Dec 2021 00:28:20 +0100 Subject: [PATCH 4/6] Delete .vscode directory --- .vscode/settings.json | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c774ed3..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "julia.environmentPath": "/home/david/Projects/0Codes/DiffRules.jl" -} \ No newline at end of file From fd721402dff4e91727b05be081401a4b49b25839 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Sun, 12 Dec 2021 17:50:27 +0100 Subject: [PATCH 5/6] Update tests --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index a02aaad..072c962 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -102,7 +102,7 @@ for xtype in [:Float64, :BigFloat] for ytype in [:Integer, :UInt64, :Int64] @eval begin let - x = $xtype(rand(1 : 10)) + 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) From 4861370cc3d88b9595d184312f467ec5b5d0b3e2 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Sun, 12 Dec 2021 17:50:53 +0100 Subject: [PATCH 6/6] Bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index fc3dfd5..769ec33 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DiffRules" uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.8.0" +version = "1.9.0" [deps] LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688"