rust_fuzzylogic/membership/
triangular.rs1use super::{slope, validate_order, Float, MembershipFn};
2
3#[derive(Clone, Copy, PartialEq, Debug)]
6pub struct Triangular {
7 left: Float,
8 center: Float,
9 right: Float,
10}
11
12impl MembershipFn for Triangular {
13 fn eval(&self, x: Float) -> Float {
15 if x <= self.left {
17 return 0.0;
18 }
19 if x >= self.right {
20 return 0.0;
21 }
22
23 if (x - self.center).abs() < 1e-9 {
25 1.0
26 } else if x < self.center {
27 slope(x, self.left, self.center, 1.0)
28 } else {
29 slope(x, self.center, self.right, -1.0)
30 }
31 }
32}
33
34impl Triangular {
35 pub fn new(l: Float, c: Float, r: Float) -> crate::error::Result<Self> {
37 validate_order(&[l, c, r])?;
38 return Ok(Triangular {
39 left: l,
40 center: c,
41 right: r,
42 });
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn test_triangular() {
52 let membership_func = Triangular::new(-1.0, 0.0, 1.0);
53 let eps = crate::Float::EPSILON;
54
55 assert_eq!(
56 Triangular::new(0.0, 0.0, -1.0),
57 Err(crate::error::FuzzyError::BadArity)
58 );
59
60 assert!((membership_func.clone().unwrap().eval(0.0) - 1.0).abs() < eps);
61 assert!((membership_func.clone().unwrap().eval(0.5) - 0.5).abs() < eps);
62 assert!((membership_func.unwrap().eval(1.0)).abs() < eps);
63 }
64}