-
Notifications
You must be signed in to change notification settings - Fork 4
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
Some small pushfwd
issues
#89
Comments
BTW for @inline function logdensity_def(d::AffinePushfwd{(:λ,)}, x::AbstractArray)
z = d.λ * x
MeasureBase.unsafe_logdensityof(d.parent, z)
end So computing |
Instead of Regarding with_logabsdet_jacobian - ChangesOfVariables can't depend on AD packages, that would make it way too heavy. Also, ForwardDiff isn't necessarily always the right default mechanism. A further complication with logabsdet-via-AD is that it the result often needs to be auto-diffed again, e.g. to get gradients of transformed densities/measures, and not all AD packages supported nested-AD (though ForwardDiff does). This might work as a clean approach for cases where that would perform well: We could have a package AutoDiffLADJs.jl or so (name could be better) that depends on AbstractDifferentiation.jl and provides a function |
Nice! I like this idea, and made a comment in that issue.
Yes, I understand that ForwardDiff isn't always the best approach. The
Then on your last point...
I like this idea. I think it's important for users to be able to build pushforwards easily, but I agree an extension package would be better than making ChangesOfVariables much heavier. |
Regarding the multiple call to |
That's the hope - that's why this is an MB issue ;) |
I think this problem of calling a function multiple time is specific to pushforwards, and doesn't come up in most cases. Here's the typically-called @inline function logdensityof(μ::AbstractMeasure, x)
result = dynamic(unsafe_logdensityof(μ, x))
ifelse(insupport(μ, x) == true, result, oftype(result, -Inf))
end The idea with Oh! Or maybe we just grab https://github.com/longemen3000/CachedFunctions.jl or similar? |
What if we specialize |
Ok, let's try that first. It seemed kind of hacky when I did it for affine transforms, because it's doing an end run around this whole nice system we set up. And it forces going all the way to the root measure, which is kind of weird. But it's quick to implement and will get performance back in line |
I've been exploring our pushforward basics in MeasureBase.jl...
Say we have a uniform measure on$(-\pi/2, \pi/2)$ and want to push that through
asin
. So we doNow, we want to be able to do
We can't use InverseFunctions.jl to get the inverse automatically, because$\mu$ ".
sin
only has a one-sided inverse (not currently handled by that package). This three-argument form ofpushfwd
lets use say "this inverse works on the domain ofThis won't quite work yet, because it doesn't know how to get the logjac. But we can define
And we can test this implementation:
So now our pushforward works:
But let's make a small update to our functions to see what they're really doing:
Our final call now looks like this:
So this is making three calls to
finv
. These areinsupport
logdensity_def
logdensity_def
on the base measureThe base measure is
So this raises a few questions/comments:
finv
once? It's not so bad in this case, but it could sometimes get very expensive. Previously I had aMapsTo
type for this sort of thing, maybe we need to bring that back?finv
(and neverf
) gets me back to thinking it's much more natural in lots of cases to work in terms of a pullbackLebesgue()
. I think the right way to do this is to pushLebesgue()
throughfinv
(or pull back throughf
) and compare the result withmu
.The text was updated successfully, but these errors were encountered: