#[derive(Debug)]
pub struct MembershipRange {
name: String,
mu: Vec<f64>,
}
impl MembershipRange {
pub fn new(name: String, mu: Vec<f64>) -> Self {
Self { name, mu }
}
pub fn new_triangle(universe: &Vec<f64>, name: String, a: f64, b: f64, c: f64) -> Self {
assert!(a < b, "a must be less than b");
assert!(b < c, "b must be less that c");
let mut mu: Vec<f64> = Vec::new();
for x in universe.into_iter() {
let data: f64;
if *x <= a {
data = 0.0;
} else if *x <= b {
data = (*x - a) / (b - a);
} else if *x <= c {
data = (c - *x) / (c - b);
} else {
data = 0.0;
}
mu.push(data);
}
Self { name, mu }
}
pub fn new_trapezoid(
universe: &Vec<f64>,
name: String,
a: f64,
b: f64,
c: f64,
d: f64,
) -> Self {
assert!(a <= b, "a must be less than b");
assert!(b <= c, "b must be less than c");
assert!(c <= d, "c must be less than d");
let mut mu: Vec<f64> = Vec::new();
let mut data: f64;
for value in universe.into_iter() {
if *value <= a {
data = 0.0;
} else if *value <= b {
data = (*value - a) / (b - a);
} else if *value <= c {
data = 1.0;
} else if *value <= d {
data = (d - *value) / (d - c);
} else {
data = 0.0;
}
mu.push(data);
}
Self { name, mu }
}
pub fn new_linearz(universe: &Vec<f64>, name: String, a: f64, b: f64) -> Self {
assert!(a < b);
let mut mu: Vec<f64> = Vec::new();
let mut data: f64;
for x in universe.into_iter() {
if *x < a {
data = 1.0;
} else if *x < b {
data = (a - *x) / (a - b);
} else {
data = 0.0;
}
mu.push(data);
}
Self { name, mu }
}
pub fn new_linears(universe: &Vec<f64>, name: String, a: f64, b: f64) -> Self {
assert!(a < b);
let mut mu: Vec<f64> = Vec::new();
let mut data: f64;
for x in universe.into_iter() {
if *x < a {
data = 0.0;
} else if *x < b {
data = (*x - a) / (b - a);
} else {
data = 1.0;
}
mu.push(data);
}
Self { name, mu }
}
pub fn new_step_down(universe: &Vec<f64>, name: String, a: f64) -> Self {
let mut mu: Vec<f64> = Vec::new();
for x in universe.into_iter() {
let mut data: f64 = 1.0;
if *x > a {
data = 0.0;
}
mu.push(data);
}
Self { name, mu }
}
pub fn new_step_up(universe: &Vec<f64>, name: String, a: f64) -> Self {
let mut mu: Vec<f64> = Vec::new();
for x in universe.into_iter() {
let mut data: f64 = 0.0;
if *x > a {
data = 1.0;
}
mu.push(data);
}
Self { name, mu }
}
pub fn new_gaussian(universe: &Vec<f64>, name: String, mean: f64, variance: f64) -> Self {
let mut mu: Vec<f64> = Vec::new();
assert!(variance > 0.0);
for x in universe.into_iter() {
let data: f64 = f64::exp(-0.5 * f64::powi((*x - mean) / variance, 2));
mu.push(data);
}
Self { name, mu }
}
pub fn new_double_gaussian(
universe: &Vec<f64>,
name: String,
mean1: f64,
variance1: f64,
mean2: f64,
variance2: f64,
) -> Self {
assert!(mean1 <= mean2, "mean1 must be less than mean2");
assert!(variance1 > 0.0);
assert!(variance2 > 0.0);
let mut mu: Vec<f64> = Vec::new();
for x in universe.into_iter() {
let data: f64;
if *x < mean1 {
data = f64::exp(-0.5 * f64::powi((*x - mean1) / variance1, 2));
} else if *x < mean2 {
data = 1.0;
} else {
data = f64::exp(-0.5 * f64::powi((*x - mean2) / variance2, 2));
}
mu.push(data);
}
Self { name, mu }
}
pub fn new_bell(
universe: &Vec<f64>,
name: String,
width: f64,
shape: f64,
center: f64,
) -> Self {
let mut mu: Vec<f64> = Vec::new();
assert!(width > 0.0);
assert!(shape > 0.0);
for x in universe.into_iter() {
let data = 1.0 / (1.0 + f64::powf(f64::abs((*x - center) / width), 2.0 * shape));
mu.push(data);
}
Self { name, mu }
}
pub fn get_mu(&self) -> &Vec<f64> {
&self.mu
}
pub fn get_name(&self) -> String {
self.name.clone()
}
}
impl IntoIterator for MembershipRange {
type Item = f64;
type IntoIter = std::vec::IntoIter<f64>;
fn into_iter(self) -> Self::IntoIter {
self.mu.into_iter()
}
}