% function [uniqueSol] = findUniqueSolutionsBioInf(sol, n)
% findUniqueSolutionsBioInf discards duplicate clustering solutions in sol
% by comparing the summary information on their clusters; n is the number
% of solutions.
%
% This file is part of Cluster4MetaAnalysis.
%     Cluster4MetaAnalysis is free software: you can redistribute it 
%     and/or modify it under the terms of the GNU General Public License 
%     as published by the Free Software Foundation, either version 3 of 
%     the License, or (at your option) any later version.
% 
%     Cluster4MetaAnalysis is distributed in the hope that it will be 
%     useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
%     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
% 
%     You should have received a copy of the GNU General Public License
%     along with Cluster4MetaAnalysis.  If not, see
%     <http://www.gnu.org/licenses/>.


function [uniqueSol] = findUniqueSolutionsBioInf(sol, n)

% dimensionality of the data
numDim = (size(sol(1).clusterData, 2) - 1)/2;
 
% compare cluster means AND cardinality to find clusters
% shared among all solutions
shared = sol(1).clusterData(:, [1:numDim numDim*2+1]);
for i=2:n
    shared = intersect(shared, sol(i).clusterData(:, [1:numDim numDim*2+1]), 'rows');
end

% get clusters that are not common to all clustering solutions
unshared = setdiff(sol(1).clusterData(:, [1:numDim numDim*2+1]), shared, 'rows');

if (size(unshared, 1) == 0 || size(unshared, 2) == 0) % only one unique solution
    disp('***One unique solution only!***')
    uniqueSol = sol(1);
    return;
else
    % we add a column to keep trace of the number of occurrences
    % of each cluster (identified by mean coordinates and cardinality)
    unshared(:, numDim+2) = ones(size(unshared, 1), 1);    % each cluster appears 
                                                           % just once, for now
    for i=2:n
        temp = setdiff(sol(i).clusterData(:, [1:numDim numDim*2+1]), shared, 'rows');
        unshared(:, numDim+2) = unshared(:, numDim+2) + ismember(unshared(:, 1:numDim+1), temp, 'rows');
        for j=1:size(temp, 1)
            if (~ismember(temp(j, :), unshared(:, 1:numDim+1), 'rows'))
                l = size(unshared, 1) + 1;
                unshared(l, 1:numDim+1) = temp(j, :);
                unshared(l, numDim+2) = 1;
            end
        end     
    end

    
    % find different clusterings by using unshared clusters
    l = size(unshared, 1);
    clLabels = zeros(n, l);

    for i=1:n
        for j=1:l
            if (ismember(unshared(j, 1:numDim+1), sol(i).clusterData(:, [1:numDim numDim*2+1]), 'rows'))
                clLabels(i, j) = 1;            
            end
        end
    end
    [uniq, uniqIdx] = unique(clLabels, 'rows');
    disp('Unique clustering solutions: ');
    numUniq = size(uniq, 1)  % Number of unique solutions
    
    % compute number of occurrences for each unique solution
    clCount = zeros(numUniq, 1);  

    for i=1:n
        for j=1:numUniq
            if (ismember(clLabels(i, :), uniq(j, :), 'rows'))
                clCount(j) = clCount(j) + 1;
                break
            end
        end
    end
    disp('# occurrences of each unique solution: ');
    clCount
    
    % return only unique solutions
    uniqueSol = sol(uniqIdx);
    
end