Why does this code give me an error?
Show older comments
I want to run the Wild Horse Optimizer (WHO) with my fitness function. It will give me an estimated solution "gBest". Then I want to supply that estimated solution to the local builtin optimizer "sqp" while providing an initial guess as a starting point. My code is below:
clear;clc
u=[-33 33];% desired vector
dim=length(u);
lb=-90*ones(1,dim);
ub= 90*ones(1,dim);
Noise=0;
% Define the objective function
objectiveFunctionForMetaheuristic = @(x) MIMOfunNoise(x,u,Noise) + penaltyTerm(x, u);
objectiveFunctionForLocal = @(x) MIMOfunNoise(x, u, Noise) + penaltyTerm(x, u);
% Initial guess
initialGuess = u;
% Set options for fmincon (SQP solver)
options = optimoptions('fmincon', 'Algorithm', 'sqp', 'Display', 'off');
Runs=30;
% Pre-allocation for WHO algorithm
one=zeros(Runs,1);
time=zeros(Runs,1);
temp=zeros(Runs,dim);
two=zeros(Runs,dim);
% Pre-allocation for SQP algorithm
oneSQP=zeros(Runs,1);
timeSQP=zeros(Runs,1);
tempSQP=zeros(Runs,dim);
twoSQP=zeros(Runs,dim);
nn=0;
for n=1:Runs %------------(2)
nn=nn+1;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Call WHO
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%[time,gBest,gBestScore]=WHO(N,Max_iter,lb,ub,dim,objectiveFunction);
[time,gBest,gBestScore]=WHO(30,500,lb,ub,dim,objectiveFunctionForMetaheuristic);
one(nn)=gBestScore;
temp(nn,:)=gBest;
time1(nn)=time;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%- Swapping
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[~, ix] = sort(u);
[~, ix1(ix)] = sort(temp(nn,:));
two(nn,:) = temp(nn,ix1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Call the SQP
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tic;
%[bestX, fmin] = fmincon(objectiveFunctionForLocal, gBest, [], [], [], [], lb, ub, [], options);
objectiveFunctionForLocal(gBest)
[c,ceq] = nonlinear_constraint(gBest)
[bestX, fmin] = fmincon(objectiveFunctionForLocal, gBest, [], [], [], [], lb, ub, @(x) nonlinear_constraint(x), options, initialGuess);
timeSQP(nn)=toc;
oneSQP(nn)=fmin;
tempSQP(nn,:)=bestX;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%- Swapping
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[~, ix] = sort(u); % u is my desired vector
[~, ix1(ix)] = sort(tempSQP(nn,:));
twoSQP(nn,:) = tempSQP(nn,ix1);
end
%%%%%%%%%%%%%%%%%%%
% Choose best
%%%%%%%%%%%%%%%%%%%
[one1 ind]=sort(one,'descend');
[fitness,ind1]=min(one1);
two1=two(ind1,:);
[one1SQP indSQP]=sort(oneSQP','descend');
[fitnessSQP,ind1SQP]=min(one1SQP);
two1SQP=twoSQP(ind1SQP,:);
% Display results
format compact
fprintf('Global_Sol : %s\n', num2str(round(two1, 4),'%.4f '));
fprintf('Local_Sol : %s\n', num2str(round(two1SQP,4),'%.4f '));
fprintf('Desired : %s\n', num2str(u,'%.4f '));
fprintf('Global_fmin : %f\n', fitness);
fprintf('Local_fmin : %f\n', fitnessSQP);
%%%%%%%%%%%%%%%%%%
% Save workspace data
%%%%%%%%%%%%%%%%%
%save 2sn0dB
function e=MIMOfunNoise(b,u,Noise)
M=6; % const1
N=6; % const2
K=length(u);%const3
d = 0.5; % const4
vec = @(MAT) MAT(:);
vecH = @(MAT) MAT(:).';
steerVecT = @(ang) exp(1j*2*pi*d*(0:M-1).'*sin(vecH(ang)));
steerVecR = @(ang) exp(1j*2*pi*d*(0:N-1).'*sin(vecH(ang)));
%%%%%%%%%%%%%%%%%%%%
% Swapping vector b
%%%%%%%%%%%%%%%%%%%%
[~, ix] = sort(u);
[~, ix1(ix)] = sort(b);
b = b(ix1);
A = ones(K, 1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Calculation of yo and ye
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
yo = yMatTR(deg2rad(u), steerVecT, steerVecR);
yo=awgn(yo,Noise);
ye = yMatTR(deg2rad(b), steerVecT, steerVecR);
%%%%%%%%%%%%%%%%%%
% MSE
%%%%%%%%%%%%%%%%%%
e=norm(yo-ye).^2/(M*N);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% User defined function called within MIMOfunNoise
%%%%%%%%%%%%%%%%%%%%%%%%5%%%
function y = yMatTR(targetAngle, steerVecT, steerVecR)
steerA = steerVecT(targetAngle);
steerB = steerVecR(targetAngle);
y=sum( steerA.*permute(steerB,[3,2,1]) ,2);
y=y(:);
end
function penalty = penaltyTerm(x, desiredResult)
% Define a penalty term based on the deviation from the desired result
penalty = 100 * sum((x - desiredResult).^2);
end
function [X]=initialization(N,dim,up,down)
if size(up,1)==1
X=rand(N,dim).*(up-down)+down;
end
if size(up,1)>1
for i=1:dim
high=up(i);low=down(i);
X(:,i)=rand(1,N).*(high-low)+low;
end
end
end
function Stallion=exchange(Stallion)
nStallion=length(Stallion);
for i=1:nStallion
[value,index]=min([Stallion(i).group.cost]);
if value<Stallion(i).cost
bestgroup=Stallion(i).group(index);
Stallion(i).group(index).pos=Stallion(i).pos;
Stallion(i).group(index).cost=Stallion(i).cost;
Stallion(i).pos=bestgroup.pos;
Stallion(i).cost=bestgroup.cost;
end
end
end
% Developed in MATLAB R2017b
% Source codes demo version 1.0
% _____________________________________________________
% Author, inventor and programmer: Iraj Naruei and Farshid Keynia,
% e-Mail: irajnaruei@iauk.ac.ir , irajnaruei@yahoo.com
% _____________________________________________________
% Co-author and Advisor: Farshid Keynia
%
% e-Mail: fkeynia@gmail.com
% _____________________________________________________
% Co-authors: Amir Sabbagh Molahoseyni
%
% e-Mail: sabbagh@iauk.ac.ir
% _____________________________________________________
% You can find the Wild Horse Optimizer code at
% _____________________________________________________
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Max_iter: maximum iterations, N: populatoin size, Convergence_curve: Convergence curve
%function [Convergence_curve,gBest,gBestScore]=WHO(N,Max_iter,lb,ub,dim,fobj)
function [time,gBest,gBestScore]=WHO(N,Max_iter,lb,ub,dim,fobj)
tic; % By Me
if size(ub,1)==1
ub=ones(1,dim).*ub;
lb=ones(1,dim).*lb;
end
PS=0.2; % Stallions Percentage
PC=0.13; % Crossover Percentage
NStallion=ceil(PS*N); % number Stallion
Nfoal=N-NStallion;
Convergence_curve = zeros(1,Max_iter);
gBest=zeros(1,dim);
gBestScore=inf;
%create initial population
empty.pos=[];
empty.cost=[];
group=repmat(empty,Nfoal,1);
for i=1:Nfoal
group(i).pos=lb+rand(1,dim).*(ub-lb);
group(i).cost=fobj(group(i).pos);
end
Stallion=repmat(empty,NStallion,1);
for i=1:NStallion
Stallion(i).pos=lb+rand(1,dim).*(ub-lb);
Stallion(i).cost=fobj(Stallion(i).pos);
end
ngroup=length(group);
a=randperm(ngroup);
group=group(a);
i=0;
k=1;
for j=1:ngroup
i=i+1;
Stallion(i).group(k)=group(j);
if i==NStallion
i=0;
k=k+1;
end
end
Stallion=exchange(Stallion);
[value,index]=min([Stallion.cost]);
WH=Stallion(index); % global
gBest=WH.pos;
gBestScore=WH.cost;
Convergence_curve(1)=WH.cost;
l=2; % Loop counter
while l<Max_iter+1
TDR=1-l*((1)/Max_iter);
for i=1:NStallion
ngroup=length(Stallion(i).group);
[~,index]=sort([Stallion(i).group.cost]);
Stallion(i).group=Stallion(i).group(index);
for j=1:ngroup
if rand>PC
z=rand(1,dim)<TDR;
r1=rand;
r2=rand(1,dim);
idx=(z==0);
r3=r1.*idx+r2.*~idx;
rr=-2+4*r3;
Stallion(i).group(j).pos= 2*r3.*cos(2*pi*rr).*(Stallion(i).pos-Stallion(i).group(j).pos)+(Stallion(i).pos);
else
A=randperm(NStallion);
A(A==i)=[];
a=A(1);
c=A(2);
% B=randperm(ngroup);
% BB=randperm(ngroup);
% b1=B(1);b2=BB(1);
x1=Stallion(c).group(end).pos;
x2=Stallion(a).group(end).pos;
y1=(x1+x2)/2; % Crossover
Stallion(i).group(j).pos=y1;
end
Stallion(i).group(j).pos=min(Stallion(i).group(j).pos,ub);
Stallion(i).group(j).pos=max(Stallion(i).group(j).pos,lb);
Stallion(i).group(j).cost=fobj(Stallion(i).group(j).pos);
end
% end
%
% for i=1:NStallion
R=rand;
% z=rand(1,dim)<TDR;
% r1=rand;
% r2=rand(1,dim);
% idx=(z==0);
% r3=r1.*idx+r2.*~idx;
% rr=-2+4*r3;
if R<0.5
k= 2*r3.*cos(2*pi*rr).*(WH.pos-(Stallion(i).pos))+WH.pos;
else
k= 2*r3.*cos(2*pi*rr).*(WH.pos-(Stallion(i).pos))-WH.pos;
end
k=min(k,ub);
k=max(k,lb);
fk=fobj(k);
if fk<Stallion(i).cost
Stallion(i).pos =k;
Stallion(i).cost=fk;
end
end
Stallion=exchange(Stallion);
[value,index]=min([Stallion.cost]);
if value<WH.cost
WH=Stallion(index);
end
gBest=WH.pos;
gBestScore=WH.cost;
Convergence_curve(l)=WH.cost;
l = l + 1;
time=toc; % By Me
end
end
The WHO and its supported files are in the attachment. But when I run the above code, it gives me an error like this:
Error using abcd>@(x)MIMOfunNoise(x,u,Noise)+penaltyTerm(x,u)
Too many input arguments.
Error in fmincon (line 563)
initVals.f = feval(funfcn{3},X,varargin{:});
Error in abcd (line 61)
[bestX, fmin] = fmincon(objectiveFunctionForLocal, gBest, [], [], [], [], lb, ub, @(x) nonlinear_constraint(x), options, initialGuess);
Caused by:
Failure in initial objective function evaluation. FMINCON
cannot continue.
>>
8 Comments
Torsten
on 24 Feb 2024
Your constraint function "nonlinear_constraint" is missing.
Sadiq Akbar
on 24 Feb 2024
You call "fmincon" and tell him that you want to supply a constraint function "nonlinear_constraint" that "fmincon" will search for. Where is this function ?
[bestX, fmin] = fmincon(objectiveFunctionForLocal, gBest, [], [], [], [], lb, ub, @(x) nonlinear_constraint(x), options, initialGuess);
And what is the "initialGuess" argument for if you want to supply gBest as initial guess ?
It appears that the code was originally authored by Iraj Naruei and Farshid Keynia. Could you please clarify which part of the code you have modified to suit your application? It is important to establish your understanding of the entire code and the extent of your modifications. Without this clarity, it may be challenging to effectively communicate and address programming issues.
Based on logical deduction, I suspect that you may have modified or supplied your own Cost Function, MIMOfunNoise(), but without including constraints in your optimization problem. In the authors' demo, the original fmincon() optimization problem likely required the nonlinear_constraint(x) function. If you run the code without addressing this incompatibility issue, an error is likely to occur.
It is unlikely that any designer who created the Cost Function would not understand whether or not there are constraints placed on the design. Could you please write out the optimization problem in mathematical form? By expressing the problem mathematically, you can later translate it into MATLAB code for implementation.
Sadiq Akbar
on 24 Feb 2024
Sadiq Akbar
on 24 Feb 2024
Sam Chak
on 24 Feb 2024
@Sadiq Akbar, you should check and compare the fmincon() function in your code with the proper syntax of fmincon as shown below:
[bestX, fmin] = fmincon(objectiveFunctionForLocal, ... % cost function
gBest, ... % initial point
[], ... % A
[], ... % b
[], ... % Aeq
[], ... % beq
lb, ... % lower bound
ub, ... % upper bound
@(x) nonlinear_constraint(x), ... % nonlinear inequalities
options, ... % optimoptions()
initialGuess); % ???

Rena Berman
on 15 Mar 2024
(Answers Dev) Restored edit
Answers (2)
Hi @Sadiq Akbar
If nonlinear inequality constraints are not available, you can disable them in the code. It appears that the updated code now returns some results. Please verify and check.
% [c,ceq] = nonlinear_constraint(gBest)
[bestX, fmin] = fmincon(objectiveFunctionForLocal, gBest, [], [], [], [], lb, ub, [], options)
%%%%%%%%%%%%%%%%%%%
% Choose best
%%%%%%%%%%%%%%%%%%%
[one1 ind]=sort(one,'descend');
[fitness,ind1]=min(one1);
two1=two(ind1,:);
[one1SQP indSQP]=sort(oneSQP','descend');
[fitnessSQP,ind1SQP]=min(one1SQP);
two1SQP=twoSQP(ind1SQP,:);
% Display results
format compact
fprintf('Global_Sol : %s\n', num2str(round(two1, 4),'%.4f '));
fprintf('Local_Sol : %s\n', num2str(round(two1SQP,4),'%.4f '));
fprintf('Desired : %s\n', num2str(u,'%.4f '));
fprintf('Global_fmin : %f\n', fitness);
fprintf('Local_fmin : %f\n', fitnessSQP);
2 Comments
Sadiq Akbar
on 24 Feb 2024
Sam Chak
on 24 Feb 2024
You're welcome, @Sadiq Akbar. I simply fixed the fmincon syntax in the optimization code to get it running. As for why the GA-SQP hybrid is expected to perform better in your problem, I cannot provide a definitive answer at the moment.
Walter Roberson
on 24 Feb 2024
[bestX, fmin] = fmincon(objectiveFunctionForLocal, gBest, [], [], [], [], lb, ub, @(x) nonlinear_constraint(x), options, initialGuess);
fmincon() does not expect an initialGuess parameter. It sees the initialGuess as an extra parameter. What it does with that extra parameter is no longer documented: it passes that extra parameter as an extra parameter to objectiveFunctionForLocal and as an extra parameter to @(x) nonlinear_constraint(x) too. But
objectiveFunctionForLocal = @(x) MIMOfunNoise(x, u, Noise) + penaltyTerm(x, u);
expects only a single parameter, and so gives an error when the extra parameter intialGuess is passed to it.
1 Comment
Sadiq Akbar
on 25 Feb 2024
Categories
Find more on Systems of Nonlinear Equations 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!