for loop for gradient nested within objective function of fmincon

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
%---------------------------------------------------------    

 채택된 답변

Alan Weiss
Alan Weiss 2018년 4월 20일

0 개 추천

It looks to me as if your gradient should have 10 elements.

Did you declare all those variables global in the workspace? Maybe n isn't being passed. For more reliable ways to include extra parameters and avoid global variables, see Passing Extra Parameters.

Alan Weiss

MATLAB mathematical toolbox documentation

추가 답변 (0개)

카테고리

질문:

2018년 4월 19일

댓글:

2018년 4월 23일

Community Treasure Hunt

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

Start Hunting!

Translated by