# Automatic Differentiation of arbitrary-order derivatives

**URL:** https://discourse.julialang.org/t/automatic-differentiation-of-arbitrary-order-derivatives/33774
**Category:** Numerics
**Created:** [January 25, 2020, 6:17am UTC](https://discourse.julialang.org/t/automatic-differentiation-of-arbitrary-order-derivatives/33774 "2020-01-25T06:17:31Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![GregVernon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregvernon/32/5611_2.png) [@GregVernon](https://discourse.julialang.org/u/GregVernon)
#### Post date: [January 25, 2020, 6:17am UTC](https://discourse.julialang.org/t/automatic-differentiation-of-arbitrary-order-derivatives/33774/1 "2020-01-25T06:17:32Z")

</div>

I was wondering if it is possible to _programmatically_ do higher-order automatic differentiation using ForwardDiff (or ReverseDiff).

Here’s a MWE that shows a non-optimal way to get specific derivatives (hard-coded):

```julia
import ForwardDiff

function myFun(degree,variate)
    f = (variate^2 - 1)^degree
    return f
end

# Pick a degree
degree = 4

# Make functions for arbitrarily high derivatives
D1(x) = ForwardDiff.derivative(x->myFun(degree,x),x)
D2(x) = ForwardDiff.derivative(x->ForwardDiff.derivative(x->myFun(degree,x),x),x)
D3(x) = ForwardDiff.derivative(x->ForwardDiff.derivative(x->ForwardDiff.derivative(x->myFun(degree,x),x),x),x)
D4(x) = ForwardDiff.derivative(x->ForwardDiff.derivative(x->ForwardDiff.derivative(x->ForwardDiff.derivative(x->myFun(degree,x),x),x),x),x)
# etc

## Evaluate the derivatives at a point
v1 = D1(sqrt(2)/4)
v2 = D2(sqrt(2)/4)
v3 = D3(sqrt(2)/4)
v4 = D4(sqrt(2)/4)
# etc

```

But I would like something that provides the same functionality / user-experience as these MATLAB MWEs:

1. First Matlab Example

```matlab
clear
x = sym('x','real');
degree = sym('degree',{'positive','integer'});

nDeriv = 4; % I want the 4th derivative in this case, but this could be...
% nDeriv = randi([0 100])
f(x,degree) = (x^2 - 1) ^ degree; % Define f(x) as symbolic function
df = diff(f,x,nDeriv); % Construct a function that evaluates the value of the 4th derivative at a point

deg = 4;
df_val = df(sqrt(2)/4,deg) % Compute the 4th derivative at a point - is symbolic
df_val = double(df_val) % Cast to a double

```

1. Second Matlab Example

```matlab
clear
x = sym('x','real');
degree = sym('degree',{'positive','integer'});

nDeriv = 4; % I want the 4th derivative in this case, but this could be...
% nDeriv = randi([0 100])
f(x,degree) = (x^2 - 1) ^ degree; % Define f(x) as symbolic function
for n = 0:nDeriv
    if n == 0
        df = f;
    else
        df = diff(df,x); % Construct a function that evaluates the value of the 4th derivative at a point
    end
end

deg = 4;
df_val = df(sqrt(2)/4,deg) % Compute the 4th derivative at a point - is symbolic
df_val = double(df_val) % Cast to a double

```

I’ve tried doing a Julia code that follows the idea of the second Matlab example

```julia
import ForwardDiff

function myFun(degree,variate)
    f = (variate^2 - 1)^degree
    return f
end

degree = 4
nDeriv = 4
df(x) = x->myFun(degree,x)
for n = 1:nDeriv
    df(x) = ForwardDiff.derivative(x->df(x),x)
end

```

But evaluating `df(sqrt(2)/4)` results in something like `#23 (generic function with 1 method)` instead of returning a double (should be `-9.750000000000007`)

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [January 25, 2020, 6:45am UTC](https://discourse.julialang.org/t/automatic-differentiation-of-arbitrary-order-derivatives/33774/2 "2020-01-25T06:45:25Z")

</div>

Try making df an anonymous function instead of a named function.

---

<div class="post-metadata">

### Author: ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)
#### Post date: [January 25, 2020, 9:14am UTC](https://discourse.julialang.org/t/automatic-differentiation-of-arbitrary-order-derivatives/33774/3 "2020-01-25T09:14:11Z")

</div>

I really like this snippet from [Roots.jl docs](https://nbviewer.jupyter.org/github/JuliaLang/Roots.jl/blob/master/doc/roots.ipynb)

```julia
import ForwardDiff
degree = 4 
myFun(d,x)=(x^2-1)^d
D(f) = x -> ForwardDiff.derivative(f, float(x))
D(f, n) = n > 1 ? D(D(f),n-1) : D(f)
f = x-> myFun(degree, x) 
D(f, 6)(2) #sixth order scalar derivative

```

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [January 25, 2020, 9:36am UTC](https://discourse.julialang.org/t/automatic-differentiation-of-arbitrary-order-derivatives/33774/4 "2020-01-25T09:36:16Z")

</div>

I’m not sure whether this answers your question, but the following package may be of interest:

```julia
julia> using TaylorSeries

julia> t = Taylor1(Float64, 6)
 1.0 t + 𝒪(t⁷)

julia> sqrt(1 + t)/2
 0.5 + 0.25 t - 0.0625 t² + 0.03125 t³ - 0.01953125 t⁴ + 0.013671875 t⁵ - 0.01025390625 t⁶ + 𝒪(t⁷)

julia> myFun(4, 2+t) # longemen3000's function
 81.0 + 432.0 t + 972.0 t² + 1200.0 t³ + 886.0 t⁴ + 400.0 t⁵ + 108.0 t⁶ + 𝒪(t⁷)

julia> 77760 / factorial(6)
108.0

```
