You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I observe an error when updating from ForwardDiff v0.10 to v1.x. The error occurs when differentiating through quadgk integration.
A MWE to reproduce the error is as follows:
using ForwardDiff
using QuadGK
delta = [ 1.0, 10.0 ]
chi = [ 0.03, 0.30 ]
S = inv([ exp(-chi_ * delta_) for delta_ in delta, chi_ in chi ])
g(x) = quadgk(t -> S*x, 0.0, 1.0)[1]
ForwardDiff.jacobian(g, zeros(2))
With ForwardDiff 1.3, I get the following error:
ERROR: LoadError: DomainError with 0.5:
integrand produced Dual{ForwardDiff.Tag{typeof(g), Float64}}(NaN,NaN,NaN) in the interval (0.0, 1.0)
Note that the code does not throw with ForwardDiff v0.10.39.
Also note that when changing the matrx S, e.g. adding a line S .+= 0.5 then above code also works with v1.3.
Honestly, I still don't understand why this is not enabled by default. IMO it's the only sane way to use ForwardDiff - regardless of the performance (which was improved significantly by #777), IMO the default setting should always prioritize correctness. And I think non-NaN-safe mode is just not correct in general: If you input a number without perturbations (ie a non-Dual or a Dual with zero sensitivities), then the output should be unperturbed as well. That is, zero sensitivities should be strong zeros.
Activity
devmotion commentedon Nov 17, 2025
Can you include the full stacktrace in the issue?
sschlenkrich commentedon Nov 17, 2025
Sure, please see below.
My guess is, it has to do with calling
norm(...)on a Dual at zero.sschlenkrich commentedon Nov 17, 2025
I did some further analysis. The error can be traced back to the evaluation of square root at zero.
Consider the following three calcultions of the 2-norm of
xwhich should yield the same result:Output is
I would say, output 2 and 3 should be equal either way. This is probbly a different discussion.
But output 1 should not have
NaNas function value. This is what causes the error inquadgk.As far as I can see, output 1 is linked to the evaluation of
iszero(x). With ForwardDiff v1.x this evaluatesfalse. And this causes division by zero.https://github.com/JuliaLang/LinearAlgebra.jl/blob/b599095ef3da7ba7e950ee4700a3ba0fea047949/src/generic.jl#L588
I understand that
iszero(x)equal tofalseis a deliberate choice/consequence from the change to v1.x. But in my viewnorm(x)should not beNaN.Any chance this could be fixed?
mcabbott commentedon Nov 17, 2025
Xref #547 for some earlier discussion of
norm.devmotion commentedon Nov 17, 2025
As I mentioned in #547,
sqrtbehaves as expected if one enables NaN-safe mode:Honestly, I still don't understand why this is not enabled by default. IMO it's the only sane way to use ForwardDiff - regardless of the performance (which was improved significantly by #777), IMO the default setting should always prioritize correctness. And I think non-NaN-safe mode is just not correct in general: If you input a number without perturbations (ie a non-
Dualor aDualwith zero sensitivities), then the output should be unperturbed as well. That is, zero sensitivities should be strong zeros.The
normcase seems different and I agree with your analysis - it seems due to the (intended) behaviour in ForwardDiff@1, we miss the early exit in https://github.com/JuliaLang/LinearAlgebra.jl/blob/b599095ef3da7ba7e950ee4700a3ba0fea047949/src/generic.jl#L577 for vectors of duals with zero primals. Generally, I thinknormdeserves its own ForwardDiff rule. Then we'd also be able to hit the BLAS version it seems.