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):
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:
- First Matlab Example
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
- Second Matlab Example
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
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
)