Symbolic differentiation with fminunc

3 vues (au cours des 30 derniers jours)
Henry Shackleton
Henry Shackleton le 30 Jan 2019
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?

Réponse acceptée

Walter Roberson
Walter Roberson le 30 Jan 2019
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 )

Plus de réponses (0)

Community Treasure Hunt

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

Start Hunting!

Translated by