TuringLang / Bijectors.jl

Implementation of normalising flows and constrained random variable transformations
https://turinglang.org/Bijectors.jl/
MIT License
196 stars 32 forks source link

Matrix factorization bijectors #274

Open sethaxen opened 1 year ago

sethaxen commented 1 year ago

There are a number of bijective matrix factorizations that it might make sense to include here, e.g.

For each of these, the logdetjacs are known and can be efficiently computed. The factorizations are especially common in random matrix theory. e.g. applying the unique QR polar decomposition to a matrix of IID std normal parameters gives a Q that is uniform on the Stiefel manifold; for the polar decomposition sqrt(P) is Wishart-distributed.

sethaxen commented 1 year ago

It probably makes sense for these bijectors to return a Factorization object but for their inverses to accept not only a Factorization but also an iterable of the factors. e.g. for unique QR, one needs to implement a new QR Factorization as well as an AbstractQ to enforce the sign convention. Since these might be of general interest, maybe it makes sense to make a UniqueFactorizations.jl package that only depends on LinearAlgebra, which could then be used in these bijectors.

sethaxen commented 1 year ago

Or does it make more sense to in an extension to a UniqueFactorizations.jl package, overload the Bijectors interface for functions like UniqueFactorizations.qr? Is there anything in Bijectors expecting all bijectors are a Bijectors.Bijector subtype?

sethaxen commented 1 year ago

@torfjelde @devmotion what do you think?

torfjelde commented 1 year ago

Is there anything in Bijectors expecting all bijectors are a Bijectors.Bijector subtype?

Not really:) It really only lets you have a default implementation for stuff like inverse (which returns the lazy Bijectors.Inverse bijector).

You probably don't even need an extension (unless you want to hook it up to Distributions.jl using stuff like bijector); implementation of ChangesOfVariables.with_logabsdet_jacobian and InverseFunctions.inverse is sufficient to make it possible to use it with Bijectors.jl (but, as mentioned, for hooking into Distributions.jl, an extension might be the way to go).