radiate-rust 0.3.0

A Rust library for genetic algorithms and artificial evolution.
Documentation
use rand::random;

use super::gene::{BoundGene, Gene, NumericGene, Valid};

pub struct FloatGene {
    pub allele: f32,
    pub min: f32,
    pub max: f32,
    pub upper_bound: f32,
    pub lower_bound: f32,
}

impl FloatGene {
    pub fn new(min: f32, max: f32) -> Self {
        FloatGene {
            allele: random::<f32>() * (max - min) + min,
            min,
            max,
            upper_bound: f32::MAX,
            lower_bound: f32::MIN,
        }
    }
}

impl Valid for FloatGene {
    fn is_valid(&self) -> bool {
        self.allele >= self.min && self.allele <= self.max
    }
}


impl Gene<FloatGene, f32> for FloatGene {
    fn allele(&self) -> &f32 {
        &self.allele
    }

    fn new_instance(&self) -> FloatGene {
        FloatGene {
            allele: random::<f32>() * (self.max - self.min) + self.min,
            min: self.min,
            max: self.max,
            upper_bound: self.upper_bound,
            lower_bound: self.lower_bound,
        }
    }

    fn from_allele(&self, allele: &f32) -> FloatGene {
        FloatGene {
            allele: *allele,
            min: self.min,
            max: self.max,
            upper_bound: self.upper_bound,
            lower_bound: self.lower_bound
        }
    }
}

impl BoundGene<FloatGene, f32> for FloatGene {
    fn upper_bound(&self) -> &f32 {
        &self.upper_bound
    }

    fn lower_bound(&self) -> &f32 {
        &self.lower_bound
    }

    fn with_bounds(self, upper_bound: f32, lower_bound: f32) -> FloatGene {
        FloatGene {
            upper_bound,
            lower_bound,
            ..self
        }
    }
}

impl NumericGene<FloatGene, f32> for FloatGene {
    fn add(&self, other: &FloatGene) -> FloatGene {
        FloatGene {
            allele: self.allele + other.allele,
            ..*self
        }
    }

    fn sub(&self, other: &FloatGene) -> FloatGene {
        FloatGene {
            allele: self.allele - other.allele,
            ..*self
        }
    }

    fn mul(&self, other: &FloatGene) -> FloatGene {
        FloatGene {
            allele: self.allele * other.allele,
            ..*self
        }
    }

    fn div(&self, other: &FloatGene) -> FloatGene {
        let other_allele = match other.allele() == &0_f32 {
            true => 1_f32,
            false => *other.allele(),
        };
        
        FloatGene {
            allele: self.allele / other_allele,
            ..*self
        }
    }

    fn mean(&self, other: &FloatGene) -> FloatGene {
        FloatGene {
            allele: (self.allele + other.allele) / 2_f32,
            ..*self
        }
    }
}

impl Clone for FloatGene {
    fn clone(&self) -> Self {
        FloatGene {
            allele: self.allele,
            min: self.min,
            max: self.max,
            upper_bound: self.upper_bound,
            lower_bound: self.lower_bound,
        }
    }
}

impl PartialEq for FloatGene {
    fn eq(&self, other: &Self) -> bool {
        self.allele == other.allele && self.min == other.min && self.max == other.max
    }
}

impl std::fmt::Debug for FloatGene {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.allele)
    }
}