function y = EKM(xPoint,wLower,wUpper,maxFlag)

% To implement the EKM algorithms [1]. It is called in centroidIT2.m
% and LWA.m.
%
% [1] Dongrui Wu and Jerry M. Mendel, "Enhanced Karnik-Mendel Algorithms," IEEE
% Trans. on Fuzzy Systems, in press.
%
% Dongrui WU (dongruiw@usc.edu), 5/12/2008
%
% xPoint: x_i
% [wLower, wUpper]: lower and upper membership grades of w_i
% maxFlag: 1, if to output the maximum; -1, if to output the minimum
% xPoint, wLower and wUpper must have the same length.
%

if max(wUpper)==0 & maxFlag>0
    y=max(xPoint);
    return;
end

if max(wLower)==0 & maxFlag<0
    y=min(xPoint);
    return;
end

if length(xPoint)==1
    y=xPoint;
    return;
end

[M,N]=size(xPoint);
if N==1
    xPoint=xPoint';
end

[M,N]=size(wLower);
if N==1
    wLower=wLower';
    wUpper=wUpper';
end

[xSort,xIndex] = sort(xPoint);
lowerSort = wLower(xIndex);
upperSort = wUpper(xIndex);

ly=length(xSort);
if maxFlag<0
    k=round(ly/2.4);
    temp=[upperSort(1:k) lowerSort(k+1:ly)];
else
    k=round(ly/1.7);
    temp=[lowerSort(1:k) upperSort(k+1:ly)];
end
a=sum(temp.*xSort);
b=sum(temp);
y = a/b; 
xIndex = find(xSort > y);
kNew=min(xIndex)-1;
sOld=y+1;

while k~=kNew & abs(y-sOld)>0.0001
    
    mink=min(k,kNew);
    maxk=max(k,kNew);
    
    temp=upperSort(mink+1:maxk)-lowerSort(mink+1:maxk);
    b=b-sign(kNew-k)*sign(maxFlag)*sum(temp);
    a=a-sign(kNew-k)*sign(maxFlag)*sum(temp.*xSort(mink+1:maxk));
    sOld=y;
    y = a/b;
    k=kNew;  
    xIndex = find(xSort > y);
    minIndex = min(xIndex);
    kNew=minIndex-1;
end    