# Automatic differentation of \`f(x::Real) = f(float(x))\` leads to stackoverflow

**URL:** <https://discourse.julialang.org/t/automatic-differentation-of-f-x-real-f-float-x-leads-to-stackoverflow/16076>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 9, 2018, 2:40pm UTC](https://discourse.julialang.org/t/automatic-differentation-of-f-x-real-f-float-x-leads-to-stackoverflow/16076 "2018-10-09T14:40:26Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 2:40pm UTC](https://discourse.julialang.org/t/automatic-differentation-of-f-x-real-f-float-x-leads-to-stackoverflow/16076/1 "2018-10-09T14:40:26Z")

</div>

Many definitions follow this pattern:

```julia
f(x::AbstractFloat) = 2x # any computation here
f(x::Real) = f(float(x))

```

But then:

```julia
julia> ForwardDiff.derivative(f, 1.)
ERROR: StackOverflowError:
Stacktrace:
 [1] f(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f),Float64},Float64,1}) at ./REPL[3]:1 (repeats 80000 times)

```

Because `float(Dual)` gives `Dual` which is not `AbstractFloat`. Is there a way around this?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 9, 2018, 2:45pm UTC](https://discourse.julialang.org/t/automatic-differentation-of-f-x-real-f-float-x-leads-to-stackoverflow/16076/2 "2018-10-09T14:45:20Z")

</div>

> [@e3c6](#):
>
> Is there a way around this?

1. Ideally, define the operations themselves to work with `Dual`. Then you don’t need to define separate methods. For `*`, `ForwardDiff` does this.
2. In case you need a signature for `Dual`, define that. See various macros in ForwardDiff for that.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [October 9, 2018, 2:49pm UTC](https://discourse.julialang.org/t/automatic-differentation-of-f-x-real-f-float-x-leads-to-stackoverflow/16076/3 "2018-10-09T14:49:06Z")

</div>

See also:

- [https://github.com/JuliaLang/julia/issues/26552](https://github.com/JuliaLang/julia/issues/26552)
- [https://github.com/JuliaDiff/ForwardDiff.jl/issues/261](https://github.com/JuliaDiff/ForwardDiff.jl/issues/261)
- [https://github.com/JuliaDiff/ForwardDiff.jl/issues/324](https://github.com/JuliaDiff/ForwardDiff.jl/issues/324)
- [https://github.com/musm/SLEEF.jl/issues/11](https://github.com/musm/SLEEF.jl/issues/11)

Basically, don’t follow the pattern that Base switched to in 0.7, it’s just not a good idea. Something like [https://github.com/JuliaLang/julia/issues/26552#issuecomment-374958654](https://github.com/JuliaLang/julia/issues/26552#issuecomment-374958654) would turn the `StackOverFlowError` into a `MethodError` that describes exactly what method you need to define, while still doing the right thing for `Real`s that do have the property that `float(x) isa AbstractFloat`.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 2:49pm UTC](https://discourse.julialang.org/t/automatic-differentation-of-f-x-real-f-float-x-leads-to-stackoverflow/16076/4 "2018-10-09T14:49:35Z")

</div>

> [@Tamas\_Papp](#):
>
> 1. Ideally, define the operations themselves to work with `Dual` . Then you don’t need to define separate methods. For `*` , `ForwardDiff` does this.
> 2. In case you need a signature for `Dual` , define that. See various macros in ForwardDiff for that.

I don’t follow. Can you point me to an example, to see what you mean?

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 3:00pm UTC](https://discourse.julialang.org/t/automatic-differentation-of-f-x-real-f-float-x-leads-to-stackoverflow/16076/5 "2018-10-09T15:00:17Z")

</div>

> [@tkoolen](#):
>
> Something like [Fallback math methods for ::Real are likely to call themselves · Issue #26552 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/26552#issuecomment-374958654) would turn the `StackOverFlowError` into a `MethodError` that describes exactly what method you need to define, while still doing the right thing for `Real` s that do have the property that `float(x) isa AbstractFloat` .

What you mean is that I should define instead:

```julia
f(x::Real) = _f(float(x))
_f(x::AbstractFloat) = 2x

```

But then I get a `MethodError`, as you say, so I still don’t get automatic differentiation. Am I forced to explicitly define

```julia
function f(d::ForwardDiff.Dual{T}) where {T}
       x = ForwardDiff.value(d)
       v = f(x)
       g = 2
       ForwardDiff.Dual{T}(v, g * ForwardDiff.partials(d))
end

```

? This is painful for more complicated functions, and really is just what I wanted to avoid by using AD.

Is there a better way?

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [October 9, 2018, 3:22pm UTC](https://discourse.julialang.org/t/automatic-differentation-of-f-x-real-f-float-x-leads-to-stackoverflow/16076/6 "2018-10-09T15:22:47Z")

</div>

If your `f` is somehow ‘primitive’, in the sense that it uses operations that don’t have derivative rules defined for them in ForwardDiff.jl/DiffRules.jl, then you have to define an overload for `Dual`, yes. But if it’s like your example case, I’d just define `f(x::Real) = 2x`. Could you provide a more realistic example where it’s clear why you’d need the `float` call?

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 3:43pm UTC](https://discourse.julialang.org/t/automatic-differentation-of-f-x-real-f-float-x-leads-to-stackoverflow/16076/7 "2018-10-09T15:43:50Z")

</div>

Not at the moment. I had an example, but I figured out a better way to do it.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [October 9, 2018, 4:48pm UTC](https://discourse.julialang.org/t/automatic-differentation-of-f-x-real-f-float-x-leads-to-stackoverflow/16076/8 "2018-10-09T16:48:16Z")

</div>

And another one: [https://github.com/JuliaDiff/ForwardDiff.jl/issues/363](https://github.com/JuliaDiff/ForwardDiff.jl/issues/363).
