function [BEST, BESTFITVAL] = Aquila_Optimizer (fobj,N,Lower,Upper,Maxiter)


fobj = TestFunctions (Func_name);
D=length(Lower);
BEST=zeros(1,D);
X=zeros(N,D);
XNEW=zeros(N,D);
fitness=zeros(1,N);
fitnessnew=zeros(1,N);
D1=zeros(1,D);
r=zeros(1,D);
phi=zeros(1,D);
xx=zeros(1,D);
yy=zeros(1,D);
XMEAN2D=zeros(1,D);
lvyvals=zeros(1,D);

alpha=0.1;
delta=0.1;
BESTFITVAL=1e+200;
u=0.0265;
omega=0.005;
phi0=3*pi/2;

 

for j=1:D
  D1(j)=j;
end

%% initial population
for i=1:N
  for j=1:D
    X(i,j)=Lower(j)+(Upper(j)-Lower(j))*rand;
    XNEW(i,j)=X(i,j);
  end
end

X = sortX (X,fobj,N,D);
BEST=X(1,:);

 
iter=1;

    while(iter <= Maxiter)
           
           X=boundary(X, Lower,Upper,N,D);
           
           for i=1:N
               fitness(i)=fobj(X(i,:));
               if (fitness(i)<BESTFITVAL)
                    BESTFITVAL=fobj(X(i,:));
                    BEST=X(i,:);
               end
           end
           
           G2=2*rand-1;
           G1=2*(1-(iter/Maxiter));
           r0=ceil(20*rand);
           r=r0+u.*D1;
           phi=-omega.*D1+phi0;
           xx=r.*cos(phi);
           yy=r.*sin(phi);
           QF= (iter^((2.0*rand-1.0)/((1-Maxiter)*(1-Maxiter))));
           

           if(iter<=0.666*Maxiter)
                  
                 for i=1:N
                     if(rand<0.5)
                        meanX=mean(X(i,:));
                        XNEW(i,:)=BEST.*(1.0-(iter/Maxiter)) + (meanX - BEST).*rand;
                        fitnessnew(i)=fobj(XNEW(i,:));
                            if(fitnessnew(i)<fitness(i))
                               X(i,:)=XNEW(i,:);
                               fitness(i)=fitnessnew(i);
                            end
                     else
                         lvyvals=Levy(D);
                         NRAND=floor(N*rand)+1;
                         XNEW(i,:)=BEST.*lvyvals+X(NRAND,:)+(yy-xx).*rand;
                         if (fitnessnew(i)<fitness(i))
                             X(i,:)=XNEW(i,:);
                             fitness(i)=fitnessnew(i);
                         end 
                     end   
                 end   
           else        
                 for i=1:N
                    if (rand<0.5)
                        XMEAN2D=mean(X);
                        XNEW(i,:)=(BEST-XMEAN2D).*alpha-rand+ (Lower+(Upper-Lower).*rand).*delta ;
                        fitnessnew(i)=fobj(XNEW(i,:));
                            if(fitnessnew(i)<fitness(i))
                               X(i,:)=XNEW(i,:);
                               fitness(i)=fitnessnew(i);
                            end
                    else
                       lvyvals=Levy(D);
                       XNEW(i,:)=QF.*BEST - (G2*X(i,:).*rand) - G1.*lvyvals+rand.*G2;
                       fitnessnew(i)=fobj(XNEW(i,:));
                            if(fitnessnew(i)<fitness(i))
                               X(i,:)=XNEW(i,:);
                               fitness(i)=fitnessnew(i);
                            end
                    end
                 end
           end
           iter=iter+1;
   end

   
endfunction
