gusucode.com > 模糊控制工具箱 fuzzy logic toolbox源码程序 > fuzzy/fuzzy/evalfis1.m
function [output_stack,IRR,ORR,ARR] = evalfis(input_stack, fismatrix); % EVALFIS Evaluation of a fuzzy inference system. % OUTPUT_STACK = EVALFIS(INPUT_STACK, FISMATRIX) computes the % output of a fuzzy inference system specified by FISMATRIX. % INPUT_STACK can be a vector specifying the input vector, or % a matrix where each row specifies an input vector. % OUTPUT_STACK is a stack of output (row) vectors. % % For example: % % [xx, yy] = meshgrid(-5:5); % input = [xx(:) yy(:)]; % fismat = readfis('mam21'); % out = evalfis(input, fismat); % surf(xx, yy, reshape(out, 11, 11)) % title('evalfis') % Roger Jang, 11-19-93, 1-17-94, 9-29-94. % Copyright 1994-2002 The MathWorks, Inc. % $Revision: 1.7 $ $Date: 2002/04/14 22:22:27 $ global GLOBAL_FIS_MATRIX global FIS_NAME FIS_TYPE IN_N OUT_N IN_MF_N OUT_MF_N RULE_N global AND_METHOD OR_METHOD IMP_METHOD AGG_METHOD DEFUZZ_METHOD global BOUND IN_MF_TYPE OUT_MF_TYPE RULE_LIST AND_OR RULE_WEIGHT global IN_PARAM OUT_PARAM global OUT_TEMPLATE_MF OUT_MF QUALIFIED_OUT_MF OVERALL_OUT_MF point_n = 101; mf_para_n = 4; initialization = 1; % Check if initialization necessary. if (size(fismatrix, 1) == size(GLOBAL_FIS_MATRIX, 1)), if (size(fismatrix, 2) == size(GLOBAL_FIS_MATRIX, 2)), if ~isequal(fismatrix,GLOBAL_FIS_MATRIX), initialization = 0; end end end % Unpack data and initialize global variables. if initialization, GLOBAL_FIS_MATRIX = fismatrix; FIS_NAME = fismatrix.name; FIS_TYPE = fismatrix.type; FIS_TYPE(find(FIS_TYPE == 0)) = []; IN_N = length(fismatrix.input); OUT_N = length(fismatrix.output); for i=1:IN_N IN_MF_N(i) = length(fismatrix.input(i).mf); end for i=1:OUT_N OUT_MF_N(i) = length(fismatrix.output(i).mf); end RULE_N = length(fismatrix.rule); AND_METHOD = fismatrix.andMethod; OR_METHOD = fismatrix.orMethod; IMP_METHOD = fismatrix.impMethod; AGG_METHOD = fismatrix.aggMethod; DEFUZZ_METHOD = fismatrix.defuzzMethod; AND_METHOD(find(AND_METHOD == 0)) = []; OR_METHOD(find(OR_METHOD == 0)) = []; IMP_METHOD(find(IMP_METHOD == 0)) = []; AGG_METHOD(find(AGG_METHOD == 0)) = []; DEFUZZ_METHOD(find(DEFUZZ_METHOD == 0)) = []; IN_MF_TYPE=[]; for i=1:IN_N in_bound(i, 1:2)=fismatrix.input(i).range; for j=1:length(fismatrix.input(i).mf) IN_MF_TYPE=strvcat(IN_MF_TYPE, fismatrix.input(i).mf(j).type); end end for i=1:OUT_N out_bound(i, 1:2)=fismatrix.output(i).range; for j=1:length(fismatrix.output(i).mf) OUT_MF_TYPE=strvcat(OUT_MF_TYPE, fismatrix.output(i).mf(j).type); end end BOUND = [in_bound; out_bound]; %%% tmp = getfis(fismatrix, 'rulelist'); %%% for i=1:length(fismatrix.rulenew) %%% RULE_WEIGHT(i,:) = fismatrix.rulenew(i).weight; %%% AND_OR(i,:) = fismatrix.rulenew(i).connective; %%% RULE_LIST(i,:) = fismatrix.rulenew(i).weight; tmp = getfis(fismatrix, 'rulelist'); RULE_WEIGHT = tmp(:, IN_N+OUT_N+1); AND_OR = tmp(:, IN_N+OUT_N+2); RULE_LIST = tmp(:, 1:IN_N+OUT_N); k=1; totalInputMFs=sum(IN_MF_N); totalOutputMFs=sum(OUT_MF_N); IN_PARAM=zeros(totalInputMFs, 4); for i=1:IN_N for j=1:length(fismatrix.input(i).mf) temp=fismatrix.input(i).mf(j).params; IN_PARAM(k,1:length(temp))=temp; k=k+1; end end k=1; OUT_PARAM=zeros(totalOutputMFs, 4); for i=1:OUT_N for j=1:length(fismatrix.output(i).mf) temp=fismatrix.output(i).mf(j).params; OUT_PARAM(k,1:length(temp))=temp; k=k+1; end end if strcmp(FIS_TYPE, 'sugeno'), OUT_PARAM = OUT_PARAM(:, 1:IN_N+1); elseif strcmp(FIS_TYPE, 'mamdani'), OUT_PARAM = OUT_PARAM(:, 1:mf_para_n); else error('Unknown FIS type!'); end if strcmp(FIS_TYPE, 'mamdani'), % Compute OUT_TEMPLATE_MF OUT_TEMPLATE_MF = zeros(sum(OUT_MF_N), point_n); cum_mf = cumsum(OUT_MF_N); for i = 1:sum(OUT_MF_N), tmp = find((cum_mf-i) >= 0); output_index = tmp(1); % index for output OUT_TEMPLATE_MF(i, :) = ... evalmf(linspace(BOUND(IN_N+output_index,1), ... BOUND(IN_N+output_index,2), point_n), ... OUT_PARAM(i, :), deblank(OUT_MF_TYPE(i, :))); end % Reorder to fill OUT_MF, an (RULE_N X point_n*OUT_N) matrix. OUT_MF = zeros(RULE_N, point_n*OUT_N); for i = 1:RULE_N, for j = 1:OUT_N, mf_index = RULE_LIST(i, IN_N+j); index = sum(OUT_MF_N(1:j-1)) + abs(mf_index); if mf_index > 0, % regular MF OUT_MF(i, (j-1)*point_n+1:j*point_n) = ... OUT_TEMPLATE_MF(index, :); elseif mf_index < 0,% Linguistic hedge "NOT" OUT_MF(i, (j-1)*point_n+1:j*point_n) = ... 1 - OUT_TEMPLATE_MF(index, :); else % Don't care (MF index == 0) OUT_MF(i, (j-1)*point_n+1:j*point_n) = ... ones(1, point_n); end end end % Allocate other matrices QUALIFIED_OUT_MF = zeros(RULE_N, point_n*OUT_N); OVERALL_OUT_MF = zeros(1, point_n*OUT_N); end % fprintf('Global variables for %s FIS are initialized\n', FIS_NAME); end % End of initialization % Error checking for input stack m = size(input_stack, 1); n = size(input_stack, 2); if ~((n >= IN_N) | ((n == 1) & (m >= IN_N))), fprintf('The input stack is of size %dx%d,', m, n); fprintf('while expected input vector size is %d.\n', IN_N); error('Exiting ...'); end if ((n == 1) & (m == IN_N)) data_n = 1; input_stack = input_stack'; else data_n = m; end % Allocate output stack output_stack = zeros(data_n, OUT_N); % Iteration through each row of input stack for kkk = 1:data_n, input = input_stack(kkk, :); % Find in_template_mf_value in_template_mf_value = zeros(sum(IN_MF_N), 1); cum_mf = cumsum(IN_MF_N); for i = 1:sum(IN_MF_N), tmp = find((cum_mf-i) >= 0); input_index = tmp(1); in_template_mf_value(i) = ... evalmf(input(input_index), IN_PARAM(i, :), deblank(IN_MF_TYPE(i, :))); end % Reordering to fill in_mf_value, which is an (RULE_N X IN_N) matrix. index = ones(RULE_N, 1)*cumsum([0 IN_MF_N(1:IN_N-1)]) +... abs(RULE_LIST(:, 1:IN_N)); zero_index = find(index == 0); % index for don't care MF index(zero_index) = ones(size(zero_index)); % temp. setting for easy indexing in_mf_value = reshape(in_template_mf_value(index), RULE_N, IN_N); % Take care of don't care (MF index is zero) % tmp1 is the position index for zeor mf index in a AND rule tmp1 = find(((AND_OR(:, ones(IN_N, 1))==1).*(RULE_LIST(:, 1:IN_N)==0))==1); in_mf_value(tmp1) = ones(size(tmp1));% take care of zero index % tmp2 is the position index for zeor mf index in a OR rule tmp2 = find(((AND_OR(:, ones(IN_N, 1))==2).*(RULE_LIST(:, 1:IN_N)==0))==1); in_mf_value(tmp2) = zeros(size(tmp2));% take care of zero index % Take care of linguistic hedge NOT (MF index is negative) neg_index = find(RULE_LIST(:, 1:IN_N) < 0); in_mf_value(neg_index) = 1 - in_mf_value(neg_index); %disp(in_mf_value); % Find the firing strengths % AND_METHOD = 'min' or 'prod'; which is used as function name too % OR_METHOD = 'max' or 'probor'; which is used as function name too firing_strength = zeros(RULE_N, 1); and_index = find(AND_OR == 1); or_index = 1:RULE_N; or_index(and_index) = []; if IN_N ~= 1, firing_strength(and_index) = feval(AND_METHOD, in_mf_value(and_index, :)')'; firing_strength(or_index) = feval(OR_METHOD, in_mf_value(or_index, :)')'; else firing_strength = in_mf_value; end %disp(firing_strength); % Recalculate firing strengths scaled by rule weights firing_strength = firing_strength.*RULE_WEIGHT; % Find output if strcmp(FIS_TYPE, 'sugeno'), template_output = OUT_PARAM*[input(:); 1]; % Output for template % Reordering according to the output part of RULE_LIST; % Negative MF index will becomes positive index = ones(RULE_N, 1)*cumsum([0 OUT_MF_N(1:OUT_N-1)]) +... abs(RULE_LIST(:, IN_N+1:IN_N+OUT_N)); zero_index = find(index == 0); index(zero_index) = ones(zero_index); % temp. setting for easy indexing rule_output = reshape(template_output(index), RULE_N, OUT_N); zero_index = find(RULE_LIST(:, IN_N+1:IN_N+OUT_N) == 0); rule_output(zero_index) = zeros(size(zero_index)); % take care of zero index sum_firing_strength = sum(firing_strength); if sum_firing_strength == 0 fprintf('input = ['); for i=1:IN_N, fprintf('%f ', input(i)); end fprintf(']\n'); error('Total firing strength is zero!'); end if strcmp(DEFUZZ_METHOD, 'wtaver'), output_stack(kkk, :) = firing_strength'*rule_output/sum_firing_strength; elseif strcmp(DEFUZZ_METHOD, 'wtsum'), output_stack(kkk, :) = firing_strength'*rule_output; else error('Unknown defuzzification method!'); end elseif strcmp(FIS_TYPE, 'mamdani'), % Transform OUT_MF to QUALIFIED_OUT_MF % Duplicate firing_strength. tmp = firing_strength(:, ones(1, point_n*OUT_N)); if strcmp(IMP_METHOD, 'prod'), % IMP_METHOD == 'prod' QUALIFIED_OUT_MF = tmp.*OUT_MF; elseif strcmp(IMP_METHOD, 'min'), % IMP_METHOD == 'min' QUALIFIED_OUT_MF = feval(IMP_METHOD, tmp, OUT_MF); else % IMP_METHOD is user-defined tmp1 = feval(IMP_METHOD, [tmp(:)'; OUT_MF(:)']); QUALIFIED_OUT_MF = reshape(tmp1, RULE_N, point_n*OUT_N); end % AGG_METHOD = 'sum' or 'max' or 'probor' or user-defined OVERALL_OUT_MF = feval(AGG_METHOD, QUALIFIED_OUT_MF); for i = 1:OUT_N; output_stack(kkk, i) = defuzz( ... linspace(BOUND(IN_N+i,1), BOUND(IN_N+i,2), point_n), ... OVERALL_OUT_MF(1, (i-1)*point_n+1:i*point_n), ... DEFUZZ_METHOD); end else fprintf('fis_type = %d\n', FIS_TYPE); error('Unknown FIS type!'); end end if nargout >= 2, IRR = in_mf_value; end if strcmp(FIS_TYPE, 'sugeno'), if nargout >= 3, ORR = rule_output; end if nargout >= 4, ARR = firing_strength(:, ones(1,OUT_N)); end else if nargout >= 3, ORR = []; for iii = 1:OUT_N, ORR = [ORR; QUALIFIED_OUT_MF(:,(iii-1)*point_n+1:iii*point_n)]; end ORR = ORR'; end if nargout >= 4, ARR = reshape(OVERALL_OUT_MF, point_n, OUT_N); end end