Why does this code give me an error?
2 views (last 30 days)
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
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); % ???
Answers (2)
Sam Chak
on 24 Feb 2024
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
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.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!