tpapp / TransformVariables.jl

Transformations to contrained variables from ℝⁿ.
Other
66 stars 14 forks source link

TransformVariables: a subset of optics functionality? #114

Closed aplavin closed 1 year ago

aplavin commented 1 year ago

Looks like all major functionality of TransformVariables is available as optics/lenses, as defined in Accessors. Optics are very general and composable, so maybe it's worth looking into "replacing" TransformVariables usage with optics. If some useful features aren't covered by optics yet, this most likely can be improved.

Simple example along the lines of TransformVariables docs:

julia> using AccessorsExtra, StaticArrays

# @optics may be upstreamed to Accessors proper at some point
julia> o = @optics log(_.μ) log(_.σ) log(_.τ) _.θs[∗]

julia> y = (μ=1, σ=2, τ=3, θs=SVector(4, 5))

julia> getall(y, o)
(0.0, 0.6931471805599453, 1.0986122886681098, 4, 5)

julia> setall(y, o, getall(y, o) .+ 1)
(μ = 2.718281828459045, σ = 5.436563656918091, τ = 8.154845485377137, θs = [5, 6])
tpapp commented 1 year ago

I consider calculating the log determinant of the Jacobian major functionality, and I am not sure how you would implement that with optics. See transform_and_logjac.

Also, a lot of transformations are nonlinear mappings.

Are you sure you read the manual?

aplavin commented 1 year ago

Also, a lot of transformations are nonlinear mappings.

See logs in my example, nonlinear functions work just fine.

calculating the log determinant of the Jacobian

Thanks for pointing this out! Not sure if I totally understand what exactly is meant by Jacobian here. It's commonly defined for vector-to-vector functions, but what's a Jacobian of NamedTuple function as((μ = asℝ, σ = asℝ₊, τ = asℝ₊, θs = as(Array, 8)))?

Optics can easily be differentiated, I regularly compute gradients with them. But don't understand what you mean by Jacobian.

tpapp commented 1 year ago

See https://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant#Jacobian_determinant, https://en.wikipedia.org/wiki/Integration_by_substitution#Substitution_for_multiple_variables, and the docs.

aplavin commented 1 year ago

Yes, that's the definition of log-Jacobian for functions R^n -> R^n (vector -> vector). But what's a Jacobian of a vector -> namedtuple function?

tpapp commented 1 year ago

The Jacobian of the result flattened to a vector. (Edit: for non-bijective transforms, a subset, eg the upper triangle of correlation matrices).

aplavin commented 1 year ago

I see... This very specific functionality is not available out of the box in Accessors. One can use regular autodiff there to find gradients/jacobians/..., but need to specify both input(s) and output(s) of the differentiated function instead of them being implicit. Sorry for bothering with the suggestion then. I made this issue just because earlier at some point I used TransformVariables for transform/inverse, and now optics replaced that functionality for me.

tpapp commented 1 year ago

No worries, suggestions are always welcome. Yes, this functionality is very specific to Bayesian estimation / MCMC. I will close the issue for now as I think it is resolved, but if you comment I will reopen it.