function [Leader_pos,Leader_score] = Whale_Optimization_Algorithm (Func_name,N,Lower,Upper,Maxiter)

fobj = TestFunctions (Func_name); 
D=length(Lower); 
Positions=zeros(N,D);
Leader_Pos=zeros(1,D);
X_RAND=zeros(1,D);
fitness=zeros(1,N);
BEST=zeros(1,D);
 
% Trial fitness value of the bes olution
% This value will be iteratively minimized
% until the predefined algorithm termination 
% criterion is sartisfied 
Leader_score=1e+200;

%% Initializing the trial whale population and 
%% Evaluation of the trial solutions for determing the 
%% current best solution and its respective fitness value   

for i=1:N
  for j=1:D
    % Initialize the spatial positions of  N sized D dimensional whale population 
    Positions(i,j)=Lower(j)+(Upper(j)-Lower(j))*rand; 
  endfor
  % Calculating the fitness value of each whale individual in the population
  fitness(i)=fobj(Positions(i,:)); 
  if(fitness(i)<Leader_score)
     Leader_pos=Positions(i,:); %% Current best solution (Prey individual)
     Leader_score=fitness(i);   %% Fitness value of the current best solution
  end   
endfor

% Inıtialing the iteration counter
iter=1;

while(iter <= Maxiter)
    %% Iteratively adjusted algorithm parameter -- a
    a=2-(iter*(2/Maxiter));
    %% Iteratively adjusted algorithm parameter -- a2
    a2= -1.0 + iter*(-1.0/Maxiter);
    for i=1:N
      r1=rand;   
      r2=rand;
      % Decisive algorithm parameter --A-- 
      % having the effect on exploration and 
      % exploitation phases
      A=2.0.*a.*r1-a;
      % Randomized algorithm parameter --C--
      C=2.0.*r2;   
      % Algorithm parameters --b-- and --l--
      % defining the spiral shape of whale movement
      b=1.0;  
      l=(a2-1.0).*rand + 1.0;
      p=rand;
      if (p<0.5)
        if (abs(A)>=1.0)
          rand_index=ceil(N*rand);
          X_RAND=Positions(rand_index,:);
          Positions(i,:)=X_RAND-A.*abs(C.*X_RAND - Positions(i,:));
          % Applying Eq .1 for  the exploration of undiscovered spaces
          % based on the randomly selected whale 
        elseif(abs(A)<1.0)
          Positions(i,:)=Leader_pos-A.*abs(C.*Leader_pos - Positions(i,:));
          % Discovering the unexplored areas by using Eq.4 based on the current best solution
        endif
      else
          Positions(i,:)=abs(Leader_pos - Positions(i,:)).*exp(b.*l).*cos(l.*2.0.*pi) +  Leader_pos;
          % Executing the exploitation phase of the algorithm through Eq.7 
          % under the guidance of current best solution
      end
    endfor
    %Applying boundary check mechanism
    Positions = boundary (Positions, Lower,Upper,N,D);
    % Updating the current best solution
    for i=1:N
        fitness(i)=fobj(Positions(i,:));
        if(fitness(i)<Leader_score)
           Leader_score=fitness(i);
           Leader_pos=Positions(i,:);
        end  
    end
    % Updating the iteration counter
    iter=iter+1;
end  

endfunction
