function [Weight, History] = IMRelief_1(patterns, targets, Para4IRelief)
% ** mbfunctions for input arguments
mbrealmatrix(patterns)
mbrealrow(targets)

% Structure: Para4IRelief
mbrealscalar(Para4IRelief.it)
mbcharrow(Para4IRelief.distance)
mbcharrow(Para4IRelief.kernel)
mbrealscalar(Para4IRelief.sigma)
mbrealscalar(Para4IRelief.Outlier)

%IM_Relief_1: Relief using EM algorithm for both binary and multiclass problems..
%Here we use the margin difinition that is also used in Relief-F
%NOTE: IM_Relief_1 is different from IM_Relief_2 in the margin difinition.
%INPUT:
%     patterns:  training data: Each column is an observation
%     targets:   class label = {1,2,...C}
%OUTPUT:
%    Weight: weight of features
%--------------------------------------------------------------------------
%by Yijun Sun @University of Florida
%Oct. 15/17/25, Nov 3, 2005/June 2, 2006
%==========================================================================
T = Para4IRelief.it;              % maximum iteration
distance = Para4IRelief.distance; % distance metric
kernel = Para4IRelief.kernel;     % kernel function used to compute probability
sigma = Para4IRelief.sigma;       % kernel width
Outlier = Para4IRelief.Outlier;
%----------------------------------

%Uc          = unique(targets);
Uc=min(targets):max(targets);
if min(Uc)==-1
    targets = targets/2+1.5; %transform targets into {1,2}
end

N_patterns = length(targets);% # of patterns
dim = size(patterns,1);      % Data dimenionality

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Utar's modifications
N=zeros(1,length(Uc));
Pro_NoT_Outlier=zeros(1,N_patterns);
index=zeros(length(Uc),N_patterns);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for n=1:length(Uc)
    temp = find(targets==n);
%    index{n} =temp;
    N(n) = length(temp);
    index(n,1:N(n))=temp;
end
Prioi = N/sum(N);

History = zeros(dim,T+1);
Weight = 1/sqrt(dim)*ones(dim,1);
History(:,1)= Weight;
% -------------------------------------------------------------------------

Difference =1;
t=0;
Theta =[];
while Difference>0.02 & t<T
    t=t+1;
    disp(sprintf('IRELIEF iteration # %d',t));
    NM = zeros(dim,N_patterns);
    NH = zeros(dim,N_patterns);

    for i = 1:N_patterns,
        Prob_dif = 0;
        Prob_same = 0;

        for c = 1:length(Uc)
            switch lower(distance)
                case {'euclidean'}
                    %Temp            = (patterns(:,index{c}) - patterns(:,i)*ones(1,N(c))).^2;
                    Temp            = (patterns(:,index(c,1:N(c))) - patterns(:,i)*ones(1,N(c))).^2;
                case {'block'}
                    %Temp            = abs(patterns(:,index{c}) - patterns(:,i)*ones(1,N(c)));
                    Temp            = abs(patterns(:,index(c,1:N(c))) - patterns(:,i)*ones(1,N(c)));
            end

            if t==1
                dist    = sum(Temp,1)/sqrt(dim);
            else
                dist    = (Weight(:)')*Temp;
            end
            temp_index = find(dist==0);

            switch lower(kernel) %calculate probabilities
                case{'exp'}
                    prob = exp(-dist/sigma);prob(temp_index) = 0;
                    if sum(prob)~=0;prob_1 = prob./sum(prob);else;prob_1=zeros(size(prob));end
                case{'1/d'}
                    switch lower(distance)
                        case {'euclidean'}
                            prob = (1./(dist)).^(1/0.5); %1./sqrt(dist);%
                        case {'block'}
                            prob = 1./(dist);
                    end
                    prob(temp_index) = 0;
                    if sum(prob)~=0;prob_1 = prob./sum(prob);else;prob_1=zeros(size(prob));end
            end

            if targets(i)==c;
                NH(:,i) = Temp*prob_1(:);
                Prob_same = sum(prob)/N(c);
            end
            if targets(i)~=c;
                NM(:,i) = NM(:,i)+ Temp*prob_1(:)*Prioi(c)/(1-Prioi(targets(i)));
                Prob_dif = Prob_dif+sum(prob)/N(c);
            end
        end
        if N(targets(i))>1
            if Outlier ==1
                Pro_NoT_Outlier(i) = Prob_same./(Prob_same+Prob_dif);
                NH(:,i) = NH(:,i)*Pro_NoT_Outlier(i);
                NM(:,i) = NM(:,i)*Pro_NoT_Outlier(i);
            else
                NH(:,i) = NH(:,i);
                NM(:,i) = NM(:,i);
            end
        else
            NM(:,i) = NM(:,i); %for the case where there is only one sample in Class c.
        end
    end

    %NM = NM/(length(Uc)-1);
    C = sum(NM-NH,2);
    C_original = C;
    %Objective_1(t) = (Weight(:)')*C;
    in = find(C<0); C(in)=0;
    %Weight = C/norm(C);
    Weight = C/sqrt(sum(C.^2));
    %Objective(t) = (Weight(:)')*C_original;

    Difference = sqrt(sum((Weight-History(:,t)).^2));
    Theta(t) = Difference;
    History(:,t+1) = Weight;
end

%monitoring the feature weights
% figure(9);plot(Theta,'-o')
% title('Theta');
% xlabel('Number of Iteration');
% ylabel('Difference')
% grid on

return
%End of the code



