gusucode.com > 模糊控制工具箱 fuzzy logic toolbox源码程序 > fuzzy/fuzzy/genfis2.m
function fismat = genfis2(Xin,Xout,radii,xBounds,options) %GENFIS2 Generates a Sugeno-type FIS using subtractive clustering. % % Given separate sets of input and output data, GENFIS2 generates a fuzzy % inference system (FIS) using fuzzy subtractive clustering. GENFIS2 can be % used to generate an initial FIS for ANFIS training by first applying % subtractive clustering on the data. GENFIS2 accomplishes this by extracting % a set of rules that models the data behavior. The rule extraction method % first uses the SUBCLUST function to determine the number of rules and % antecedent membership functions and then uses linear least squares % estimation to determine each rule's consequent equations. % % FIS = GENFIS2(XIN,XOUT,RADII) returns a Sugeno-type FIS given input data XIN % and output data XOUT. The matrices XIN and XOUT have one column per FIS % input and output, respectively. RADII specifies the range of influence of % the cluster center for each input and output dimension, assuming the data % falls within a unit hyperbox (range [0 1]). Specifying a smaller cluster % radius will usually yield more, smaller clusters in the data, and hence more % rules. When RADII is a scalar it is applied to all input and output % dimensions. When RADII is a vector, it has one entry for each input and % output dimension. % % FIS = GENFIS2(...,XBOUNDS) also specifies a matrix XBOUNDS used to normalize % the data XIN and XOUT into a unit hyperbox (range [0 1]). XBOUNDS is size % 2-by-N, where N is the total number of inputs and outputs. Each column of % XBOUNDS provides the minimum and maximum values for the corresponding input % or output data set. If XBOUNDS is an empty matrix or not provided, the % minimum and maximum data values found in XIN and XOUT, are used as defaults. % % FIS = GENFIS2(...,XBOUNDS,OPTIONS) specifies options for changing the % default algorithm parameters, type HELP SUBCLUST for details. % % Examples % Xin1 = 7*rand(50,1); % Xin2 = 20*rand(50,1)-10; % Xin = [Xin1 Xin2]; % Xout = 5*rand(50,1); % fis = genfis2(Xin,Xout,0.5) specifies a range of influence of 0.5 for % all data dimensions. % % fis = genfis2(Xin,Xout,[0.5 0.25 0.3]) specifies the ranges of influence % in the first, second, and third data dimensions are 0.5, 0.25, and 0.3 % times the width of the data space, respectively. % % fis = genfis2(Xin,Xout,0.5,[0 -10 0; 7 10 5]) specifies the data in % the first column of Xin are scaled from [0 7], the data in the % second column of Xin are scaled from [-10 10], and the data in Xout are % scaled from [0 5]. % % See also SUBCLUST, GENFIS1, ANFIS. % Steve Chiu, 1-25-95 Kelly Liu 4-10-97 % Copyright 1994-2005 The MathWorks, Inc. % $Revision: 1.17.2.2.2.1 $ $Date: 2005/07/17 06:06:23 $ % Reference % S. Chiu, "Fuzzy Model Identification Based on Cluster Estimation," J. of % Intelligent & Fuzzy Systems, Vol. 2, No. 3, 1994. [numData,numInp] = size(Xin); [numData2,numOutp] = size(Xout); if numData ~= numData2 % There's a mismatch in the input and output data matrix dimensions if numData == numOutp % The output data matrix should have been transposed, we'll fix it Xout = Xout'; numOutp = numData2; else error('Mismatched input and output data matrices'); end end if nargin < 5 verbose = 0; if nargin < 4 xBounds = []; end [centers,sigmas] = subclust([Xin Xout],radii,xBounds); else verbose = options(4); [centers,sigmas] = subclust([Xin Xout],radii,xBounds,options); end if verbose disp('Setting up matrix for linear least squares estimation...'); end % Discard the clusters' output dimensions centers = centers(:,1:numInp); sigmas = sigmas(:,1:numInp); % Distance multipliers distMultp = (1.0 / sqrt(2.0)) ./ sigmas; [numRule,foo] = size(centers); sumMu = zeros(numData,1); muVals = zeros(numData,1); dxMatrix = zeros(numData,numInp); muMatrix = zeros(numData,numRule * (numInp + 1)); for i=1:numRule for j=1:numInp dxMatrix(:,j) = (Xin(:,j) - centers(i,j)) * distMultp(j); end dxMatrix = dxMatrix .* dxMatrix; if numInp > 1 muVals(:) = exp(-1 * sum(dxMatrix')); else muVals(:) = exp(-1 * dxMatrix'); end sumMu = sumMu + muVals; colNum = (i - 1)*(numInp + 1); for j=1:numInp muMatrix(:,colNum + j) = Xin(:,j) .* muVals; end muMatrix(:,colNum + numInp + 1) = muVals; end % endfor i=1:numRule sumMuInv = 1.0 ./ sumMu; for j=1:(numRule * (numInp + 1)) muMatrix(:,j) = muMatrix(:,j) .* sumMuInv; end if verbose disp('Solving linear least squares estimation problem...'); end % Compute the TSK equation parameters outEqns = muMatrix \ Xout; % Each column of outEqns now contains the output equation parameters % for an output variable. For example, if output variable y1 is given by % the equation y1 = k1*x1 + k2*x2 + k3*x3 + k0, then column 1 of % outEqns contains [k1 k2 k3 k0] for rule #1, followed by [k1 k2 k3 k0] % for rule #2, etc. if verbose disp('Creating FIS matrix...'); end % Find out the number of digits required for printing out the input, % output, and rule numbers numInDigit = floor(log10(numInp)) + 1; numOutDigit = floor(log10(numOutp)) + 1; numRuleDigit = floor(log10(numRule)) + 1; % Find out the required size of the FIS matrix numRow = 11 + (2 * (numInp + numOutp)) + (3 * (numInp + numOutp) * numRule); numCol = numInp + numOutp + 2; % number of columns required for the rule list strSize = 3 + numInDigit + numOutDigit; % size of name 'sug[numInp][numOutp]' numCol = max(numCol,strSize); strSize = 4 + numInDigit + numRuleDigit; % size of 'in[numInp]mf[numRule]' numCol = max(numCol,strSize); strSize = 5 + numOutDigit + numRuleDigit; % size of 'out[numOutp]fm[numRule]' numCol = max(numCol,strSize); numCol = max(numCol,7); % size of 'gaussmf' is 7 % Set the FIS name as 'sug[numInp][numOutp]' theStr = sprintf('sug%g%g',numInp,numOutp); fismat.name=theStr; % FIS type fismat.type = 'sugeno'; % Number of inputs and outputs %fismat(3,1:2) = [numInp numOutp]; % Number of input membership functions %fismat(4,1:numInp) = numRule * ones(1,numInp); % Number of output membership functions %fismat(5,1:numOutp) = numRule * ones(1,numOutp); % Number of rules %fismat(6,1) = numRule; % Inference operators for and, or, imp, agg, and defuzz(???in this order, kliu) fismat.andMethod = 'prod'; fismat.orMethod = 'probor'; fismat.impMethod = 'prod'; fismat.aggMethod = 'max'; fismat.defuzzMethod = 'wtaver'; rowIndex = 11; % Set the input variable labels for i=1:numInp theStr = sprintf('in%g',i); strSize = length(theStr); fismat.input(i).name = theStr; end % Set the output variable labels for i=1:numOutp theStr = sprintf('out%g',i); strSize = length(theStr); fismat.output(i).name = theStr; end % Set the input variable ranges if length(xBounds) == 0 % No data scaling range values were specified, use the actual minimum and % maximum values of the data. minX = min(Xin); maxX = max(Xin); else minX = xBounds(1,1:numInp); maxX = xBounds(2,1:numInp); end ranges = [minX ; maxX]'; for i=1:numInp fismat.input(i).range = ranges(i,:); end % Set the output variable ranges if length(xBounds) == 0 % No data scaling range values were specified, use the actual minimum and % maximum values of the data. minX = min(Xout); maxX = max(Xout); else minX = xBounds(1,numInp+1:numInp+numOutp); maxX = xBounds(2,numInp+1:numInp+numOutp); end ranges = [minX ; maxX]'; for i=1:numOutp fismat.output(i).range = ranges(i,:); end % Set the input membership function labels for i=1:numInp for j=1:numRule theStr = sprintf('in%gcluster%g',i,j); fismat.input(i).mf(j).name = theStr; end end % Set the output membership function labels for i=1:numOutp for j=1:numRule theStr = sprintf('out%gcluster%g',i,j); fismat.output(i).mf(j).name = theStr; end end % Set the input membership function types for i=1:numInp for j=1:numRule fismat.input(i).mf(j).type = 'gaussmf'; end end % Set the output membership function types for i=1:numOutp for j=1:numRule fismat.output(i).mf(j).type = 'linear'; end end % Set the input membership function parameters colOfOnes = ones(numRule,1); % a column of ones for i=1:numInp for j=1:numRule fismat.input(i).mf(j).params = [sigmas(i) centers(j, i)]; end end % Set the output membership function parameters for i=1:numOutp for j=1:numRule outParams = reshape(outEqns(:,i),numInp + 1,numRule); fismat.output(i).mf(j).params = outParams(:,j)'; end end % Set the membership function pointers in the rule list colOfEnum = [1:numRule]'; for j=1:numRule for i=1:numInp fismat.rule(j).antecedent(i)=colOfEnum(j); end for i=1:numOutp fismat.rule(j).consequent(i) = colOfEnum(j); end % Set the antecedent operators and rule weights in the rule fismat.rule(j).weight=1; fismat.rule(j).connection=1; end