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,
% secondly defuzzifies the type-1 set using defuzzMethod
%
% SG 161109

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

resultsPairList = []; % initialisation of TRS

sizeT2FS = size(T2FS);
domainSize = sizeT2FS(2); % number of x slices (columns)
coDomainSize = sizeT2FS(1); % number of y 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 y co-ords defining the ES of the lower MF
upperES = zeros(1, domainSize); % initialisation of a list of y 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; % y 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; % y co-ord of upper MF
        end
    end
end

EScounter = 1;  % initialisation of ES counter
currentES = lowerES;
   
while currentES <= upperES

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

    defuzzES = defuzz(xVector, yVector, reductionMethod);
    minES = min(zVector);
 
    resultsPair = [defuzzES; minES]; % pair of (x,z) co-ordinates
    resultsPairList = [resultsPairList resultsPair]; % matrix comprising list of (x,z) co-ordinates
    
    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 

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

toc