Evaluation of function gives NaN

The division of two functions gives NaN when it is not simplified.
Here is an example code

using ForwardDiff
f(x) = (x-1)^2
df(x) = ForwardDiff.derivative(f,x)
val = f(1)/df(1)

Mathematically this should be 0 but gives NaN.
How do I address such a problem?
Side note: I get the expected value on all other x.

Thank you

If I am not mistaken, you have \text{val} = \frac{(x-1)^2}{2(x-1)} for x=1. That simplifies to \frac{0}{0}, which is often considered undefined.

EDIT: Technically, you could evaluate the expression in the limit as x \to 0. Then \lim_{x \to 0} \frac{(x-1)^2}{2(x-1)} = \lim_{x \to 0} \frac{2(x - 1)}{2} = 0 (L’Hôpital’s rule). But this is not done automatically.


Indeed, running 0.0 / 0.0 in the REPL will return NaN, as specified by IEEE 754. This is what happens here since f(1) == 0 and df(1) == 0 and the division promotes the values to Float64.

Yes, but that is when it is not simplified.
It should be \frac{x-1}{2} on simplification.

Hence my question: how do I address such problems in Julia?

Yes, thank you. I am aware of this. But how should one proceed in such a case?

Julia is not a CAS; expressions are not automatically simplified. You may be interested in Symbolics.jl instead.


Not so, the function is undefined at x=1. The (two-sided) limit exists there, making it a removable singularity.

Define a small function:

julia> f_over_df(x) = isone(x) ? zero(x) : f(x) / df(x)
f_over_df (generic function with 1 method)

You can take the limit analytically yourself, do the algebraic simplification yourself (or via a computer-algebra system like Symbolics.jl), or take a limit numerically, e.g. with Richardson.jl:

julia> using Richardson

julia> extrapolate(x -> f(x) / df(x), 0.5, x0=1)
(0.0, 0.0)

(an estimated limit and an estimated error bar). So it correctly finds that the limit is zero. (Depending on the starting x, there may be some roundoff error, e.g. if you replace 0.5 with 0.1 it finds a limit of about -4.77e-17 due to roundoff errors).

Obviously, your particular example in this thread is so simple that you should just use the analytical form manually, but I’m presuming that you are also interested in other cases that can’t be handled analytically so easily.


Thank you. I like this