 # Promote big duals in ForwardDiff

I’m computing some derivatives of functions where the interior temporarily enters the realm of BigFloat,

``````using ForwardDiff
g(x) = float(log(exp(x*1e6)))
ForwardDiff.derivative(g, 1.0)
``````
``````NaN
``````

In this example, the exponent is too large for float. One can promote a scalar which isn’t a dual, which surprisingly works.

``````using ForwardDiff
g(x) = float(log(exp(x*big(1e6))))
ForwardDiff.derivative(g, 1.0)
``````
``````1.0e+06
``````

Computing a derivative with respect to a BigFloat also works,

``````g2(x) = float(log(exp(x*1e6)))
ForwardDiff.derivative(g2, big(1.0))
``````
``````1.0e+06
``````

However, a naive approach where one attempts to promote a dual does not work.

``````g(x) = float(log(exp(big(x)*1e6)))
ForwardDiff.derivative(g, 1.0)
``````
``````ERROR: LoadError: MethodError: no method matching big(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(g),Float64},Float64,1})
Closest candidates are:
big(::Type{Complex{T}}) where T<:Real at complex.jl:1018
big(::Type{var"#s828"} where var"#s828"<:Integer) at gmp.jl:465
big(::Type{var"#s828"} where var"#s828"<:Rational) at gmp.jl:466
...
``````

A really naive definition would be to define

``````import Base: big
big(x::ForwardDiff.Dual{TG, T}) where {TG, T} = big(one(T)) * x
``````

Since such promotion rules aren’t in ForwardDiff, I’m wondering if there are dangers associated with this latter approach?

2 Likes