function DV = exhaustiveGen(T2FS, reductionMethod, defuzzMethod);

% DV = exhaustiveGen(T2FS, reductionMethod, defuzzMethod);
% defuzzifies a type-2 fuzzy set to give an x-value
% firstly type reduces the type-2 fuzzy set to a type-1 fuzzy set using
% reductionMethod, (ensuring highest z grade is used where more than one
% embedded sets defuzzify to the same centroid,)
% secondly defuzzifies the type-1 set using defuzzMethod
%
% SG 161109, modified 110511, 030615, 151015, 090518

tic
% TYPE REDUCTION [(x,u,z) --> (x,z)] --------------------------------------

resultsPairList = [0; 0]; % initialisation of TRS

sizeT2FS = size(T2FS);
domainSize = sizeT2FS(2); % number of x slices (columns)
coDomainSize = sizeT2FS(1); % number of u slices (rows)

xSlices = linspace(1,domainSize,domainSize); % initialise x-axis
xVector = linspace(0,1,domainSize); % initialise x-axis

lowerES = zeros(1, domainSize); % initialisation of a list of u co-ords defining the ES of the lower MF
upperES = zeros(1, domainSize); % initialisation of a list of u co-ords defining the ES of the upper MF

for columnCounter = 1:domainSize % work through all the columns of the type-2 fuzzy set
    for rowCounter = 1:coDomainSize % work through all the rows of the type-2 fuzzy set
        if T2FS(rowCounter,columnCounter) >= 0.0001
            lowerES(columnCounter) = rowCounter; % u co-ord of lower MF
            break
        end
    end
end

for columnCounter = 1:domainSize % work through all the columns of the type-2 fuzzy set
    for rowCounter = 1:coDomainSize % work through all the rows of the type-2 fuzzy set
        if T2FS(rowCounter,columnCounter) >= 0.0001
            upperES(columnCounter) = rowCounter; % u co-ord of upper MF
        end
    end
end

EScounter = 1;  % initialisation of ES counter
nonRedEScounter = 1;  % initialisation of non-redundant ES counter 
currentES = lowerES;
   
while currentES <= upperES

    uVector = (currentES-1)/(coDomainSize-1);
    for index = 1:domainSize
        zVector(index) = T2FS(currentES(index),index);
    end

    defuzzES = defuzz(xVector, uVector, reductionMethod);
    minES = min(zVector);
 
    resultsPair = [defuzzES; minES]; % pair of (x,z) co-ordinates
    [tf, loc] = ismember(resultsPair(1), resultsPairList(1,:));
    if tf == 1 % if x co-ordinate matches a member of resultsPairList x co-ordinates
        if resultsPair(2) > resultsPairList(2,loc); % if new z co-ordinate is greater than existing z co-ordinate
            resultsPairList(2,loc) = resultsPair(2); % replace old z co-ordinate with new higher z value
        end
    elseif tf == 0 % if x co-ordinate does not match any of resultsPairList x co-ordinates
        resultsPairList = [resultsPairList resultsPair]; % append to matrix comprising list of (x,z) co-ordinates
        nonRedEScounter = nonRedEScounter + 1;
    end
    currentES(domainSize) = currentES(domainSize) + 1;
    EScounter = EScounter + 1;
        
    columnPointer = domainSize;
    while currentES(columnPointer) > upperES(columnPointer)
        currentES(columnPointer) = lowerES(columnPointer);
        columnPointer = columnPointer - 1;
        currentES(columnPointer) = currentES(columnPointer) + 1;
        if (columnPointer == 1) && (currentES(columnPointer) > upperES(columnPointer))
             break
        end
    end
    
end

numberESs = EScounter - 1;

% DEFUZZIFICATION [(x,z) --> x] -------------------------------------------

DV = defuzz(resultsPairList(1,:), resultsPairList(2,:), defuzzMethod); % defuzzify the type-1 fuzzy set 

toc

fprintf('Number of embedded sets: %0.0f \n', numberESs)
fprintf('Defuzzified value: %0.10f \n', DV)
