-
Notifications
You must be signed in to change notification settings - Fork 32
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
Second derivative of Matern in zero is wrong #517
Comments
This is most likely due to this function _matern(ν::Real, d::Real)
if iszero(d)
return one(d)
else
y = sqrt(2ν) * d
b = log(besselk(ν, y))
return exp((one(d) - ν) * oftype(y, logtwo) - loggamma(ν) + ν * log(y) + b)
end
end The |
Might be due to the hardcoded (constant) value for |
Shouldn't be necessary in ForwardDiff 0.11: It skips measure zero branches (which fixes some problems but broke existing code). |
https://github.com/cgeoga/BesselK.jl https://arxiv.org/pdf/2201.00090.pdf would be a possibility |
wow neat - when is that going to be released? |
The package and paper is mainly concerned with derivatives wrt the order, which does not seem to be the issue in the OP.
I don't know. Initially the change was released in a non-breaking 0.10.X version but it broke a lot of downstream packages that rely on the current behaviour. So it was reverted and re-applied to the master branch but releases are only made in a separate 0.10.X branch without this change recently. I don't think anyone plans to release a 0.11 any time soon because the same thing will happen and nobody wants to invest the time to fix all the broken downstream code. |
@devmotion you are probably right about the references - damn I thought I have seen that somehwere. Can't find it at the moment. Given that the variance of the derivatives is really important for everything, this is not really a corner case and will break working with derivatives of GPs... |
…t) (#10) * enableDiffWrap instead of general * jldoctest * trim jldoctest * warning docs, shorten name * identify broken tests * push broken state (upstream issue) JuliaGaussianProcesses/KernelFunctions.jl#517
Are you interested in a taylor expansion for the if
Same issue with the rationalQuadratic btw (although that does not appear to branch in the same way) julia> using KernelFunctions: RationalQuadraticKernel
julia> k = RationalQuadraticKernel()
Rational Quadratic Kernel (α = 2.0, metric = Distances.Euclidean(0.0))
julia> kx(x,y) = FD.derivative(t->k(x+t, y), 0)
kx (generic function with 1 method)
julia> dk(x,y) = FD.derivative(t->k(x,y+t), 0)
dx (generic function with 1 method)
julia> dk(0,0)
0.0 EDIT: Wikipedia https://en.wikipedia.org/wiki/Mat%C3%A9rn_covariance_function#Taylor_series_at_zero_and_spectral_moments |
but for RationalQuadratic
|
neat so switching to enzyme would at least fix the rational quadratic. |
If I understand your code correctly, you reimplemented kappa (in the first plot you make sure that it results in the same function by comparing it to the reference implementation) and then you take the derivative of this kappa. But your kappa does not have an As autodiff simply takes the derivative of the branch it finds itself in, it will take the derivative of this if case (if d is zero). And the derivative of a constant is zero. |
That's not true in general. ForwardDiff#master is supposed to ignore branches of measure zero. |
But it doesn't at the moment and not in the forseeable future as I understood from the reaction when I asked around about it. And the point of my comment was to explain what the issue was at the moment (and this is probably it). |
From my understanding and experiments, the general Matern implementation doesn't matter for Further down in the file you linked, you can see the code for |
I didn't know that |
Continuing to look into it, it seems the issues with This also explains why ForwardDiff.jl failed. KernelFunctions defines a custom rule for this case (via ChainRules.jl), but ForwardDiff does not use ChainRules as far as I can tell. |
Apologies as I haven't read further up and got linked here from slack, I mean the linked Enzyme issue there is that the derivative of sqrt is undefined at 0. We chose to have it as 0 there instead of nan, which the linked research says is good for a variety of reasons, though added an extra instruction. Cc @martinjm97 |
No, ForwardDiff uses its own definitions (functions with |
@devmotion Do you think adding something like this special rule would be the solution in this context? |
@devmotion fwiw that's how Enzyme defines its abs derivative (see below). Sqrt, however, cannot have this though. julia> using Enzyme
julia> Enzyme.API.printall!(true)
julia> Enzyme.autodiff(Forward, abs, Duplicated(0.0, 1.0))
after simplification :
; Function Attrs: mustprogress nofree nosync readnone willreturn
define double @preprocess_julia_abs_615_inner.1(double %0) local_unnamed_addr #3 !dbg !10 {
entry:
%1 = call {}*** @julia.get_pgcstack() #4
%2 = call double @llvm.fabs.f64(double %0) #4, !dbg !11
ret double %2, !dbg !13
}
; Function Attrs: mustprogress nofree nosync readnone willreturn
define internal double @fwddiffejulia_abs_615_inner.1(double %0, double %"'") local_unnamed_addr #3 !dbg !14 {
entry:
%1 = call {}*** @julia.get_pgcstack() #4
%2 = fcmp fast olt double %0, 0.000000e+00, !dbg !15
%3 = select fast i1 %2, double -1.000000e+00, double 1.000000e+00, !dbg !15
%4 = fmul fast double %"'", %3, !dbg !15
ret double %4
}
(1.0,) |
@wsmoses A bit of a side issue, but would it make sense to have that |
Oh yeah go for it, contributions welcome! |
This is wrong, because for a centered GP$Z$ with covariance function $k$
And$\text{Cov}(Z'(0), Z'(0)) >0$ .
The text was updated successfully, but these errors were encountered: