-
Notifications
You must be signed in to change notification settings - Fork 34
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
[RFC] Add angle bijector #168
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me! I’m not sure why some CIs are broken.
Oh, this actually does not currently work. As noted in the top comment, I'm not even certain how to test it, so no tests have been added. And I don't know what needs to be added for it to be used with Turing. |
As you point out, this does require some changes to how we handle things in Bijectors.jl. Ideally we'd instead have something like IMO the way to go about this is to figure out exactly what we need to change to accomodate non-bijective transformations (preferably continue the discussion in the issue you reference), then we make those, and then this PR follows. It might be possible to add a very hacky support for non-bijective transformations by just relaxing the requirements on |
It might make sense to have a |
We can also expand the definition of space/domain similar to |
I think that is a great idea. |
I am wondering if the type parameter A bijective function requires that the mathematical dimension of the in- and outputs are the same but this dimension is not the same as
Similar to regular Julia functions, one could just drop this requirement and stop trying to reason about outputs/inputs when composing bijectors and throw an error at runtime if they are not compatible. If one wants to reason about in- and outputs, then I think an encoding of the mathematical spaces of inputs and outputs (e.g. with TransformVariables) would be more useful. But I am not sure, if the mathematical description would be sufficient for the batch computations. E.g., one would have to encode the support of a univariate normal distribution and a one-dimensional multivariate normal distribution in different ways probably. And the compatibility of the mathematical spaces does not per se guarantee that the in- and output types of the bijectors are compatibility when composing them. |
Let's have the discussion on the referenced issue (#58), since it's a more general issue than just this PR. |
Please reopen this if needed. |
cc @trappmartin @yebai
As discussed on slack (and in #58), this PR adds an
Angle
"bijector". Given an angleθ ∈ [-π,π]
, the bijector maps to the corresponding point on the surface of the circle and then embeds the point in the 2D plane. That map is bijective with logdetjac of 0. Its left-inverse maps from the 2D plane to the circle via normalization (non-bijective) and then bijectively maps to the angle. Normalization has a singular Jacobian, so the logdetjac is infinite. However, we do know what adjustment to the logpdf is necessary to sample in the unconstrained plane instead, because it's the same as drawing a bivariate normally distributed random variable and then normalizing it to get a uniformly distributed point on the surface of the circle. So the logpdf is that of the bivariate normal distribution. See https://mc-stan.org/docs/2_26/reference-manual/unit-vector-section.html for details.Some issues I ran into:
test_bijector
appears to assume a real Jacobian is used and checks it with AD. Here a real Jacobian is not used.Real
toVector{<:Real}
of length 2. Hence, whileVonMises
is aUnivariateDistribution
,transform(VonMises(0.5))
is not.TransformedDistribution
seems to force it to be, which causes methods likelogpdf(transform(VonMises(0.5)), randn(2)
to fail.