fuzzy_logic_rs/
defuzzifications.rs1use std::iter::zip;
2
3#[derive(Debug)]
4pub enum Defuzzifiers {
5 Centroid,
6 Bisection,
7 Custom(fn(Vec<f64>, &Vec<f64>) -> f64),
8}
9
10impl Defuzzifiers {
11 pub fn defuzzify(&self, vec: Vec<f64>, universe: &Vec<f64>) -> f64 {
12 match self {
13 Self::Centroid => centroid_defuzzification(vec, universe),
14 Self::Bisection => bisection_defuzzification(vec, universe),
15 Self::Custom(f) => f(vec, universe),
16 }
17 }
18}
19
20pub fn centroid_defuzzification(vec: Vec<f64>, universe: &Vec<f64>) -> f64 {
21 let numerator: f64 = zip(&vec, universe).map(|(e, u)| e * u).sum();
22 let denominator: f64 = (&vec).iter().sum();
23 let idx = numerator / denominator;
24 idx
25}
26
27pub fn bisection_defuzzification(vec: Vec<f64>, universe: &Vec<f64>) -> f64 {
28 let total_area: f64 = vec.iter().sum();
29 let mut idx = 0;
30 for i in 0..vec.len() {
31 let mut area = 0.0;
32 for ii in 0..i {
33 area += vec[ii]
34 }
35 if area > total_area * 0.5 {
36 idx = i;
37 break;
38 }
39 }
40 universe[idx]
41}
42
43#[derive(Debug)]
44pub enum TSKDefuzzifiers {
45 Mean,
46 Custom(fn(&Vec<f64>, &Vec<f64>) -> f64),
47}
48
49impl TSKDefuzzifiers {
50 pub fn defuzzify(&self, mu_vec: &Vec<f64>, weighed_input: &Vec<f64>) -> f64 {
51 match self {
52 Self::Mean => mean_tsk_defuzzification(mu_vec, weighed_input),
53 Self::Custom(fun) => fun(mu_vec, weighed_input),
54 }
55 }
56}
57
58pub fn mean_tsk_defuzzification(mu_vec: &Vec<f64>, weighed_input: &Vec<f64>) -> f64 {
59 let den: f64 = weighed_input.iter().sum();
60 let num: f64 = mu_vec.iter().zip(weighed_input).map(|(mu, i)| mu * i).sum();
61 num / den
62}