diff --git a/src/rules.jl b/src/rules.jl index d1ca0a2..45104aa 100644 --- a/src/rules.jl +++ b/src/rules.jl @@ -244,6 +244,8 @@ _abs_deriv(x) = signbit(x) ? -one(x) : one(x) @define_diffrule LogExpFunctions.log1mexp(x) = :(-exp($x - LogExpFunctions.log1mexp($x))) @define_diffrule LogExpFunctions.log2mexp(x) = :(-exp($x - LogExpFunctions.log2mexp($x))) @define_diffrule LogExpFunctions.logexpm1(x) = :(exp($x - LogExpFunctions.logexpm1($x))) +@define_diffrule LogExpFunctions.log1pmx(x) = :(-$x / (1 + $x)) +@define_diffrule LogExpFunctions.logmxp1(x) = :((1 - $x) / $x) # binary @define_diffrule LogExpFunctions.xlogy(x, y) = :(log($y)), :($x / $y) diff --git a/test/runtests.jl b/test/runtests.jl index 6618a36..ba687a9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -27,7 +27,7 @@ non_diffeable_arg_functions = [(:Base, :rem2pi, 2), (:Base, :ldexp, 2), (:Base, goo = if $(f in (:asec, :acsc, :asecd, :acscd, :acosh, :acoth)) # avoid singularities with finite differencing rand($T) + $T(1.5) - elseif $(f in (:log, :airyaix, :airyaiprimex)) + elseif $(f in (:log, :airyaix, :airyaiprimex, :logmxp1)) # avoid singularities with finite differencing rand($T) + $T(0.5) elseif $(f === :log1mexp) @@ -40,7 +40,13 @@ non_diffeable_arg_functions = [(:Base, :rem2pi, 2), (:Base, :ldexp, 2), (:Base, # We're happy with types with the correct promotion behavior, e.g. # it's fine to return `1` as a derivative despite input being `Float64`. @test promote_type(typeof($deriv), $T) === $T - @test $deriv ≈ finitediff($M.$f, goo) rtol=1e-2 atol=1e-3 + if $(f in (:log1pmx, :logmxp1)) && $T == Float32 + # These two functions currently don't have fallbacks for `Real` + # arguments, nor optimized implementations for `Float32` + @test_throws MethodError finitediff($M.$f, goo) + else + @test $deriv ≈ finitediff($M.$f, goo) rtol=1e-2 atol=1e-3 + end # test for 2pi functions if $(f === :mod2pi) goo = 4 * pi