Fuzzy Logic Toolbox - addRule throws "Do not use a rule keyword as a membership function name" error
80 views (last 30 days)
Show older comments
Kartik Sahajpal
on 16 Apr 2023
Commented: Sam Chak
on 20 Mar 2024 at 15:32
I'm trying to design a simple Mamdani FIS with two inputs and one output in MATLAB using the Fuzzy Logic Toolbox, as shown in the code snippet below.
fis_size = mamfis;
fis_size = addInput(fis_size,[1000 2000], 'Name','flow rate');
fis_size = addInput(fis_size,[2.5 15], 'Name','T_approach');
fis_size = addOutput(fis_size,[2000 12000], 'Name','size');
fis_size = addMF(fis_size, "flow rate", 'trimf', [1000 1500 2000], 'Name', 'high');
fis_size = addMF(fis_size, "flow rate", 'trimf', [1000 1250 1500], 'Name', 'low');
fis_size = addMF(fis_size, "T_approach", 'trimf', [5 10 15], 'Name', 'large');
fis_size = addMF(fis_size, "T_approach", 'trimf', [2.5 5 7.5], 'Name', 'small');
fis_size = addMF(fis_size, "size", 'trimf', [4000 8000 12000], 'Name', 'huge');
fis_size = addMF(fis_size, "size", 'trimf', [2000 5000 8000], 'Name', 'tiny');
rule1 = "If flow rate is high and T_approach is small then size is huge";
rule2 = "If flow rate is low or T_approach is large then size is tiny";
rule3 = "If flow rate is low and T_approach is small then size is huge";
fis_size = addRule(fis_size, [rule1 rule2 rule3]);
However, MATLAB keeps throwing the error in the last line
fis_size = addRule(fis_size, [rule1 rule2 rule3]);
"Error using FuzzyInferenceSystem/addRule
Do not use a rule keyword as a membership function name."
I have not been able to locate the source of the error following the documentation - https://in.mathworks.com/help/fuzzy/mamfis.addrule.html and https://in.mathworks.com/help/fuzzy/working-from-the-command-line.html. I'd appreciate any help in figuring out where I'm going wrong or using a rule keyword as a membership function name.
3 Comments
Sam Chak
on 16 Apr 2023
Yup, it's baffling. It appears that sequence of the word-spacing fuzzy Input affects the type of error message.
fis_size = mamfis;
fis_size = addInput(fis_size,[2.5 15], 'Name','Approach temperature');
fis_size = addInput(fis_size,[1000 2000], 'Name','flow');
fis_size = addOutput(fis_size,[2000 12000], 'Name','size');
fis_size = addMF(fis_size, "Approach temperature", 'trimf', [5 10 15], 'Name', 'large');
fis_size = addMF(fis_size, "Approach temperature", 'trimf', [2.5 5 7.5], 'Name', 'small');
fis_size = addMF(fis_size, "flow", 'trimf', [1000 1500 2000], 'Name', 'high');
fis_size = addMF(fis_size, "flow", 'trimf', [1000 1250 1500], 'Name', 'low');
fis_size = addMF(fis_size, "size", 'trimf', [4000 8000 12000], 'Name', 'huge');
fis_size = addMF(fis_size, "size", 'trimf', [2000 5000 8000], 'Name', 'tiny');
rule1 = "If Approach temperature is high and flow is small then size is huge"; %
rule2 = "If Approach temperature is low or flow is large then size is tiny";
rule3 = "If Approach temperature is low and flow is small then size is huge";
fis_size = addRule(fis_size, [rule1 rule2 rule3]);
Accepted Answer
Sam Chak
on 16 Apr 2023
Change the name of the fuzzy variable to "flowrate" (to eliminate the space).
fis_size = mamfis;
% Input #1
fis_size = addInput(fis_size, [1000 2000], 'Name', 'flowrate');
fis_size = addMF(fis_size, "flowrate", 'trimf', [1000 1500 2000], 'Name', 'high');
fis_size = addMF(fis_size, "flowrate", 'trimf', [1000 1250 1500], 'Name', 'low');
% Input #2
fis_size = addInput(fis_size, [2.5 15], 'Name', 'T_approach');
fis_size = addMF(fis_size, "T_approach", 'trimf', [5.0 10 15], 'Name', 'large');
fis_size = addMF(fis_size, "T_approach", 'trimf', [2.5 5 7.5], 'Name', 'small');
figure(1)
subplot(211)
plotmf(fis_size, 'input', 1), grid on, title('Input 1: Flow rate')
subplot(212)
plotmf(fis_size, 'input', 2), grid on, title('Input 2: T_{approach}')
% Output
fis_size = addOutput(fis_size,[2000 12000], 'Name', 'size');
fis_size = addMF(fis_size, "size", 'trimf', [4000 8000 12000], 'Name', 'huge');
fis_size = addMF(fis_size, "size", 'trimf', [2000 5000 8000], 'Name', 'tiny');
figure(2)
plotmf(fis_size, 'output', 1), grid on, title('Output: Size')
% Rules
rule1 = "If flowrate is high and T_approach is small then size is huge";
rule2 = "If flowrate is low or T_approach is large then size is tiny";
rule3 = "If flowrate is low and T_approach is small then size is huge";
fis_size = addRule(fis_size, [rule1 rule2 rule3]);
% Surface
figure(3)
opt = gensurfOptions('NumGridPoints', 41);
gensurf(fis_size, opt); grid on
view(135, 30),
xlabel('Flow rate'), ylabel('T_approach'), zlabel('Size');
title('Surface');
More Answers (4)
Sam Chak
on 23 May 2023
Hi @tulu
There are several typos. If you make the code less 'cluttered', you can spot the mistakes easily. The code is now is fixed.
If you find the solution helpful, please consider voting 👍 on the answer. Thanks a bunch! 🙏
my_fis = mamfis('Name', "fuzzy controller", "AndMethod", "prod", "defuzzificationMethod", "centroid");
% Adding inputs
num_inputs = 2;
in1_Range = [0, 100];
my_fis = addInput(my_fis, in1_Range, 'Name', "error");
in2_Range = [0, 1];
my_fis = addInput(my_fis, in2_Range, 'Name', "rate_of_error");
% adding outputs
out_Range = [0, 5];
my_fis = addOutput(my_fis, out_Range, 'Name', "OP");
% defining and adding membership function in generated fis
num_in_MFs = 5;
input_mf_names = ["VS"; "S"; "M"; "L"; "VL"];
% Paramaters of different membership function for inputs
params_input_mf(:,:,1) = [ 0 10 20;
20 30 40;
40 50 60;
60 70 80;
80 90 100];
params_input_mf(:,:,2) = [0.0 0.1 0.2;
0.2 0.3 0.4;
0.4 0.5 0.6;
0.6 0.7 0.8;
0.8 0.9 1.0];
for i = 1:num_inputs
for j = 1:num_in_MFs
my_fis = addMF(my_fis, my_fis.inputs(i).name, "trimf", params_input_mf(j,:,i), 'Name', input_mf_names(j));
end
end
figure(1)
plotmf(my_fis, 'input', 1), grid on
figure(2)
plotmf(my_fis, 'input', 2), grid on
% defining anmd adding membership function to outputs of FIS
OP_mf1 = fismf("zmf", [0.00 0.20], 'Name', "VS");
OP_mf2 = fismf("gaussmf", [0.20 0.40], 'Name', "S");
OP_mf3 = fismf("gaussmf", [0.40 0.60], 'Name', "M");
OP_mf4 = fismf("gaussmf", [0.60 0.80], 'Name', "L");
OP_mf5 = fismf("smf", [0.80 0.95], 'Name', "VL");
my_fis.outputs(1).membershipfunctions = [OP_mf1 OP_mf2 OP_mf3 OP_mf4 OP_mf5];
figure(3)
plotmf(my_fis, 'output', 1), grid on
%% adding rules to controller
my_fis = addRule(my_fis, [ ...
"error == S & rate_of_error == VS => OP = VS"; ...
"error == S & rate_of_error == S => OP = VS"; ...
"error == S & rate_of_error == M => OP = M" ; ...
"error == S & rate_of_error == L => OP = L" ; ...
"error == S & rate_of_error == VL => OP = VL"; ...
"error == M & rate_of_error == VS => OP = VS"; ...
"error == M & rate_of_error == S => OP = S" ; ...
"error == M & rate_of_error == M => OP = M" ; ...
"error == M & rate_of_error == L => OP = M" ; ...
"error == M & rate_of_error == VL => OP = L" ; ...
"error == L & rate_of_error == VS => OP = S" ; ...
"error == L & rate_of_error == S => OP = S" ; ...
"error == L & rate_of_error == M => OP = S" ; ...
"error == L & rate_of_error == L => OP = M" ; ...
"error == L & rate_of_error == VL => OP = M"]);
figure(4)
opt = gensurfOptions('NumGridPoints', 51);
gensurf(my_fis, opt), view(45, 45)
1 Comment
tulu
on 22 May 2023
Edited: Walter Roberson
on 22 May 2023
I'm trying to design a simple Mamdani FIS with two inputs and one output in MATLAB using the Fuzzy Logic Toolbox, as shown below.
clc;
clearvars;
%declaration of fuzzy inferance system
my_fis = mamfis('Name',"fuzzy controller","AndMethod","prod","defuzzificationMethod","centroid");
% Adding inputs
num_inputs_MFs= 2;
my_fis = addInput (my_fis,[0,100],'Name',"error");
my_fis = addInput (my_fis,[0,1],'Name',"rate_of_error");
%adding outputs
my_fis=addOutput(my_fis,[0,5],'Name', "OP");
%% defining and adding membership function in generated fis
num_input_MFs=5;
input_mf_names = ["VERY SMALL";"SMALL";"MEDIUM";"LARGE";"VERY LARGE"];
% Paramaters of different membership function for inputs
params_input_mf(:,:,1) = [0 10 20 ;
20 30 40;
40 50 60;
60 70 80;
80 90 100];
params_input_mf (:,:,2) = [0 0.1 0.2;
0.2 0.3 0.4;
0.4 0.5 0.6;
0.6 0.7 0.8;
0.8 0.9 1];
for i=1:num_inputs_MFs
for j=1:num_inputs_MFs
my_fis=addMF(my_fis,my_fis.inputs(i).name,"trimf", params_input_mf(j,:,i),'Name',input_mf_names(j));
end
end
%% defining anmd adding membership function to outputs of FIS
OP_mf1 = fismf("zmf",[0 0.2],'Name',"VERYSMALL");
OP_mf2 = fismf("gaussmf", [0.2 0.4], 'Name',"SMALL");
OP_mf3 = fismf("gaussmf",[0.4 0.6], 'Name',"MEDIUM");
OP_mf4 = fismf("gaussmf",[0.6 0.8],'Name',"LARGE");
OP_mf5 = fismf("smf",[0.8 0.95], 'Name',"VERYLARGE");
my_fis.outputs(1).membershipfunctions = [OP_mf1 OP_mf2 OP_mf3 OP_mf4 OP_mf5];
%% adding rules to controller
my_fis = addRule(my_fis,["error == SMALL & rate_of_error == VERY_SMALL => OP= VERY_SMALL"+ ...
"error == SMALL & rate_of_error == SMALL => OP= VERY_SMALL" + ...
"error == SMALL & rate_of_error == MEDIUM => OP= MEDIUM"+ ...
"error == SMALL & rate_of_error == LARGE => OP= LARGE" + ...
"error == SMALL & rate_of_error == VERY_LARGE => OP= VERY_LARGE" + ...
"error == MEDIUM & rate_of_error == VERY_SMALL => OP= VERY_SMALL" + ...
"error == MEDIUM & rate_of_error == SMALL => OP= SMALL" + ...
"error == MEDIUM & rate_of_error == MEDIUM => OP= MEDIUM" + ...
"error == MEDIUM & rate_of_error == LARGE=> OP= MEDIUM" + ...
"error == MESIUM & rate_of_error === VERY_LARGE => OP= LARGE" + ...
"error == LARGE $ rate_of_error === VERY_SMALL => OP=SMALL" + ...
"error == LARGE & rate_of_error == SMALL => OP=SMALL" + ...
"error == LARGE & rate_of_error == MEDIUM => OP=SMALL" + ...
"error == LARGE & rate_of_error == LARGE =>OP=MEDIUM" + ...
"error == LARGE & rate_of_error == VERY LARGE =>OP=MEDIUM"]);
"Error using FuzzyInferenceSystem/addRule
Do not use a rule keyword as a membership function name." I'd appreciate any help in figuring out where I'm going wrong or using a rule keyword as a membership function.I have not been able to locate the source of the error of the documentation. please help me
1 Comment
Walter Roberson
on 22 May 2023
You have a number of errors:
- in your rules you use VERY LARGE instead of VERY_LARGE
- in your rules you have a $ instead of a &
- Your output mf have no _ in them such as VERYSMALL but your rules use the _ version
- You have ["STRING" + ... on each line, but the string + operator is concatenation, so you are creating one long string. You should be creating a string array instead. So remove the +
There are other errors I did not track down the cause of
tulu
on 25 May 2023
Hi @Sam Chak
I am working on active cell balancing of lithiumion battery by using fuzzy-pid as a controller. so how can I implement with cuk equalization circuit? I use SOC (state of charge) as in pout variable. change of SOC and average of SOC as error and rate of error respectively.
1 Comment
Sam Chak
on 26 May 2023
Hi @tulu
The original issue related to the Error using FuzzyInferenceSystem/addRule has been adequately answered.
Thus, I'd suggest you to post a new question on the implementation of the Fuzzy PID as a controller for active cell balancing of lithiumion battery.
In the new question, please provide the mathematical models (differential equations) that describe the Active Battery Cell Balancing (1) during Discharging, or (2) while Charging. The models will be helpful in the design of the PID controller, which can be fuzzified later if an enhanced performance is desired.
Samuel
on 20 Mar 2024 at 5:04
Edited: Samuel
on 20 Mar 2024 at 15:13
Why have error? It's my code wrong? Can help me to check and tell me where need to change? Thanks a lot.
% Close all figures and clear workspace
close all;
clear all;
% Define input values
X_m3 = 66.23;
X_m1 = X_m3 - 40;
X_m2 = X_m3 - 20;
X_m4 = X_m3 + 20;
X_m5 = X_m3 + 40;
Y_m3 = 42.65;
Y_m1 = Y_m3 - 40;
Y_m2 = Y_m3 - 20;
Y_m4 = Y_m3 + 20;
Y_m5 = Y_m3 + 40;
% Define input variable range
X_min_value = 0;
X_max_value = 140;
Y_min_value = -20;
Y_max_value = 100;
% Create a Mamdani FIS
fis = mamfis('Name', "tipper");
% Add input variables with 5 Gaussian membership functions each
fis = addInput(fis, 'NumMFs', 5, 'MFType', "gaussmf");
fis = addInput(fis, 'NumMFs', 5, 'MFType', "gaussmf");
% Set input variable names and ranges
fis.Inputs(1).Name = "A";
fis.Inputs(1).Range = [X_min_value, X_max_value];
fis.Inputs(2).Name = "B";
fis.Inputs(2).Range = [Y_min_value, Y_max_value];
% Set input variable membership function names and parameters
input_mf_names = {'Right', 'Slightly_Right', 'Center', 'Slightly_Left', 'Left'};
for i = 1:5
fis.Inputs(1).MembershipFunctions(i).Name = input_mf_names{i};
fis.Inputs(2).MembershipFunctions(i).Name = input_mf_names{i};
end
% Define mean and standard deviation for X coordinate membership functions
X_means = [10, 10, 10, 10, 10];
X_stds = [X_m1, X_m2, X_m3, X_m4, X_m5];
% Define mean and standard deviation for Y coordinate membership functions
Y_means = [10, 10, 10, 10, 10];
Y_stds = [Y_m1, Y_m2, Y_m3, Y_m4, Y_m5];
% Set parameters for X coordinate membership functions
for i = 1:5
fis.Inputs(1).MembershipFunctions(i).Parameters = [X_means(i), X_stds(i)];
fis.Inputs(2).MembershipFunctions(i).Parameters = [Y_means(i), Y_stds(i)];
end
% Display input details
% fis.Inputs(1)
% fis.Inputs(2)
fis.Inputs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Define output ranges
output_range = [-2, 2];
% Add output variables with 5 Gaussian membership functions each
fis = addOutput(fis, 'NumMFs', 5, 'MFType', "gaussmf");
fis = addOutput(fis, 'NumMFs', 5, 'MFType', "gaussmf");
% Set output variable names and ranges
fis.Outputs(1).Name = "C";
fis.Outputs(1).Range = output_range;
fis.Outputs(2).Name = "D";
fis.Outputs(2).Range = output_range;
% Set output variable membership function names and parameters
output_mf_names = {'Right', 'Slightly_Right', 'Center', 'Slightly_Left', 'Left'};
for i = 1:5
fis.Outputs(1).MembershipFunctions(i).Name = output_mf_names{i};
fis.Outputs(2).MembershipFunctions(i).Name = output_mf_names{i};
end
% Define mean and standard deviation for output membership functions
output_means = [0.4, 0.4, 0.4, 0.4, 0.4];
output_stds = [-2, -1, 0, 1, 2];
% Set parameters for output membership functions
for i = 1:5
fis.Outputs(1).MembershipFunctions(i).Parameters = [output_means(i), output_stds(i)];
fis.Outputs(2).MembershipFunctions(i).Parameters = [output_means(i), output_stds(i)];
end
% Display output details
% fis.Outputs(1)
% fis.Outputs(2)
fis.Outputs
% fis = readfis('xxx');
fis = addRule(fis,["If A == Center && B == Center => C == Center && D == Center" ...
"If A == Center && B == Center => C == Center && D == Center"...
])
% r1 = "If A is Center and B is Center then C is Center and D is Center";
% r = [r1];
% fis = addRule(fis, "If fis.Inputs(1).Name == input_mf_names(1) && fis.Inputs(2).Name === input_mf_names(1) => fis.Outputs(1).Name == output_mf_names(1) && fis.Outputs(2).Name == output_mf_names(1)" );
% fis2 = addRule(fis,r1);
1 Comment
See Also
Categories
Find more on Fuzzy Inference System Modeling in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!