genomic/chromosome/
mod.rs1use rand::{distributions::Distribution, Rng};
2
3mod uniform;
4pub use uniform::*;
5
6mod fixed;
7pub use fixed::*;
8
9pub trait Chromosome {
10 fn mutate(&mut self, rate: f64, rng: &mut impl Rng);
14}
15
16macro_rules! impl_ch_int {
17 ( $type:ty ) => {
18 impl Chromosome for $type {
19 fn mutate(&mut self, rate: f64, rng: &mut impl Rng) {
20 debug_assert!(rate <= 1.0);
21 debug_assert!(rate >= 0.0);
22 let distribution = rand::distributions::Bernoulli::new(rate * 0.5)
23 .expect("`rate` should be between 0.0 and 1.0");
24
25 for (bit, should_flip) in (0..<$type>::BITS).zip(distribution.sample_iter(rng)) {
26 if should_flip {
27 *self ^= 1 << bit;
28 }
29 }
30 }
31 }
32 };
33}
34
35impl_ch_int!(u8);
36impl_ch_int!(u16);
37impl_ch_int!(u32);
38impl_ch_int!(u64);
39impl_ch_int!(u128);
40impl_ch_int!(i8);
41impl_ch_int!(i16);
42impl_ch_int!(i32);
43impl_ch_int!(i64);
44impl_ch_int!(i128);
45
46impl Chromosome for () {
47 fn mutate(&mut self, _rate: f64, _rng: &mut impl Rng) {
49 }
51}
52
53impl<T: Chromosome + ?Sized> Chromosome for Box<T> {
54 fn mutate(&mut self, rate: f64, rng: &mut impl Rng) {
55 self.as_mut().mutate(rate, rng);
56 }
57}
58
59impl Chromosome for bool {
60 fn mutate(&mut self, rate: f64, rng: &mut impl Rng) {
61 if rng.gen_bool(rate * 0.5) {
62 *self = !*self;
63 }
64 }
65}