diff --git a/Project.toml b/Project.toml index 390d81b..37a0a82 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ChangesOfVariables" uuid = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" -version = "0.1.9" +version = "0.1.10" [deps] InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" diff --git a/README.md b/README.md index 61289d4..3e09ca5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Documentation for stable version](https://img.shields.io/badge/docs-stable-blue.svg)](https://JuliaMath.github.io/ChangesOfVariables.jl/stable) [![Documentation for development version](https://img.shields.io/badge/docs-dev-blue.svg)](https://JuliaMath.github.io/ChangesOfVariables.jl/dev) [![License](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](LICENSE.md) -[![Build Status](https://github.com/JuliaMath/ChangesOfVariables.jl/workflows/CI/badge.svg?branch=master)](https://github.com/JuliaMath/ChangesOfVariables.jl/actions?query=workflow%3ACI) +[![Build Status](https://github.com/JuliaMath/ChangesOfVariables.jl/workflows/CI/badge.svg)](https://github.com/JuliaMath/ChangesOfVariables.jl/actions?query=workflow%3ACI) [![Codecov](https://codecov.io/gh/JuliaMath/ChangesOfVariables.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaMath/ChangesOfVariables.jl) diff --git a/src/with_ladj.jl b/src/with_ladj.jl index 52ec48d..2fcb4ce 100644 --- a/src/with_ladj.jl +++ b/src/with_ladj.jl @@ -80,24 +80,34 @@ export with_logabsdet_jacobian struct NoLogAbsDetJacobian{F,T} An instance `NoLogAbsDetJacobian{F,T}()` signifies that `with_logabsdet_jacobian(::F, ::T)` is not defined. + +Constructors: +```julia +NoLogAbsDetJacobian(f, x) +NoLogAbsDetJacobian{F,T}() +``` """ struct NoLogAbsDetJacobian{F,T} end export NoLogAbsDetJacobian -with_logabsdet_jacobian(::F, ::T) where {F,T} = NoLogAbsDetJacobian{F,T}() +@inline NoLogAbsDetJacobian(::F, ::T) where {F,T} = NoLogAbsDetJacobian{F,T}() +@inline NoLogAbsDetJacobian(::Type{F}, ::T) where {F,T} = NoLogAbsDetJacobian{Type{F},T}() +@inline NoLogAbsDetJacobian(::F, ::Type{T}) where {F,T} = NoLogAbsDetJacobian{F,Type{T}}() +@inline NoLogAbsDetJacobian(::Type{F}, ::Type{T}) where {F,T} = NoLogAbsDetJacobian{Type{F},Type{T}}() +with_logabsdet_jacobian(f, x) = NoLogAbsDetJacobian(f, x) @static if VERSION >= v"1.6" function with_logabsdet_jacobian(f::Base.ComposedFunction, x) y_ladj_inner = with_logabsdet_jacobian(f.inner, x) if y_ladj_inner isa NoLogAbsDetJacobian - NoLogAbsDetJacobian{typeof(f),typeof(x)}() + NoLogAbsDetJacobian(f, x) else y_inner, ladj_inner = y_ladj_inner y_ladj_outer = with_logabsdet_jacobian(f.outer, y_inner) if y_ladj_outer isa NoLogAbsDetJacobian - NoLogAbsDetJacobian{typeof(f),typeof(x)}() + NoLogAbsDetJacobian(f, x) else y, ladj_outer = y_ladj_outer (y, ladj_inner + ladj_outer) @@ -107,6 +117,10 @@ with_logabsdet_jacobian(::F, ::T) where {F,T} = NoLogAbsDetJacobian{F,T}() end +function _with_ladj_on_mapped(@nospecialize(map_or_bc::F), y_with_ladj::NoLogAbsDetJacobian) where {F<:Union{typeof(map),typeof(broadcast)}} + return y_with_ladj +end + function _with_ladj_on_mapped(map_or_bc::F, y_with_ladj::Tuple{Any,Real}) where {F<:Union{typeof(map),typeof(broadcast)}} return y_with_ladj end diff --git a/test/getjacobian.jl b/test/getjacobian.jl index 4766d8a..ff4c480 100644 --- a/test/getjacobian.jl +++ b/test/getjacobian.jl @@ -1,5 +1,7 @@ # This file is a part of ChangesOfVariables.jl, licensed under the MIT License (MIT). +if !isdefined(Main, :getjacobian) + import ForwardDiff torv_and_back(V::AbstractVector{<:Real}) = V, identity @@ -33,4 +35,11 @@ function getjacobian(f, x) ForwardDiff.jacobian(vf, V) end +end # !isdefined(Main, :getjacobian) + + +if !isdefined(Main, :foo) + foo(x) = inv(exp(-x) + 1) + +end # !isdefined(Main, :foo) diff --git a/test/test_with_ladj.jl b/test/test_with_ladj.jl index 5db91c1..ff307f7 100644 --- a/test/test_with_ladj.jl +++ b/test/test_with_ladj.jl @@ -18,11 +18,20 @@ include("getjacobian.jl") _bc_func(f) = Base.Fix1(broadcast, f) end - @test with_logabsdet_jacobian(sum, rand(5)) == NoLogAbsDetJacobian{typeof(sum),Vector{Float64}}() - @test with_logabsdet_jacobian(sum ∘ log, 5.0f0) == NoLogAbsDetJacobian{typeof(sum ∘ log),Float32}() - @test with_logabsdet_jacobian(log ∘ sum, 5.0f0) == NoLogAbsDetJacobian{typeof(log ∘ sum),Float32}() + @test with_logabsdet_jacobian(sum, rand(5)) === NoLogAbsDetJacobian(sum, rand(5)) + @test with_logabsdet_jacobian(log ∘ sum, 5.0f0) === NoLogAbsDetJacobian(log ∘ sum, 5.0f0) @test_throws MethodError _, _ = with_logabsdet_jacobian(sum, rand(5)) + @test with_logabsdet_jacobian(sin, 4.9) === NoLogAbsDetJacobian{typeof(sin), Float64}() + @test with_logabsdet_jacobian(String, 4.9) === NoLogAbsDetJacobian{Type{String}, Float64}() + @test with_logabsdet_jacobian(String, Float64) === NoLogAbsDetJacobian{Type{String}, Type{Float64}}() + @test with_logabsdet_jacobian(sin, Float64) === NoLogAbsDetJacobian{typeof(sin), Type{Float64}}() + + @test with_logabsdet_jacobian(sin ∘ log, 4.9) === NoLogAbsDetJacobian{typeof(sin ∘ log), Float64}() + @test with_logabsdet_jacobian(log ∘ sin, 4.9) === NoLogAbsDetJacobian{typeof(log ∘ sin), Float64}() + + @test with_logabsdet_jacobian(Base.Fix1(broadcast, sin), 4.9) === NoLogAbsDetJacobian{typeof(sin), Float64}() + function ChangesOfVariables.with_logabsdet_jacobian(::typeof(foo), x) y = foo(x) ladj = -x + 2 * log(y)