MATLAB: Symbolic differentiation with fminunc

differentiationfminuncminimization

I'm looking at the page for the function fminunc, and they supply the following example of miniminization with an additional supplied gradient:
function [f,g] = rosenbrockwithgrad(x)
% Calculate objective f
f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2;
if nargout > 1 % gradient required
g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1));
200*(x(2)-x(1)^2)];
end
For a simple function like this, the gradient can easily be calculated explicitely. However, I am trying to minimize a very similar function, but with a much more complicated gradient. The gradient can be calculated symbolically with the diff function, but is very lengthy, and I would like to be able to easily change the function f without having to modify all the gradients as well. How can I use diff to calculate the gradient symbolically for use in the fminunc function?

Best Answer

function [f,g] = rosenbrockwithgrad_s(x)
X = sym('x', [1 2]);
% Calculate objective f

F = 100*(X(2) - X(1)^2)^2 + (1-X(1))^2;
f = double( subs(F, X, x) );
if nargout > 1 % gradient required
G = diff(F);
g = double( subs(G, X, x) );
end
However, this would involve repeated calculation of diff(F) symbolically, which is pointless. Instead you would do something like,
function [f, g] = f_and_g(x, F, G)
f = F(x);
if nargout > 1
g = G(x);
end
end
together with (outside)
X = sym('x', [1 2]);
% Calculate objective f
f = 100*(X(2) - X(1)^2)^2 + (1-X(1))^2;
g = diff(f);
F = matlabFunction(f, 'vars', {X});
G = matlabFunction(g, 'vars', {X});
x = fminunc( @(x) f_and_g(x, F, G), x0 )