---
# System prepended metadata

title: Fuzzy Notes
tags: [fuzzy logic, matlab]

---

---
slideOptions:
  transition: slide
---
<style>
.reveal {
  font-size: 24px;
}
</style>


# Fuzzy Notes

"These are functions, codes, and summaries about fuzzy logic"

For better look check this note in [HackMD.io](https://hackmd.io/@libernormous/fuzzy)

by:  
[Liber Normous](https://hackmd.io/@libernormous)

---

# Membership checking

## Triangle membership

Using this function you can make one membership variable.  
If you input a number, you will see the degree of membership of that number. The function is built using many 2 linear line equation. The linear equation is shifted to the amount of `start`  
$$
y = y_0 + v(x - x_0)\\
v = \frac{y_f - y_0}{x_f - x_0}
$$

----

CODE:  
```c=
function out = triangle(input, start, middle, stop, str_val, mid_val, sto_val)
    if input<start
        out = str_val;
        
    elseif (input>=start) && (input<middle)
        v = (mid_val-str_val)/(middle-start);
        out = str_val + v*(input-start);
    
    elseif (input==middle)
        out = mid_val;
        
    elseif (input>middle) && (input<=stop)
        v = (sto_val-mid_val)/(stop-middle);
        out = mid_val + v*(input-middle);
        
    elseif input>stop
        out = sto_val;
    end
end
```
arguments:
1. `input`: the number you want to check the value of
2. `start`: beginning of the rising value
3. `middle`: peak value
4. `stop`: end of falling value
5. `str_val, mid_val, sto_val`: values for `start, middle, stop,` respectively

----

Example 1:  

```c=
t = 0:1:70;
out=t;
for i=1:length(t)
    out(i)=triangle(t(i),10,30,50,0,20,0);
end
plot(t,out,'.-')
```

----

Result:  
![](https://i.imgur.com/DJGVDpe.png)

----

Example 2:  
```c=
t = -2:1:5;
out=t;
for i=1:length(t)
    out(i)=triangle(t(i),0, 2, 4, 0, 1, 0);
end
plot(t,out,'.-')
```
![](https://i.imgur.com/id49F4N.png)

----

Example 3:  
```c=
t = -2:0.1:5;
out=t;
for i=1:length(t)
    out(i)=triangle(t(i),0, 0, 2, 0, 1, 0);
end
plot(t,out,'.-')
```
![](https://i.imgur.com/tjCfn8D.png)


----

Example 4:  
```c=
t = 9:0.1:13;
out=t;
for i=1:length(t)
    out(i)=triangle(t(i), 10, 12, 12, 0, 1, 0);
end
plot(t,out,'.-')
```
![](https://i.imgur.com/fcW5jo5.png)


----

If we want to check from many membership variable of a fuzzy set. We can repeat `triangle()` function.  
I wrote a function to check all values from all membership variable. Using this function we can get the degree of membership for each linguistic variable.  
The idea is the function return a vector of membership degree values. For example:  
$$
\mu_A(0.5) = \{0.9, 0.1, 0, 0\}
$$

----

So, if we input from $-\infty$ to $\infty$ to the fuzzy set, we will get the picture of fuzzification (but, practically not from $-\infty$ to $\infty$).  

Example 5 (Velocity membership):  
```c
%//=====================to check all value in velocity fuzzification
function out = check_velocity_membership(input)
    z = triangle (input, 0, 0, 2, 1, 1, 0);%zero
    s = triangle (input, 0, 2, 4, 0, 1, 0);%slow
    nm = triangle (input, 2, 4, 6, 0, 1, 0);%near medium
    m = triangle (input, 4, 6, 8, 0, 1, 0);%medium
    nh = triangle (input, 6, 8, 10, 0, 1, 0);%near high
    h = triangle (input, 8, 10, 12, 0, 1, 0);%high
    vh = triangle (input, 10, 12, 12, 0, 1, 1);%very high
    out = [z;s;nm;m;nh;h;vh];
end

%//===============Plotting velocity membership function
t = -1:0.5:13;
out = [];
for i=1:length(t)
    ret=check_velocity_membership(t(i));
    out = [out ret];
end
figure(3)
plot(t,out(1,:),'.-',t,out(2,:),'.-',t,out(3,:),'.-',t,out(4,:),'.-',t,out(5,:),'.-',t,out(6,:),'.-',t,out(7,:),'.-')
grid
```
In above example there are 7 linguistic variables (`'zero','slow','near medium', 'medium', 'near high', 'high, very high'`). So the function will return a vector with size of $5\times1$.  

----

Result:  
![](https://i.imgur.com/QpmcfKR.png)


----

Example 6 (Angle error membership):
```c=
%=====================to check all value in angle error fuzzification
function out = check_err_angle_membership(input)
    n = triangle (input, -175, -175, -88, 1, 1, 0); %negative
    sn = triangle (input, -175, -88, -43, 0, 1, 0); %small neg
    nnz = triangle (input, -88, -43, 0, 0, 1, 0); % near neg zero
    z = triangle (input, -43, 0, 43, 0, 1, 0); %zero
    npz = triangle (input, 0, 43, 88, 0, 1, 0); %near pos zero
    sp = triangle (input, 43, 88, 175, 0, 1, 0); %small pos
    p = triangle (input, 88, 175, 175, 0, 1, 1); %positive
    out = [n; sn; nnz; z; npz; sp; p];
end

%===============Plotting angle error membership function
t = -200:1:200;
out = [];
for i=1:length(t)
    ret=check_err_angle_membership(t(i));
    out = [out ret];
end
figure(2)
plot(t,out(1,:),'.-',t,out(2,:),'.-',t,out(3,:),'.-',t,out(4,:),'.-',t,out(5,:),'.-',t,out(6,:),'.-',t,out(7,:),'.-')
grid
```

----

Result :  
![](https://i.imgur.com/Qpwd74p.png)

----

Example (distance membership function):  

```c=
%=====================to check all value in distance fuzzification
function out = check_distance_membership(input)
    z = triangle (input, 0, 0, 5, 1, 1, 0); %//zero
    nz = triangle (input, 0, 5, 10, 0, 1, 0); %//near zero
    n = triangle (input, 5, 10, 15, 0, 1, 0); %//near
    m = triangle (input, 10, 15, 20, 0, 1, 0); %//medium
    nf = triangle (input, 15, 20, 25, 0, 1, 0); %//near far
    f = triangle (input, 20, 25, 30, 0, 1, 0); %//far
    vf = triangle (input, 25, 30, 30, 0, 1, 1); %//very far
    out = [z;nz;n;m;nf;f;vf];
end

%===============Plotting distance membership function

t = -5:1:35;
out = [];
for i=1:length(t)
    ret=check_distance_membership(t(i));
    out = [out ret];
end
figure(1)
plot(t,out(1,:),'.-',t,out(2,:),'.-',t,out(3,:),'.-',t,out(4,:),'.-',t,out(5,:),'.-',t,out(6,:),'.-',t,out(7,:),'.-')
grid

```

----

![](https://i.imgur.com/9ZekJ5X.png)

----

Example (Membership functions for the LV and RV of OAFLC):  
```c=
%//=====================to check all value in LV and RV of OAFLC
function out = check_vl_vr_oaflc_membership(input)
    nh = triangle (input, -10, -5, 0, 0, 1, 0);%//negative high
    n = triangle (input, -5, -2.5, 0, 0, 1, 0);%///negative
    p = triangle (input, 0, 2, 2, 0, 1, 0);%//positive
    hp = triangle (input, 0, 6.25, 8, 0, 1, 0);%//high positive
    vhp = triangle (input, 6.25, 8, 12, 0, 1, 0);%//very high positive
    out = [nh;n;p;hp;vhp];
end

%//===============Plotting Membership functions for the LV and RV of OAFLCtion
t = -10:0.1:15;
out = [];
for i=1:length(t)
    ret=check_vl_vr_oaflc_membership(t(i));
    out = [out ret];
end
figure(7)
plot(t,out(1,:),'-',t,out(2,:),'-',t,out(3,:),'-',t,out(4,:),'-',t,out(5,:),'-')
grid
```
![](https://i.imgur.com/bKdvNKi.png)



----

## Trapezoid membership  
CODE:  
```c=
%===============trapezoid shaped fuzzy membership
function out = trapezoid(input, start, middle1, middle2, stop, str_val, mid1_val, mid2_val, sto_val)
    if(input<start)
        out = str_val;
        
    elseif(input>=start) && (input<middle1)
        v = (mid1_val-str_val)/(middle1-start);
        out = str_val + v*(input-start);
    
    elseif(input==middle1)
        out = mid1_val;
        
    elseif(input>middle1) && (input<middle2)
        v = (mid2_val-mid1_val)/(middle2-middle1);
        out = mid1_val + v*(input-middle1);
        
    elseif(input==middle2)
        out = mid2_val;
        
    elseif(input>middle2) && (input<=stop)
        v = (sto_val-mid2_val)/(stop-middle2);
        out = mid2_val + v*(input-middle2);
        
    elseif(input>stop)
        out = sto_val;
    end
end
```

----

Example:  
```c=
t = -1:0.5:13;
out = [];
for i=1:length(t)
    ret=trapezoid(t(i), 0, 4, 6, 10, 0, 1, 0.8, 0);
    out = [out ret];
end
figure(4)
plot(t,out,'.-')
grid
```
Result:  
![](https://i.imgur.com/LPwCQ0k.png)

----

Example:  
```c=
%===============Plotting trapezoid membership function
t = 3:0.5:7;
out = [];
for i=1:length(t)
    ret=trapezoid (t(i), 4, 4, 6, 6, 0, 1, 1, 0);
    out = [out ret];
end
figure(4)
plot(t,out,'.-')
grid
```
Result:  
![](https://i.imgur.com/hc2b1Nh.png)


----

Example:  
```c=
%===============Plotting trapezoid membership function
t = 3:0.5:7;
out = [];
for i=1:length(t)
    ret=trapezoid(t(i), 4, 5, 5, 6, 0, 1, 1, 0);
    out = [out ret];
end
figure(4)
plot(t,out,'.-')
grid
```

Result:  
![](https://i.imgur.com/CwJs0jf.png)

----

We can repeat `trapezoid()` to make more sophisticated membership function  
```c=
%=====================to check all value from sensor
function out = check_obstacle_membership(input)
    n = trapezoid (input, 0, 10, 20, 30, 0, 1, 1, 0);%near
    m = trapezoid (input, 20, 30, 40, 50, 0, 1, 1, 0);%medium
    f = trapezoid (input, 40, 50, 60, 70, 0, 1, 1, 1);%far
    out = [n;m;f];
end
```

We check a the degree of membership against all the linguistic variable.  

```c=
%===============Plotting sensor membership function
t = 0:1:70;
out = [];
for i=1:length(t)
    ret=check_obstacle_membership(t(i));
    out = [out ret];
end
figure(5)
plot(t,out(1,:),'.-',t,out(2,:),'.-',t,out(3,:),'.-')
grid
```

----

Result:  
![](https://i.imgur.com/JtIYq6u.png)

---

# Inference based on Rules

## Representing rules into matrix

----

1. Create rules  

|   - | slow | medium | fast |
| -------- | -------- | -------- | -------- | 
| very far | not break     | half break    | break |
| far      | half break    | break         | break |
| near     | break         | break         | break |

2. Represent each variables using numbers.    
3. The numbers is the index of output membership function.   

$$
\text{rule_idx_matrix}=
\left(
\begin{matrix}
1 & 2 &3\\
2 & 3 &3\\
3 & 3 &3
\end{matrix}
\right)
$$

----

Example CODE:  
```c=
%============Creating fuzzy rules Tracking fuzzy logic control (TFLC)======
% There are 7 variable for angle error, and 7 variable for distance
% So there is 49 rules
% There are 7 variable output
% Number of column denotes error angle
% Number of rows denotes distance error
% Numbers inside matrix are the output

rules_L = [
    1 1 1 1 3 3 4;
    2 2 1 2 3 5 6;
    2 2 2 3 5 6 7;
    1 1 1 4 6 6 7;
    2 2 3 5 5 6 7;
    1 1 4 6 5 6 7;
    2 2 3 7 5 6 7
    ];
rules_L_var = {'z'; 's'; 'nm'; 'm'; 'nh'; 'h'; 'vh'};
rules_L_var(rules_L)

rules_R = flip(rules_L,2);
```

Result:  
```
ans =

  7×7 cell array

    {'z'}    {'z'}    {'z' }    {'z' }    {'nm'}    {'nm'}    {'m' }
    {'s'}    {'s'}    {'z' }    {'s' }    {'nm'}    {'nh'}    {'h' }
    {'s'}    {'s'}    {'s' }    {'nm'}    {'nh'}    {'h' }    {'vh'}
    {'z'}    {'z'}    {'z' }    {'m' }    {'h' }    {'h' }    {'vh'}
    {'s'}    {'s'}    {'nm'}    {'nh'}    {'nh'}    {'h' }    {'vh'}
    {'z'}    {'z'}    {'m' }    {'h' }    {'nh'}    {'h' }    {'vh'}
    {'s'}    {'s'}    {'nm'}    {'vh'}    {'nh'}    {'h' }    {'vh'}
```

----

## Inference (relate `input1` and `input2` to create `output1`)

1. Represent the relation using matrix with the same size of rules matrix  
    
    Example: car is moving at $10\%$ slow, $90\%$ medium speed, and $0\%$ fast. the distance to next car is  $80\%$ very far, $20\%$ far, and $0\%$ near. The relation should be  like this matrix or table bellow.  
    We apply minimum for correlation/inference because the logic we use in the rule ins AND logic.  

$$
\text{rule_val_matrix}=
\left(
\begin{matrix}
0.1 & 0.8 &0\\
0.1 & 0.2 &0\\
0 & 0 &0
\end{matrix}
\right)
$$

|   - | $10\%$ slow | $90\%$ medium | $0\%$ fast |
| -------- | -------- | -------- | -------- | 
| $80\%$ very far | $10\%$ not break     | $80\%$ half break    | $0\%$ break |
| $20\%$ far      | $10\%$ half break    | $20\%$ break         | $0\%$ break |
| $0\%$ near     | $0\%$ break         | $0\%$ break         | $0\%$ break |

----

2. Create vector of the output threshold. Use the maximum value if the same rule has multiple values.  

    Example: We have $\{10\%\}$ not break, $\{10\%,80\%\}$ for half break, and $\{0\%,20\%\}$ for break class. Then we choose the maximum degree for each members. And create threshold vector out of it. so the threshold vector is $\{10\%,90\%,0.8\%\}$


$$
\text{out_thresh_vector}=
\left(
\begin{matrix}
10\%\\
80\%\\
20\%
\end{matrix}
\right)
$$

----

EXAMPLE CODE:
```c=
%example 1
ang = check_err_angle_membership(22.5)
dis = check_distance_membership(17.2)
[relate_L,v_out_th_L] = relate(dis,ang,rules_L)

%%=Relate a fuzzification to another with the result of matrix & vec======
% the relation is using minimum, because the relation in fuzzy rules are
% using AND
function [mat_rules_val,v_out_th] = relate(set1, set2, rules_index)
% set1 is rows, and set2 is columns
    % find correspoding values for each rules
    m = zeros(length(set1), length(set2));
    for i=1:length(set1)
        for j=1:length(set2)
            m(i,j)=min(set1(i),set2(j)); %MIN
        end
    end
    
    % find the output index of each rules values
    % then create vector, of possible maximum mambership value from output
    % membership class
    v_out = zeros(max(max(rules_index)),1);
    [w,h]=size(rules_index);
    for i = 1:w
        for j = 1:h
            v_out( rules_index(i,j) ) = max(v_out( rules_index(i,j) ), m (i,j)); %MAX
        end
    end
    mat_rules_val = m;
    v_out_th = v_out;
end
```

----

RESULT:
```
ang =

         0
         0
         0
    0.4767
    0.5233
         0
         0


dis =

         0
         0
         0
    0.5600
    0.4400
         0
         0


relate_L =

         0         0         0         0         0         0         0
         0         0         0         0         0         0         0
         0         0         0         0         0         0         0
         0         0         0    0.4767    0.5233         0         0
         0         0         0    0.4400    0.4400         0         0
         0         0         0         0         0         0         0
         0         0         0         0         0         0         0


v_out_th_L =

         0
         0
         0
    0.4767
    0.4400
    0.5233
         0

```
EXAMPLE CODE:  
```c=
%exapmple2
ang = check_err_angle_membership(-200)
dis = check_distance_membership(35)
[relate_L,v_out_th_L] = relate(dis,ang,rules_L)
```

----

RESULT:  
```
ang =

     1
     0
     0
     0
     0
     0
     0


dis =

     0
     0
     0
     0
     0
     0
     1


relate_L =

     0     0     0     0     0     0     0
     0     0     0     0     0     0     0
     0     0     0     0     0     0     0
     0     0     0     0     0     0     0
     0     0     0     0     0     0     0
     0     0     0     0     0     0     0
     1     0     0     0     0     0     0


v_out_th_L =

     0
     1
     0
     0
     0
     0
     0
```

----

## Calculate centroid (crisp output)

After we have all the degree of membership across all values. We can calculate Centroid.

We get centroid by estimating integral. With $\Delta t = 0.01$.  
1. For every crisp values of output, check the degree membership values. So we have array of $x=\{-\infty,...,+\infty\}$ to check the degree of membership, and array of degree of membership $\mu(x)$. Except, practically it is not $-\infty$ to $+\infty$  

2. This is how we check degree of membership. Choose the maximum value between memberships. But should always below $\text{out_thresh_vector}$  
    Example: threshold vector is $\{10\%,90\%,80\%\}$, degree of output membership is $\{30\%,70\%,0\%\}$, so the real output is $\text{MAX}(\text{MIN}(\{10\%,90\%,80\%\},\{30\%,70\%,0\%\}))$  
    or   
    $\text{MIN}(\{10\%,90\%,80\%\},\{30\%,70\%,0\%\}))=\{10\%,70\%,0\%\}$  
    $\text{MAX}(\{10\%,70\%,0\%\})=70\%$  

----

3. Centroid or crisp out put $x^*$ is formulated as  
$$
x^*=
\frac{\Sigma^n_{i=1} \ x_i \ \mu(x_i)}{\Sigma^n_{i=1}\ x_i}
$$
    where $n$ is number of samples in the fuzzy set.  

----

EXAMPLE CODE:
```c=
%example 1
ang = check_err_angle_membership(22.5)
dis = check_distance_membership(17.2)
[relate_L,v_out_th_L] = relate(dis,ang,rules_L)

%%
%%%%%%%%%%%%%%%---CENTROID---%%%%%%%%%%%%%%%%%
dt = 0.01;
t = -1:dt:13;
out = [];
for i=1:length(t)
    ret=check_velocity_membership(t(i)); %output fuzzification
    ret = min(v_out_th_L, ret); %MIN
    %Max value / real value of the inference
    out = [out max(ret)]; %MAX
    
    %out is array of possible membership values \mu(x_i)
    %t is our x_i array
end
figure(3)
plot(t,out)
grid

centeroid_VL = sum(out.*t)/sum(out)
```

----

RESULT:
![](https://i.imgur.com/XHIkDbO.png)  

----

EXAMPLE CODE:
```c=
%exapmple2
ang = check_err_angle_membership(-200)
dis = check_distance_membership(35)
[relate_L,v_out_th_L] = relate(dis,ang,rules_L)

%%
%%%%%%%%%%%%%%%---CENTROID---%%%%%%%%%%%%%%%%%
dt = 0.01;
t = -1:dt:13;
out = [];
for i=1:length(t)
    ret=check_velocity_membership(t(i));
    ret = min(v_out_th_L, ret); %MIN
    %Max value / real value of the inference
    out = [out max(ret)]; %MAX
    
    %out is array of possible membership values \mu(x_i)
    %t is our x_i array
end
figure(3)
plot(t,out)
grid

centeroid_VL = sum(out.*t)/sum(out)
```

----

RESULT:
![](https://i.imgur.com/N19y8nJ.png)

---

# Inference based on Rules 2

## Representing rules into table (Multiple Input Multiple Output MIMO)

----

1. Create rules. This is example from [1]  

![](https://i.imgur.com/UQBvkbd.png)  

----

2. Represent each variables using numbers.    
3. The numbers is the index of output membership function.   

$$
\text{rule_idx_matrix}=
\left(
\begin{matrix}
    2& 1\\
    2& 1\\
    1& 1\\
    1& 2\\
    1& 2\\
    1& 1\\
    2& 1\\
    2& 1\\
    1& 2\\
    1& 1\\
    5& 3\\
    3& 5\\
    5& 3\\
    5& 3\\
    1& 2\\
    5& 3\\
    5& 3\\
    1& 2\\
    3& 5\\
    1& 1\\
    1& 2\\
    3& 5\\
    5& 3\\
    1& 2\\
    3& 5\\
    4& 4\\
\end{matrix}
\right)
$$  

----

Example CODE:  
```c=
rules_input_OAFLC = [
    1 1 1;
    1 1 2;
    1 1 3;
    1 2 1;
    1 2 2;
    1 2 3;
    1 3 1;
    1 3 2;
    1 3 3;
    2 1 1;
    2 1 2;
    2 1 3;
    2 2 1;
    2 2 2;
    2 2 3;
    2 3 1;
    2 3 2;
    2 3 3;
    3 1 1;
    3 1 2;
    3 1 3;
    3 2 1;
    3 2 2;
    3 2 3;
    3 3 1;
    3 3 2;
    3 3 3;
    ]

rules_output_OAFLC = [
    1 1;
    2 1;
    2 1;
    1 1;
    2 1;
    2 1;
    1 1;
    2 1;
    2 1;
    1 2;
    1 1;
    5 3;
    3 5;
    5 3;
    5 3;
    1 2;
    5 3;
    5 3;
    1 2;
    3 5;
    1 1;
    1 2;
    3 5;
    5 3;
    1 2;
    3 5;
    4 4;
    ]
var_output_OAFLC={'nh', 'n', 'p', 'hp', 'vhp'}
var_output_OAFLC(rules_output_OAFLC)
```

----

RESULT:  
```
rules_input_OAFLC =

     1     1     1
     1     1     2
     1     1     3
     1     2     1
     1     2     2
     1     2     3
     1     3     1
     1     3     2
     1     3     3
     2     1     1
     2     1     2
     2     1     3
     2     2     1
     2     2     2
     2     2     3
     2     3     1
     2     3     2
     2     3     3
     3     1     1
     3     1     2
     3     1     3
     3     2     1
     3     2     2
     3     2     3
     3     3     1
     3     3     2
     3     3     3


rules_output_OAFLC =

     1     1
     2     1
     2     1
     1     1
     2     1
     2     1
     1     1
     2     1
     2     1
     1     2
     1     1
     5     3
     3     5
     5     3
     5     3
     1     2
     5     3
     5     3
     1     2
     3     5
     1     1
     1     2
     3     5
     5     3
     1     2
     3     5
     4     4


var_output_OAFLC =

  1×5 cell array

    {'nh'}    {'n'}    {'p'}    {'hp'}    {'vhp'}


ans =

  27×2 cell array

    {'nh' }    {'nh' }
    {'n'  }    {'nh' }
    {'n'  }    {'nh' }
    {'nh' }    {'nh' }
    {'n'  }    {'nh' }
    {'n'  }    {'nh' }
    {'nh' }    {'nh' }
    {'n'  }    {'nh' }
    {'n'  }    {'nh' }
    {'nh' }    {'n'  }
    {'nh' }    {'nh' }
    {'vhp'}    {'p'  }
    {'p'  }    {'vhp'}
    {'vhp'}    {'p'  }
    {'vhp'}    {'p'  }
    {'nh' }    {'n'  }
    {'vhp'}    {'p'  }
    {'vhp'}    {'p'  }
    {'nh' }    {'n'  }
    {'p'  }    {'vhp'}
    {'nh' }    {'nh' }
    {'nh' }    {'n'  }
    {'p'  }    {'vhp'}
    {'vhp'}    {'p'  }
    {'nh' }    {'n'  }
    {'p'  }    {'vhp'}
    {'hp' }    {'hp' }
```

----

## Inference (relate `input1`, `input2`, and `input3` to create `output1` and `output2`)

1. Represent the relation using matrix with the same size of rules matrix   
    example: we have 3 sensors and $\mu_{sL}(21)=\{0.9,0.1,0\}$, $\mu_{sF}(29)=\{0.1,0.9,0\}$, and $\mu_{sR}(41)=\{0, 0.9,0.1\}$  
$$
\left|
\begin{matrix}
    \bf{\text{in1}} &\bf{\text{in2}} &\bf{\text{in3}} &\bf{\text{out1}} &\bf{\text{out2}}\\
0.9&0.1&0&         0&         0\\
0.9&0.1&0.9&    0.1&    0.1\\
0.9&0.1&0.1&    0.1&    0.1\\
0.9&0.9&0&         0&         0\\
0.9&0.9&0.9&    0.9&    0.9\\
0.9&0.9&0.1&    0.1&    0.1\\
0.9&0&0&         0&         0\\
0.9&0&0.9&         0&         0\\
0.1&0&0.1&         0&         0\\
0.1&0.1&0&         0&         0\\
0.1&0.1&0.9&    0.1&    0.1\\
0.1&0.1&0.1&    0.1&    0.1\\
0.1&0.9&0&         0&         0\\
0.1&0.9&0.9&    0.1&    0.1\\
0.1&0.9&0.1&    0.1&    0.1\\
0.1&0&0&         0&         0\\
0.1&0&0.9&         0&         0\\
0&0&0.1&         0&0\\
0&0.1&0&         0&         0\\
0&0.1&0.9&         0&0\\
0&0.1&0.1&         0&         0\\
0&0.9&0&         0&0\\
0&0.9&0.9&         0&         0\\
0&0.9&0.1&         0&0\\
0&0&0&         0&         0\\
0&0&0.9&         0&0\\
0&0&0.1&         0&         0\\
\end{matrix}
\right|
$$ 

----

Because we use logic $\text{AND}$ as rule inference, so we apply $\text{MIN}$ to each input pair. And that pair is the output.  

----

2. Create vector of the output threshold. Use the maximum value if the same rule has multiple values.  
    Example: In 'out2', we have $\{0.1,0.1,0.9,0.1,0.1\%\}$ for 'Negative High' class, $\{0.1,0.1,0.1\}$ for 'Possitive' class. Then we choose the maximum degree for each members. And create threshold vector out of it. so the threshold vector is $\{0.9,0,0.1,0,0\}$  
$$
\text{out_thresh_vector}=
\left(
\begin{matrix}
0.9\\
0\\
0.1\\
0\\
0
\end{matrix}
\right)
$$

----

EXAMPLE:
```c=
%% example 3
dist_L = check_obstacle_membership(21) %left obstacle sensor
dist_F = check_obstacle_membership(29) %forward obstacle sensor
dist_R = check_obstacle_membership(41) %right obstacle sensor
dis = check_distance_membership(17.2);
[relate_L, v_out_th_L, v_out_th_R] = relate_OAFLC(dist_L,dist_F,dist_R, rules_output_OAFLC)

%% =Relate a fuzzification to another with the result of rules table & vec======
% the relation is using minimum, because the relation in fuzzy rules are
% using AND
function [mat_rules_val,v_out_th1, v_out_th2] = relate_OAFLC (set1, set2, set3, rules_index)
    % find correspoding values for each rules
    m = zeros(size(rules_index));
    c = 0;
    for i=1:length(set1)
        for j=1:length(set2)
            for k=1:length(set3)
                c = c+1;
                MIN = min(min(set1(i),set2(j)),set3(k));
                m(c,1)=MIN; %MIN output1
                m(c,2)=MIN; %MIN output2 
            end
        end
    end
    
    % find the output index of each rules values
    % then create vector, of possible maximum mambership value from output
    % membership class
    v_out1 = zeros(max(rules_index(:,1)),1); % vector output1
    v_out2 = zeros(max(rules_index(:,2)),1); % vector output2
    [h,w]=size(rules_index);
    for i = 1:h
        v_out1( rules_index(i,1) ) = max(v_out1( rules_index(i,1) ), m(i,1)); %MAX
        v_out2( rules_index(i,2) ) = max(v_out2( rules_index(i,2) ), m(i,2)); %MAX
    end
    mat_rules_val = m;
    v_out_th1 = v_out1;
    v_out_th2 = v_out2;
end
```

----

RESULT:
```
dist_L =

    0.9000
    0.1000
         0


dist_F =

    0.1000
    0.9000
         0


dist_R =

         0
    0.9000
    0.1000


relate_L =

         0         0
    0.1000    0.1000
    0.1000    0.1000
         0         0
    0.9000    0.9000
    0.1000    0.1000
         0         0
         0         0
         0         0
         0         0
    0.1000    0.1000
    0.1000    0.1000
         0         0
    0.1000    0.1000
    0.1000    0.1000
         0         0
         0         0
         0         0
         0         0
         0         0
         0         0
         0         0
         0         0
         0         0
         0         0
         0         0
         0         0


v_out_th_L =

    0.1000
    0.9000
         0
         0
    0.1000


v_out_th_R =

    0.9000
         0
    0.1000
         0
         0
```

----

## Same method of calculating centroid (crisp output)

After we have all the degree of membership across all values. We can calculate Centroid.

We get centroid by estimating integral. With $\Delta t = 0.01$.  
1. For every crisp values of output, check the degree membership values. So we have array of $x=\{-\infty,...,+\infty\}$ to check the degree of membership, and array of degree of membership $\mu(x)$. Except, practically it is not $-\infty$ to $+\infty$  
2. This is how we check degree of membership. Choose the maximum value between memberships. But should always below $\text{out_thresh_vector}$  
    Example: threshold vector is $\{10\%,90\%,80\%\}$, degree of output membership is $\{30\%,70\%,0\%\}$, so the real output is $\text{MAX}(\text{MIN}(\{10\%,90\%,80\%\},\{30\%,70\%,0\%\}))$  
    or   
    $\text{MIN}(\{10\%,90\%,80\%\},\{30\%,70\%,0\%\}))=\{10\%,70\%,0\%\}$  
    $\text{MAX}(\{10\%,70\%,0\%\})=70\%$  

----

3. Centroid or crisp output $x^*$ is formulated as  
$$
x^*=
\frac{\Sigma^n_{i=1} \ x_i \ \mu(x_i)}{\Sigma^n_{i=1}\ x_i}
$$
    where $n$ is number of samples in the fuzzy set.  

----

EXAMPLE:
```c=
%% example 3
dist_L = check_obstacle_membership(21) %left obstacle sensor
dist_F = check_obstacle_membership(29) %forward obstacle sensor
dist_R = check_obstacle_membership(41) %right obstacle sensor
dis = check_distance_membership(17.2);
[relate_L, v_out_th_L, v_out_th_R] = relate_OAFLC(dist_L,dist_F,dist_R, rules_output_OAFLC)

%% ---------CENTROID OUTPUT R---------
dt = 0.01;
t = -10:dt:15; %output data
out = [];
for i=1:length(t)
    ret=check_vl_vr_oaflc_membership(t(i)); %output fuzzification
    ret = min(v_out_th_R, ret);
    %Max value / real value of the inference
    out = [out max(ret)]; %MAX
end
figure(4)
plot(t,out)
grid

centeroid_VR = sum(out.*t)/sum(out)
```

----

RESULT (Output of right wheel):  
![](https://i.imgur.com/XQVHboj.png)  
and the crisp output value  
```
centeroid_VR =

   -4.7757
```  

----

EXAMPLE:   
```c=
%% example 3
dist_L = check_obstacle_membership(21) %left obstacle sensor
dist_F = check_obstacle_membership(29) %forward obstacle sensor
dist_R = check_obstacle_membership(41) %right obstacle sensor
dis = check_distance_membership(17.2);
[relate_L, v_out_th_L, v_out_th_R] = relate_OAFLC(dist_L,dist_F,dist_R, rules_output_OAFLC)

%% ---------CENTROID OUTPUT L---------
dt = 0.01;
t = -10:dt:15; %output data
out = [];
for i=1:length(t)
    ret=check_vl_vr_oaflc_membership(t(i)); %output fuzzification
    ret = min(v_out_th_L, ret);
    %Max value / real value of the inference
    out = [out max(ret)]; %MAX
end
figure(3)
plot(t,out)
grid

centeroid_VL = sum(out.*t)/sum(out)
```

----

RESULT (Output of Left wheel):  
![](https://i.imgur.com/76OL4Q1.png)  
and  
```
centeroid_VL =

   -1.3677
```

---

# Supplemental resource

[image link](https://www.mathworks.com/help/fuzzy/types-of-fuzzy-inference-systems.html)
![](https://i.imgur.com/yVQlWEQ.png)

---

# References

[1] Faisal, Mohammed, et al. "Fuzzy logic navigation and obstacle avoidance by a mobile robot in an unknown dynamic environment." International Journal of Advanced Robotic Systems 10.1 (2013): 37.  
[2] [Mamdani and Sugeno Fuzzy Inference Systems](https://www.mathworks.com/help/fuzzy/types-of-fuzzy-inference-systems.html)  
[3] [Defuzzification Techniques Debasis Samanta IIT Kharagpur 09.02.2018](https://cse.iitkgp.ac.in/~dsamanta/courses/sca/resources/slides/FL-03%20Defuzzification.pdf)  
[4] [Fuzzy logic, Explained](https://medium.com/verifyas/fuzzy-logic-explained-67c075c2b228)   
[5]

###### tags: `fuzzy logic` `matlab`