Azzera filtri
Azzera filtri

Updating fuzzy rules fast

4 visualizzazioni (ultimi 30 giorni)
Joseph Gabbay
Joseph Gabbay il 13 Mar 2024
Commentato: Joseph Gabbay il 8 Mag 2024
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

Risposte (1)

MULI
MULI il 24 Apr 2024
Modificato: MULI il 24 Apr 2024
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 Commento
Joseph Gabbay
Joseph Gabbay il 8 Mag 2024
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

Accedi per commentare.

Categorie

Scopri di più su Fuzzy Logic in Simulink in Help Center e File Exchange

Prodotti


Release

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by