Updating fuzzy rules fast

2 次查看(过去 30 天)
Joseph Gabbay
Joseph Gabbay 2024-3-13
Hello,
I am trying to run an evolutionary algoritm where fuzzy rules consequents are updating.
I have N=100 zero-order sugfis objects, each has 729 rules (frb_size), and 2 outputs.
The algorithm sets values in PopDec matrix of N*(2*frb_size), so that all the consequents of all the controllres should change.
Unfortunately, the "for" loops, especially the inner one is a performance killer. It is extremely slow. Εven specifying 'DisableStructuralChecks',true in sugfis() call, cannot do too much.
for n=1:obj.N
fprintf("updating %s\n",obj.nfc_pop(n).Name);
for r=1:obj.frb_size
obj.nfc_pop(n).Rules(r).Consequent=[PopDec(n,r+r-1) PopDec(n,r+r)];
end
end
I am looking for a way to initialize all the conseqents of the rules in the n-th controller using a simple assignment.
How can this be accomplished
Thank you,
Joseph

回答(1 个)

MULI
MULI 2024-4-24
编辑:MULI 2024-4-24
Hi Joseph,
I understand that you are looking for efficient method to initialize the consequents of fuzzy rules in your evolutionary algorithm avoiding the slow execution of nested loops.
Here are a few optimized strategies you might find helpful:
  1. Eliminate Console Output: By removing the "fprintf" command, you can eliminate the I/O overhead, allowing the algorithm to focus on computational task.
  2. Utilize Local Variables: Assigning the current 'FIS' object to a local variable before entering the inner loop can minimize the number of times the system needs to navigate through object properties.
  3. Batch Updates: After making all necessary updates to the local 'FIS' object, writing it back to the array in a single operation can reduce the overall number of property accesses.
Below is the modified code incorporating these suggestions:
for n = 1:obj.N
currentFIS = nfc_pop(n);
for r = 1:obj.frb_size
currentFIS.Rules(r).Consequent = [PopDec(n, 2*r-1), PopDec(n, 2*r)];
end
nfc_pop(n) = currentFIS;
end
Hope this answers your query!
  1 个评论
Joseph Gabbay
Joseph Gabbay 2024-5-8
Hello and thank you for your answer,
It seems that building and updating matrices or using cell array may execute faster than using "for" loops that call the object methods. Accessing cells and the conversion between cells and matrices with different dimensions and indexing types require some debugging.
For example, this code snippet prepares FRB and then it is possible to update its consequents without using for loop.
%% PrepareFrb
function PrepareFrb(obj,usedef)
% PrepareFrb() prepare the Fuzzy Rule Base
% This the pool of rules from which the system can select the
% subset that makes it functional
% all rules are AND type
% prepare cell array where each cell contains a row vector that holds
% [1 .. input_partition(i)]
inputArgs = cell(1,obj.numof_inputs);
for ii = 1:obj.numof_inputs
inputArgs{ii} = 1:obj.input_partition(ii);
end
% prepare cell array for outputs
outputArgs=cell(1,obj.numof_inputs);
% for 2 outputs 1x2 cell array: [1 1 1 1 1;2 2 2 2 2;3 3 3 3 3]
% [1 1 1;2 2 2;3 3 3;4 4 4;5 5 5]
[outputArgs{:}] = ndgrid(inputArgs{:});
% prepare the fullhouse antecedents
obj.antecedentMatrix=zeros(obj.numof_rules,obj.numof_inputs);
for ii=1:obj.numof_inputs
% assign a column vector in each iteraion
obj.antecedentMatrix(:,ii)=outputArgs{ii}(:);
end
% default consequent matrix
obj.conseqentMatrix=ones(obj.numof_rules,obj.numof_outputs);
if usedef > 0
for ii=1:obj.numof_outputs
% assign a column vector in each iteration with a
% constant default function number (index)
obj.conseqentMatrix(:,ii)=obj.default_output_mf(ii);
end
else
for ii=1:obj.numof_outputs
% assign a column vector in each iteration with running
% indexes of the output MF
obj.conseqentMatrix(:,ii)=(1:obj.numof_rules)';
end
end
% rule weight and type
% weight is from 0 to 1 (float)
% connection is 1 AND 2 OR (int)
obj.attribMatrix=[obj.default_weight*ones(obj.numof_rules,1),...
obj.default_connection*ones(obj.numof_rules,1)];
% assemble rule matrix
obj.ruleMatrix=[obj.antecedentMatrix obj.conseqentMatrix obj.attribMatrix];
% update the fis itself
obj.nfc=obj.nfc.addRule(obj.ruleMatrix);
end % PrepareFrb()
%% update consequents rules
function UpdateRulesSimpleConseq(obj,conseq)
% conseq is matrix numofrules x outputs
cc=num2cell(conseq,obj.numof_outputs);
[obj.nfc.Rules.Consequent] = deal(cc{:});
end % UpdateRulesSimple()
While working with constants may work, I am still looking for more effective way for updating consequent paraneters of the MFs.
% set up consequent parameters
condec=dec((obj.num_of_trapmf_params+1):numel(dec));
condec=reshape(condec,obj.numof_rules,obj.numof_outputs);
% can we deal this better?
for k=1:obj.numof_outputs
for r=1:obj.numof_rules
obj.nfc.Outputs(k).MembershipFunctions(r).Parameters=condec(r,k);
end
end

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Fuzzy Logic in Simulink 的更多信息

标签

产品


版本

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by