Skip to content

Fix construction of NoLogAbsDetJacobian #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 27, 2025
Merged
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
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down
20 changes: 17 additions & 3 deletions src/with_ladj.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
9 changes: 9 additions & 0 deletions test/getjacobian.jl
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
15 changes: 12 additions & 3 deletions test/test_with_ladj.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading