Bijectors.jl icon indicating copy to clipboard operation
Bijectors.jl copied to clipboard

Matrix factorization bijectors

Open sethaxen opened this issue 2 years ago • 5 comments

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

  • unique QR (usual QR but constraining the diagonal of R to be positive)
  • unique SVD: usual SVD but constraining the first row of U to be positive
  • polar decomposition (QP)
  • LU factorization (if matrix is square with linearly independent columns)
  • eigendecomposition (after fixing an eigenvalue sorting convention and eigenvector sign convention).
  • symmetric eigendecomposition

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 avatar Jun 20 '23 09:06 sethaxen

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 avatar Jun 20 '23 23:06 sethaxen

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 avatar Jun 21 '23 16:06 sethaxen

@torfjelde @devmotion what do you think?

sethaxen avatar Jul 10 '23 19:07 sethaxen

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).

torfjelde avatar Jul 10 '23 20:07 torfjelde