function DV = sampling(type2FS, reductionMethod, defuzzMethod, numSamples);

% DV = sampling(type2FS, reductionMethod, defuzzMethod, numSamples);
% 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
% the number of samples (numSamples) is the number of embedded sets (including repetitions) participating in the type reduction
%
% SG 291204, amended 041209

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

resultsPairList = []; % initialisation

sizeType2FS = size(type2FS);

for pass = 1:numSamples % at each pass an embedded set {(x,y,z)} is selected.  The minimum z value is found,
                        % together with the x value of the type reduced (x,y) points, to give an ordered pair (x,z).
    
    xVector = linspace(0,1,sizeType2FS(1));    % initialise x-axis
    zeroVector = linspace(0,0,sizeType2FS(1)); % }
    choiceMatrix = [];                         % } initialisation
    choiceIndexList = [];                      % }
    
    yVector = zeroVector; % initialise to 0s vector of y co-ordinates of selected points
    for columnCounter = 1:sizeType2FS(1) % work through all the columns of the type-2 fuzzy set,
        currentCol = type2FS(:,columnCounter)'; % selecting one element from each, to compile an embedded set
        choiceVector = zeroVector; % initialisation to 0s of vector representing embedded set
        if any(currentCol) ~= 0 % currentCol is not all 0s
            indices = find(currentCol); % find indices of nonzero elements
            range = max(indices) - min(indices) + 1; % number of non-zero elements
            if range == 1 % if there is only one element
                choiceIndex = min(indices); % select that element via its index
            elseif range > 1 % if there is more than one element
                rearrangement = randperm(range);                   % }
                choiceIndex = rearrangement(1) + min(indices) - 1; % } perform random selection process
            end
            yVector(columnCounter) = choiceIndex - 1; % build up the vector of y co-ordinates of selected points
            choiceVector(choiceIndex) = 1; % choiceVector has a 1 at the selected point on the y-axis
        end
        choiceVector = choiceVector';
        choiceMatrix = [choiceMatrix choiceVector]; % build up matrix with 1s at selected points of embedded set, otherwise 0s
    end
    
    embeddedSet = type2FS.*choiceMatrix; % obtain z values of embedded set
    candidateList = max(embeddedSet); % a list of non-zero y values of the embedded set
    
    for index = 1:sizeType2FS(1) % change all the 0s and near-0s in candidateList to 2s
        if candidateList(index) < 0.0001
            candidateList(index) = 2;
        end
    end

    minimum = min(candidateList); % minimum non-zero element of candidateList

    yVector = yVector/(sizeType2FS(1)-1); % normalise the y values in yVector to between 0 and 1
    embeddedSetReductionMethod = defuzz(xVector, yVector, reductionMethod); % defuzzify the embedded set
    resultsPair = [embeddedSetReductionMethod; minimum]; % pair of (x,z) co-ordinates
    resultsPairList = [resultsPairList resultsPair]; % matrix comprising list of (x,z) co-ordinates in no particular order
end

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

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

