version 2.2 (1.74 MB) by
Ulrich Reif

Compute ordinary and partial derivatives of arbitrary order.

This is an obsolete version of the AutoDiff toolbox, which is still povided because the next Version 3.0 requests Matlab Release R2016b or higher. It will not be developed any further.

The AutoDiff toolbox contains the audi class for automatic differentiation by means of operator overloading. This allows to evaluate derivatives of arbitrary order of functions depending on an arbitrary number of unknowns. AutoDiff also provides a set of utilities, including differential operators, like Laplacian and curl, Taylor expansion of explicit expressions and solutions of ODEs, and curvature analysis for curves and surfaces. To generate the icon, showing a Klein bottle colored by Gaussian curvature, it suffices to supply the surface parametrization and then call a routine from the AutoDiff library.

Ulrich Reif (2021). AutoDiff_R2015b (https://www.mathworks.com/matlabcentral/fileexchange/56856-autodiff_r2015b), MATLAB Central File Exchange. Retrieved .

Created with
R2017a

Compatible with any release

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!Create scripts with code, output, and formatted text in a single executable document.

Mazin MustafaUlrich ReifAutoDiff does not support builtin spline routines.

Sorry, Uli

SAHello all,

I'm looking for a tool box that performs an extensive automatic (algorithmic) differentiation. By extensive, I mean a toolbox that supports matlab builtin functions such as "save","load", "spline" and "ppval". I was wondering if AutoDiff_R2015b supports these functions. If not, I appreciate if you let me know of any other toolbox that allows such complicated derivatives without using finite differencing. Thank you in advance.

Mahdi S. HosseiniA generalized framework called MaxPol has been recently published and made available here

https://www.mathworks.com/matlabcentral/fileexchange/63294-maxpol-smoothing-and-differentiation-package

MaxPol provides a framework to design variety of numerical differentiation kernels with properties like:

(1) Cutoff (lowpass) design with no side-lob artifacts (for noise-robust case)

(2) Arbitrary order of differentiation

(3) Arbitrary polynomial accuracy

(4) Derivative matrix design

(5) 2D Derivative Kernels with Steering moments

(6) Intuitive examples in Signal and Image processing

Laurent KeersmaekersHi,

It seems like I found the solution by using a different function:

[x,y] = ainit(5.0, 1.0, 2);

p.a = 2;

p.b = 5;

p.c = 3;

f = @(x,y,p) p.a*x^2 + p.b*y^3 + p.c;

J = agrad(f(x,y,p), 0).'

Kind regards,

Laurent Keersmaekers

Laurent KeersmaekersHi,

I have a question regarding the use of parameters stored in a structure.

Suppose I have the following function:

f = @(x,y,p) [p.a*x^2 + p.b*y^3 + p.c];

where p.a, p.b and p.c are constants, stored in a structure.

How do I calculate e.g. the Jacobian [df/dx df/dy] by using the ajac function?

Kind regards,

Laurent Keersmaekers

Ruoxi SunHi Jeremy Chang,

I solved the issue by changing avecinit.m to

x(i,1) = audi(v(i),i,numel(v),2);

hessian requires second order.

Ruoxi SunHi Ulrich,

Thanks for the great toolbox.

I would like to ask whether one can initialize an autodiff variable without specifying its initial value. e.g. x = ainit(5) without specifying 5.

In my case, I would like to get a symbolic-like hessian function, and evaluate it at different initial values later.

Pablo BrubeckJeremy ChangHi Ulrich

thanks for providing such a great toolbox

I would like to ask a simple example

If I have a function with 3 dimension vector as input

f(x)=x1^3+x2^3+x3^3

How do I achieve its hessian matrix

evaluate at,for example,[1,2,3]

I tried

f=@(x) sum(x.^3);

x=avecinit([1,2,3])

S=ahess(f(x),0)

but only got error message

"Order must not be negative."

Could you please tell me how to finish this work?

Thanks a lot!

Philipp GliraThe toolbox is fast, reliable and well documented! Thank you very much.

Talfan EvansHi Ulrich, thanks for following up the previous question so quickly! I found that I needed to implement the fft() function as follows to avoid errors when calculating only the first differential of a function:

function x = fft(x,varargin)

if numel(x)>1

a = cell2mat(vertcat(x.c));

for i = 1:size(a,2)

a(:,i) = fft(a(:,i),varargin{:});

end

for i = 1:numel(x)

for j = 1:numel(x(i).c)

x(i).c{j} = a(i,j);

end

end

else

for i = 1:numel(x.c)

x.c{i} = ifft(x.c{i},varargin{:});

end

end

end

Talfan EvansHi Ulrich, thanks for following up the previous question so quickly! I found that I needed to implement the fft() function as follows to avoid errors when calculating only the first differential of a function:

function x = fft(x,varargin)

if numel(x)>1

a = cell2mat(vertcat(x.c));

for i = 1:size(a,2)

a(:,i) = fft(a(:,i),varargin{:});

end

for i = 1:numel(x)

for j = 1:numel(x(i).c)

x(i).c{j} = a(i,j);

end

end

else

for i = 1:numel(x.c)

x.c{i} = ifft(x.c{i},varargin{:});

end

end

end

Ulrich ReifAdd the following lines to the methods section of audi.m to overload fft:

function x = fft(x,varargin)

for i = 1:numel(x.c)

x.c{i} = fft(x.c{i},varargin{:});

end

end

Adrien PeyracheHi Ulrich, I'd like to produce the AD of a function involving FFTs with respect to the parameters of a smoothing kernel. That is to say, the derivative of the FFT would simply be the FFT of the derivative of the smoothing kernel with the signal, which itself can be computed within the existing framework.

Is there a simple way of incorporating the Matlab's built-in fft function into the AutoDiff framework without writing a custom fft function?

Ulrich ReifThanks for the feedback! For negative integer powers, use inv(a)^n. The computation of fractional powers is much more complicated and would request an audi implementation of the eig command (see my comment of Aug 12).

TNHi Ulrich,

Fantastic toolbox! Is there a reason why you don't want mpower to work with negative nor fractional power? For negative power, would adding a line for b < 0, y = 1/mpower(a,-b) cause any problem?

Thanks,

TN

Ulrich ReifI assume that you want to collect several independent variables in a single input vector. Try this:

Store the file avecinit.m containing the lines

function a = avecinit(v)

for i = numel(v):-1:1

a(i,1) = audi(v(i),i,numel(v),1);

end

Then

f = @(x) x(1:end-1).*x(2:end);

x = avecinit([1 2 4 8]);

J = ajac(f(x),0)

yields the 3x4 Jacobian of f at (1,2,4,8).

Caution: input with more than about 20 variables causes memory problems. Fixing this issue would request a modification of some core routines.

Benjamin SanderseThanks Ulrich. What if the Jacobian is not sparse? How would you extend my example to high dimensions?

Best, Benjamin

Ulrich ReifSparse matrices are not supported and I see no simple way to do that - sorry.

Benjamin SanderseHi Ulrich,

Thanks for the nice submission. I'm trying to use your code to calculate large sparse Jacobian matrices (e.g. 10000x10000) elements. I see I can use your code to compute a Jacobian, for example:

g = @(x1, x2) [x1; x1*(x2^2)];

j = ajac(g,[1 1]);

J = @(x1,x2) j(x1,x2);

J(1,2)

But how to extend this to high dimensions? It seems that using a vector as input to g, j and J does not work.

Regards,

Benjamin

Ulrich ReifThe straightforward (though tedious) way to overload a matrix factorization routine like LU, QR, or SVD is a reimplementation of the basic algorithm, which uses nothing but the overloaded binary operators +,-,*,/.

Khoa TranHi,

How can I overload the singular value decomposition svd function?

Keisuke UTODear Ulrich.

Thank you very much for a nice solution!!

The solution is what I want and beautiful.

Thanks.

Ulrich ReifTo overload concatenation, modify audi.m as follows:

Add to the methods section:

function y = horzcat(varargin)

v = audi.const2audi(varargin);

y = builtin('horzcat',v{:});

end

function y = vertcat(varargin)

v = audi.const2audi(varargin);

y = builtin('vertcat',v{:});

end

function y = cat(dim,varargin)

v = audi.const2audi(varargin);

y = builtin('cat',dim,v{:});

end

Add to the methods(Static) section:

function a = const2audi(a)

for i = 1:numel(a)

if ~isnumeric(a{i})

z = 0*a{i}(1);

end

end

for i = 1:numel(a)

a{i} = a{i} + z(ones(size(a{i})));

end

end

Keisuke UTOThanks for your comment.

I already tried your proposed solution, but the solution needs many changes for applying AD to my existing source codes.

I want to keep existing code unchanged as far as possible and apply AD.

Since an audi object has extra information like differentiation order etc, it's not easy to implement default constructor for constant numeric value, appropriately, is it?

I'll use your solution but hope better solution to apply AD to existing source code.

--

Thank you very much.

Ulrich ReifAlready

x = ainit(0);

y = [x 1]

fails since x and 1 are in different classes and concatenation is not overloaded yet. You may use the workaround

y = [x 1+0*x]

instead.

Keisuke UTOKeisuke UTODear Ulrich.

Thank you very much for an excellent tool!

AutoDiff is very useful, but I cannot differentiate a function that is implemented with a matrix including constants.

e.g

>> f = @(x) [1,x]*[x;2]

>> x = ainit(0.5)

>> y = f(x)

fails.

Do you have any idea for improving this issue?

Keisuke UTOUlrich ReifTo overload bsxfun, insert the lines

function c = bsxfun(f,a,b)

c = f(repmat(a,(size(a)~=1)+(size(a)==1).*size(b)),repmat(b,(size(b)~=1)+(size(b)==1).*size(a)));

end

in the methods section of audi.m.

Ulrich ReifTo get a list of overloaded methods open the documentation by typing ahelp() and go to the section "Overloaded operators and functions".

Khoa TranHi Ulrich, do you think the bsxfun function can be supported soon?

Khoa TranThanks Ulrich so much for this package. Could you please give us a link to the list of overloaded functions?

Jan Hakenberg