for loop for gradient nested within objective function of fmincon
Show older comments
Dear all, I am trying to include for-loop to define gradient nested within objective function of fmincon as below. However, I am getting an error saying the number of elements for the gradient has to be 10. How can properly incorporate for-loop in the gradient nested in the objective function?
clc
clear
%%
n = 10;
Q0 = 0;
x0 = zeros(n, 1) + 25;
p0 = 1;
I = 50;
p1 = 1.25;
A1 = -diag(ones(n, 1));
%%
A2 = zeros(n/2, n);
for i = 1:n/2
w = A2(i, :);
j = 2*i;
w(1:2:j) = 1;
w(2:2:j) = -1;
A2(i, :) = w;
end
%%
A3 = zeros(n/2, n);
for i = 1:n/2
w = A3(i, :);
j = 2*i;
w(j) = 1;
A3(i, :) = w;
end
%%
A12 = vertcat(A1, A2);
A = vertcat(A12, A3);
%%
b = zeros(2*n, 1);
for i = 1:2*n
if i <= n
b(i) = 0;
elseif i > n && i <= n + n/2
b(i) = Q0;
elseif i > n + n/2 && i <= n + n/2 + floor((n/2)/2) + 1
b(i) = I/p0;
else
b(i) = I/p1;
end
end
Aeq = [];
beq = [];
lb = [];
ub = [];
nonlcon=[];
options = optimoptions('fmincon','SpecifyObjectiveGradient',true);
sol = fmincon(@myobj,x0,A,b, Aeq, beq, lb, ub, [], options);
%---------------------------------------------------------
function [f, g] = myobj(x)
global I
global p0
global p1
global n
q0 = x(2:2:n/2+1);
a0 = x(1:2:n/2+1);
c0 = ones(length(q0), 1).*I - q0.*p0;
u0= a0.^(1/2).*c0.^(1/2);
q1 = x(n/2+3:2:n);
a1 = x(n/2+2:2:n);
c1 = ones(length(q1), 1).*I - q1.*p1;
u1= a1.^(1/2).*c1.^(1/2);
f = -1*(sum(u0 + u1));
% if nargout > 1
% g = -x;
% end
if nargout > 1
g = [];
for i = 1:n
if mod(i,2)==0
dx = -(1/2 * 1/sqrt(x(i)));
elseif (mod(i,2) ~= 0) && (i <= n/2 + 1)
dx = -(1/2 * (-p0)/sqrt((I - p0*x(i))));
elseif (mod(i,2) ~= 0) && (i > n/2 + 1)
dx = -(1/2 * (-p1)/sqrt((I - p1*x(i))));
end
g = [g;dx];
end
end
end
%---------------------------------------------------------
Accepted Answer
More Answers (0)
Categories
Find more on Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!