radiate_alters/mutators/
jitter.rs1use radiate_core::{
2 AlterResult, BoundedGene, Chromosome, FloatGene, Gene, Mutate, random_provider,
3};
4
5#[derive(Debug, Clone)]
13pub struct JitterMutator {
14 rate: f32,
15 magnitude: f32,
16}
17
18impl JitterMutator {
19 pub fn new(rate: f32, magnitude: f32) -> Self {
20 if !(0.0..=1.0).contains(&rate) {
21 panic!("Rate must be between 0 and 1");
22 }
23
24 if magnitude <= 0.0 {
25 panic!("Magnitude must be greater than 0");
26 }
27
28 Self { rate, magnitude }
29 }
30}
31
32impl<C> Mutate<C> for JitterMutator
33where
34 C: Chromosome<Gene = FloatGene>,
35{
36 fn rate(&self) -> f32 {
37 self.rate
38 }
39
40 #[inline]
41 fn mutate_chromosome(&self, chromosome: &mut C, rate: f32) -> AlterResult {
42 let mut count = 0;
43
44 for gene in chromosome.genes_mut() {
45 if random_provider::random::<f32>() < rate {
46 let change = random_provider::range(-1.0..1.0) * self.magnitude;
47 let new_allele = gene.allele() + change;
48 let (min, max) = gene.bounds();
49
50 (*gene.allele_mut()) = new_allele.clamp(*min, *max);
51 count += 1;
52 }
53 }
54
55 count.into()
56 }
57}