function [accuarcy,predictLabel,outputValue] = PLECOC_predict(test_data,test_target,model,isLossWeighted)

%PL_ECOC [1] deals with paritial label learning problem by adapting the ECOC techniques [2]
%
%    Syntax
%
% [accuarcy,predictLabel,outputValue] = PLECOC_predict(test_data,test_target,model)
% 
%    Description
%
%       PL_ECOC_predict takes,
%           model                       - the model which returned in the training phase
%           test_data                   - An MxN array, the ith instance of testing instance is stored in test_data(i,:)
%           test_target                 - A QxM array, if the jth class label is the ground-truth label for the ith test instance, then test_target(j,i) equals 1; otherwise test_target(j,i) equals 0
%			isLossweighted              - A bool variable, if using Loss-weighted strategy in decoding phase, isLossWeighted is 1, otherwise it is 0
% 
%      and returns,
%            accuarcy                     - Predictive accuracy on the test set
%            predictLabel                 - A QxM array, if the ith test instance is predicted to have the jth class label, then predictLabel(j,i) is 1, otherwise predictLabel(j,i) is 0
%            outputValue                  - A QxM array, the numerical output of the ith test instance on the jth class label is stored in Outputs(j,i)

  
%
%  [1] M.-L. Zhang, F. Yu, C.-Z. Tang. Disambiguation-free partial label learning. IEEE Transactions on Knowledge and Data Engineering, in press.
%
%  [2] T. G. Dietterich, G. Bakiri. Solving multiclass learning problem via error-correcting output codes. Journal of Artificial Intelligence Research, 1995, 2(1): 263-286.
%
%  [3] C. C. Chang, C. J. Lin. LIBSVM: A library for support vector machines. ACM Transactions on Intelligent Systems and Technology, 2011, 2(3): Article 27.
%

if model.type~='PLECOC'
    error('The input model does not match the prediction model')
end
fea_num = size(test_data,2);
if fea_num ~= model.fea_num
    error('feature size of test data does not match the feature size of training data');
end

if size(test_data,1)~=size(test_target,2)
    error('Length of label vector does match the number of instances');
end

Bin_Pre = [];
value = [];

perfermanceMatrix = model.perfermanceMatrix ;
baseModels = model.baseModels ;
CodingMatrix = model.CodingMatrix ;
CodewordLength = model.CodewordLength;

[num_class,num_test] = size(test_target);
parfor k = 1:CodewordLength
    model = baseModels{k,1};
    testing_label_vector = ones(num_test,1);
    [predicted_label, ~, decision_values] = svmpredict(testing_label_vector, test_data, model);
    Bin_Pre = [Bin_Pre,predicted_label];
    value = [value,decision_values];
end
    outputValue = zeros(num_class,num_test);
    predictLabel = zeros(num_class,num_test);

if isLossWeighted
    %     ELW
    for i = 1:num_test
        bin_pre_tmp = Bin_Pre(i,:);
        decisionValue = value(i,:);
        for j = 1:num_class
            codej = CodingMatrix(j,:);
            common = (bin_pre_tmp==codej).*perfermanceMatrix(j,:)./exp(abs(decisionValue));
            errors = (bin_pre_tmp~=codej).*perfermanceMatrix(j,:).*exp(abs(decisionValue));
            outputValue(j,i) = -sum(common)-sum(errors);
        end
    end
else  
    for i = 1:num_test
        tmpmat = [Bin_Pre(i,:);CodingMatrix];      
        dist = pdist(tmpmat);
        dist_mat = squareform(dist);
        outputValue(:,i) = dist_mat(1,2:end)';
        outputValue(:,i) = -outputValue(:,i);
    end
end

for i = 1:num_test      
    idx = find(outputValue(:,i)==max(outputValue(:,i)));
    tmplist = randperm(length(idx));
    max_idx = idx(tmplist(1));
    predictLabel(max_idx,i) = 1;
end

count=0;
    
for i = 1:num_test
    [~,max_idx1] = max(predictLabel(:,i));
    [~,max_idx2] = max(test_target(:,i));
    if (max_idx1==max_idx2)
        count=count+1;
    end
end
    accuarcy = count/num_test;


