📄 fuzwizmask.m
字号:
'ShowName','off','DisplayOption','bar',...
'Inputs',num2str(nout),'Position',[x0 yout(1)-30 x0+5 yout(nout)+30]);
for ct=1:nout,
add_line(CB,sprintf('Defuzzification%d/1',ct),sprintf('MuxOut/%d',ct));
end
% Default output values when total firing strength is zero
add_block('built-in/RelationalOperator',[CB,'/Zero Firing Strength?'],...
'Operator','>','Position',[xytfs+[100,-10],xytfs+[120,20]],...
'LogicOutDataTypeMode','Specify via dialog',...
'LogicDataType','''double''');
add_block('built-in/Constant',[CB,'/Zero'],'ShowName','off',...
'Value','0','Position',[xytfs+[50,40],xytfs+[70,60]]);
add_line(CB,[TFS '/1'],'Zero Firing Strength?/1');
add_line(CB,'Zero/1','Zero Firing Strength?/2');
add_block('built-in/Constant',[CB,'/MidRange'],...
'Value','mean(cat(1,fis.output.range),2)',...
'Position',[x0-20 xytfs(2)+60 x0+10 xytfs(2)+80]);
% Construct output
add_block('built-in/Switch',[CB '/Switch'],...
'Position',[x0+50 xytfs(2)-40 x0+80 xytfs(2)+60],...
'Threshold','1');
set_param(OutPort,'Position',[x0+120 xytfs(2)+2 x0+140 xytfs(2)+22]);
add_line(CB,'MuxOut/1','Switch/1');
add_line(CB,'Zero Firing Strength?/1','Switch/2');
add_line(CB,'MidRange/1','Switch/3');
add_line(CB,'Switch/1','Out1/1');
%%%%%%%%%%%%%%%%%%%%%%
% LocalCreateInputMF %
%%%%%%%%%%%%%%%%%%%%%%
function LocalCreateInputMF(CB,fis,j_in)
% Builds subsystem evaluating all MF's for input No. J_IN
% RE: Cannot redraw itself!
% Quick exit if block is uptodate or uninitialized
if isempty(fis) | ~isempty(get_param(CB,'lines'))
return
end
% Parameters
InputMF = fis.input(j_in).mf;
nmf = length(InputMF);
% Quick exit if no MF (cf. SLBTU)
if nmf==0,
add_block('built-in/Terminator',[CB '/Term'],'Position',[100 30 120 50]);
add_line(CB,'In1/1','Term/1');
return
end
% Check if MF names are unique, override them otherwise
InputMF = LocalCheckMFName(InputMF,sprintf('in%d',j_in));
% Add data conversion block
add_block('built-in/DataTypeConversion',[CB,'/DataConv'],...
'OutDataTypeMode','double',...
'Position',[100 140 150 160]);
add_line(CB,'In1/1','DataConv/1')
% Add MF blocks
load_system('fuzblock')
MFLIB = find_system('fuzblock','SearchDepth',1,'MaskType','MF Library');
for ct=1:nmf,
% Add MF block
MFblock = find_system(MFLIB{1},'SearchDepth',1,'MaskType',InputMF(ct).type);
MFblock = MFblock{1};
Nparams = length(get_param(MFblock,'MaskValues'));
MaskValues = cell(1,Nparams);
for ctp = 1:Nparams
MaskValues{ctp} = sprintf('fis.input(%d).mf(%d).params(%d)',j_in,ct,ctp);
end
Dest = sprintf('%s',InputMF(ct).name);
add_block(MFblock,sprintf('%s/%s',CB,Dest),...
'Position',[200 55*ct-25 250 55*ct-5],...
'MaskValues',MaskValues);
add_line(CB,'DataConv/1',[Dest '/1']);
% add_line(CB,'In1/1',[Dest '/1']);
% Add Outport block
add_block('built-in/Outport',sprintf('%s/Out%d',CB,ct),...
'Position',[280 55*ct-20 290 55*ct-10]);
add_line(CB,[Dest '/1'],sprintf('Out%d/1',ct));
end
%%%%%%%%%%%%%%%%%%%%%%%
% LocalCreateOutputMF %
%%%%%%%%%%%%%%%%%%%%%%%
function LocalCreateOutputMF(CB,fis,j_out)
% Builds subsystem evaluating all MF's for output No. j_out
% RE: Cannot redraw itself!
% Quick exit if block is uptodate or uninitialized
if isempty(fis) | ~isempty(get_param(CB,'lines'))
return
end
% Parameters
OutputMF = fis.output(j_out).mf;
nmf = length(OutputMF);
% Add Out blocks (one per MF)
for ct=1:nmf,
add_block('built-in/Outport',sprintf('%s/Out%d',CB,ct),...
'Position',[280 60*ct-25 300 60*ct-5]);
end
% Check if MF names are unique, override them otherwise
OutputMF = LocalCheckMFName(OutputMF,sprintf('out%d',j_out));
switch lower(fis.type)
case 'mamdani'
% Mamdani system
Range = sprintf('linspace(fis.output(%d).range(1),fis.output(%d).range(2),101)',...
j_out,j_out);
for ct=1:nmf,
Params = sprintf('fis.output(%d).mf(%d).params',j_out,ct);
MFvalue = sprintf('%s(%s,%s)',OutputMF(ct).type,Range,Params);
Dest = sprintf('%s',OutputMF(ct).name);
add_block('built-in/Constant',sprintf('%s/%s',CB,Dest),...
'Position',[150 60*ct-30 180 60*ct],...
'Value',MFvalue);
add_line(CB,[Dest '/1'],sprintf('Out%d/1',ct));
end
case 'sugeno'
% Sugeno system
nin = length(fis.input);
% Add input port for linear MF
if any(strcmpi({OutputMF.type},'linear'))
add_block('built-in/Inport',sprintf('%s/In1',CB),...
'Position',[50 100 70 120]);
load_system('fuzwiz');
end
for ct=1:nmf,
if strcmp(OutputMF(ct).type,'constant')
Dest = sprintf('%s(Constant)',OutputMF(ct).name);
Params = sprintf('fis.output(%d).mf(%d).params(1)',j_out,ct);
add_block('built-in/Constant',sprintf('%s/%s',CB,Dest),...
'Position',[150 60*ct-30 180 60*ct],...
'Value',Params);
else
Dest = sprintf('%s',OutputMF(ct).name);
a = sprintf('fis.output(%d).mf(%d).params(1:%d)',j_out,ct,nin);
b = sprintf('fis.output(%d).mf(%d).params(%d)',j_out,ct,nin+1);
add_block('fuzwiz/FIS Linear MF',sprintf('%s/%s',CB,Dest),...
'Position',[150 60*ct-30 200 60*ct],'MaskValues',{a,b});
add_line(CB,'In1/1',[Dest '/1']);
end
add_line(CB,[Dest '/1'],sprintf('Out%d/1',ct));
end
end
%%%%%%%%%%%%%%%%%%%
% LocalCreateRule %
%%%%%%%%%%%%%%%%%%%
function LocalCreateRule(CB,fis,j_rule)
% Builds subsystem evaluating rule No. J_RULE
% Input ports = antecedents + consequents (in this order)
% Output ports = firing strength (scalar) + output MF values for consequents
% RE: Cannot redraw itself!
% Quick exit if no fis model
if isempty(fis)
return
end
Rule = fis.rule(j_rule);
% AND/OR Method
Connection = [CB '/andorMethod'];
Position = get_param(Connection,'Position');
delete_block(Connection);
switch Rule.connection
case 1
% AND connector
switch lower(fis.andMethod)
case 'min'
add_block('built-in/MinMax',Connection,'Inputs','1',...
'Function','min','Position',Position);
case 'prod'
add_block('built-in/Product',Connection,'Inputs','1','Position',Position);
end
case 2
% OR connector
switch lower(fis.orMethod)
case 'max'
add_block('built-in/MinMax',Connection,'Inputs','1',...
'Function','max','Position',Position);
case 'probor'
LocalProborOrMethod(Connection, Position);
end
end
% Imply Method
Imply = [CB '/impMethod'];
Position = get_param(Imply,'Position');
delete_block(Imply);
if strcmpi(fis.type,'mamdani') & strcmpi(fis.impMethod,'min')
add_block('built-in/MinMax',Imply,'Inputs','2',...
'Function', 'min','Position',Position);
else
add_block('built-in/Product',Imply,...
'Inputs','2','Position',Position);
end
%%%%%%%%%%%%%%%%%%%%
% LocalCheckMFName %
%%%%%%%%%%%%%%%%%%%%
function ioMF = LocalCheckMFName(ioMF,iostr)
Names = {ioMF.name};
if length(unique(Names))~=length(Names),
% Some names are repeated: override all names
for ct=1:length(Names)
ioMF(ct).name = sprintf('%smf%d',iostr,ct);
end
else
% Replace / by // to make names ADDBLOCK-friendly
for ct=1:length(Names)
ioMF(ct).name = strrep(ioMF(ct).name,'/','//');
end
end
%%%%%%%%%%%%%%%%%%%%%%%
% LocalProborOrMethod %
%%%%%%%%%%%%%%%%%%%%%%%
function LocalProborOrMethod(Connection, Position)
% Builds a subsystem to implement the probor 'OR' method
% The block has scalar input and output
% Connection is the path and name of the andorMethod block
% Position is the position of the andorMethod block
% Find the path to the fuzzy block libraries
MFLIB = find_system('fuzblock','SearchDepth',1,'MaskType','MF Library');
proborblock_path = find_system(MFLIB{1},'SearchDepth',1,'MaskType','probor OR method');
proborblock_path = proborblock_path{1};
% Add the probor block and connect it to the inports and outports
add_block(proborblock_path, Connection,'Position',Position);
%%%%%%%%%%%%%%%%%%%%%%%%
% LocalProborAggMethod %
%%%%%%%%%%%%%%%%%%%%%%%%
function LocalProborAggMethod(nconseq, Connection)
% Builds a subsystem to implement the probor rule aggregation method
% The block has vector input and output
% nconseq is the number of rule consequents
% Connection is the path to the probor subsystem
% Find the path to the fuzzy block libraries
MFLIB = find_system('fuzblock','SearchDepth',1,'MaskType','MF Library');
proborblock_path = find_system(MFLIB{1},'SearchDepth',1,'MaskType','probor rule agg method');
proborblock_path = proborblock_path{1};
% Add an inport and outport
add_block('built-in/Inport', [Connection '/In1'], 'Position', [ 30 82 60 98]);
add_block('built-in/Outport',[Connection '/Out1'], 'Position', [635 82 665 98]);
dx = 0; dy = 0;
if nconseq == 1
% Only one rule consequent, therefore probor function should just directly output the input
add_line(Connection, 'In1/1','Out1/1');
else
% There is more than one rule antecedent/consequent therefore add a demux
add_block('built-in/Demux',[Connection '/aDemux'],'Outputs',num2str(nconseq),...
'ShowName','off','Position',[85 60 90 120]);
add_line(Connection, 'In1/1', 'aDemux/1');
for id = 1 : nconseq - 1
add_block(proborblock_path,[Connection sprintf('/Probor Block%i',id)],'Position',[160+dx 65+dy 210+dx 105+dy]);
if id == 1
% The first probor block has both inputs connected to the demux
for jd = 1:2
add_line(Connection, sprintf('aDemux/%i',id-1+jd), sprintf('Probor Block%i/%i',id,jd));
end
else
% The other probor blocks, first connect to the previous block then to the demux
add_line(Connection,sprintf('Probor Block%i/%i',id-1,1), sprintf('Probor Block%i/%i',id,1));
add_line(Connection,sprintf('aDemux/%i',id-1+jd), sprintf('Probor Block%i/%i',id,2));
end
dx = dx+100; dy = dy+50;
end
% Connect the last block to the output port
add_line(Connection,sprintf('Probor Block%i/1',nconseq - 1), 'Out1/1');
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -