How do I use fminunc with two variables?

15 views (last 30 days)
Sohyeon
Sohyeon on 1 Apr 2024 at 23:23
Commented: Sohyeon on 2 Apr 2024 at 1:52
I am trying to minize the follwing function q given x and muk where muk is each element of the array mu.
I first created the function q and dq, which is the gradient of q with two variables x and muk to be general.
Then, when I am work with the for loop over the size of mu, I was trying to plug in mu particularly and minize the function, q_, which is now a function of the variable x only. However, my code fails and if you guys can look at it. I'll very much appreciate it.
-------------------------------- Code is here -----------------------------------------------
mu = [1, 10, 100, 1000];
tau = 1 ./ mu;
q = @(x, muk) x(1) + x(2) + (muk / 2) * (x(1)^2 + x(2)^2 - 2)^2;
dq = @(x, muk) [1 + muk * 2 * x(1) * (x(1)^2 + x(2)^2 - 2); 1 + muk * 2 * x(2) * (x(1)^2 + x(2)^2 - 2)];
options = optimoptions('fminunc', 'Algorithm', 'trust-region', 'HessianApproximation', 'bfgs', 'SpecifyObjectiveGradient', true);
x0 = [1; 0];
xk = x0;
for k = 1:length(mu)
a = mu(k);
q_ = @(x)(q(x, a));
dq_ = @(x)(dq(x, a));
dq_2 = dq_(xk);
while norm(dq_2) > tau(k)
[x,fval] = fminunc(q_,xk,options)
xk = x;
dq_2 = dq_(xk);
end
xk
end
And I got these error at [x,fval] = fminunc(q_,xk,options) saying
Error using +
Too many output arguments.
Error in HW4_3>@(x,muk)x(1)+x(2)+(muk/2)*(x(1)^2+x(2)^2-2)^2 (line 6)
q = @(x, muk) x(1) + x(2) + (muk / 2) * (x(1)^2 + x(2)^2 - 2)^2;
Error in HW4_3>@(x)(q(x,a)) (line 18)
q_ = @(x)(q(x, a));
Error in fminunc (line 345)
[f,GRAD] = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial objective function evaluation. FMINUNC cannot continue.

Answers (1)

Torsten
Torsten on 2 Apr 2024 at 0:42
Edited: Torsten on 2 Apr 2024 at 1:17
You tell "fminunc" that you supply the gradient of the objective, but you don't do it.
mu = [1, 10, 100, 1000];
tau = 1 ./ mu;
q = @(x, muk) x(1) + x(2) + (muk / 2) * (x(1)^2 + x(2)^2 - 2)^2;
dq = @(x, muk) [1 + muk * 2 * x(1) * (x(1)^2 + x(2)^2 - 2); 1 + muk * 2 * x(2) * (x(1)^2 + x(2)^2 - 2)];
options = optimoptions('fminunc', 'Algorithm', 'trust-region', 'HessianApproximation', 'bfgs', 'SpecifyObjectiveGradient', true);
x0 = [1; 0];
%xk = x0;
for k = 1:length(mu)
a = mu(k);
%q_ = @(x)(q(x, a));
%dq_ = @(x)(dq(x, a));
%dq_2 = dq_(xk);
%while norm(dq_2) > tau(k)
[x,fval] = fminunc(@(x)q_(x,a,q,dq),x0,options)
%xk = x;
%dq_2 = dq_(xk);
%end
x
end
Local minimum found. Optimization completed because the size of the gradient is less than the value of the optimality tolerance.
x = 2x1
-1.1072 -1.1072
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
fval = -2.1123
x = 2x1
-1.1072 -1.1072
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Local minimum possible. fminunc stopped because the final change in function value relative to its initial value is less than the value of the function tolerance.
x = 2x1
-1.0123 -1.0123
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
fval = -2.0123
x = 2x1
-1.0123 -1.0123
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Local minimum possible. fminunc stopped because the final change in function value relative to its initial value is less than the value of the function tolerance.
x = 2x1
-1.0012 -1.0013
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
fval = -2.0012
x = 2x1
-1.0012 -1.0013
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Local minimum possible. fminunc stopped because the final change in function value relative to its initial value is less than the value of the function tolerance.
x = 2x1
-1.0001 -1.0001
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
fval = -2.0001
x = 2x1
-1.0001 -1.0001
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
function [z gz] = q_(x,a,q,dq)
z = q(x,a);
if nargout > 1
gz = dq(x,a);
end
end

Tags

Community Treasure Hunt

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

Start Hunting!