fuzzy_logic_rs/
defuzzifications.rs

1use 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}