radiate_core/genome/chromosomes/
float.rs1use super::{
2 Chromosome,
3 gene::{ArithmeticGene, BoundedGene, Gene, Valid},
4};
5use crate::random_provider;
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8use std::{
9 fmt::{Debug, Display},
10 ops::{Add, Div, Mul, Range, Sub},
11};
12
13const MIN: f32 = -1e10;
17const MAX: f32 = 1e10;
18
19#[derive(Clone, PartialEq, Debug)]
41#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
42pub struct FloatGene {
43 allele: f32,
44 value_range: Range<f32>,
45 bounds: Range<f32>,
46}
47
48impl FloatGene {
49 pub fn new(allele: f32, value_range: Range<f32>, bounds: Range<f32>) -> Self {
51 FloatGene {
52 allele,
53 value_range: MIN.max(value_range.start)..MAX.min(value_range.end),
54 bounds: MIN.max(bounds.start)..MAX.min(bounds.end),
55 }
56 }
57}
58
59impl Valid for FloatGene {
65 fn is_valid(&self) -> bool {
66 self.allele >= self.bounds.start && self.allele <= self.bounds.end
67 }
68}
69
70impl Gene for FloatGene {
71 type Allele = f32;
72
73 fn allele(&self) -> &f32 {
74 &self.allele
75 }
76
77 fn allele_mut(&mut self) -> &mut f32 {
78 &mut self.allele
79 }
80
81 fn new_instance(&self) -> FloatGene {
82 FloatGene {
83 allele: random_provider::range(self.value_range.clone()),
84 value_range: self.value_range.clone(),
85 bounds: self.bounds.clone(),
86 }
87 }
88
89 fn with_allele(&self, allele: &f32) -> FloatGene {
90 FloatGene {
91 allele: *allele,
92 value_range: self.value_range.clone(),
93 bounds: self.bounds.clone(),
94 }
95 }
96}
97
98impl BoundedGene for FloatGene {
99 fn min(&self) -> &Self::Allele {
100 &self.value_range.start
101 }
102
103 fn max(&self) -> &Self::Allele {
104 &self.value_range.end
105 }
106
107 fn bounds(&self) -> (&Self::Allele, &Self::Allele) {
108 (&self.bounds.start, &self.bounds.end)
109 }
110}
111
112impl ArithmeticGene for FloatGene {
113 fn mean(&self, other: &FloatGene) -> FloatGene {
114 FloatGene {
115 allele: ((self.allele + other.allele) * 0.5).clamp(self.bounds.start, self.bounds.end),
116 value_range: self.value_range.clone(),
117 bounds: self.bounds.clone(),
118 }
119 }
120}
121
122impl Add for FloatGene {
123 type Output = FloatGene;
124
125 fn add(self, other: FloatGene) -> FloatGene {
126 FloatGene {
127 allele: (self.allele + other.allele).clamp(self.bounds.start, self.bounds.end),
128 value_range: self.value_range.clone(),
129 bounds: self.bounds.clone(),
130 }
131 }
132}
133
134impl Sub for FloatGene {
135 type Output = FloatGene;
136
137 fn sub(self, other: FloatGene) -> FloatGene {
138 FloatGene {
139 allele: (self.allele - other.allele).clamp(self.bounds.start, self.bounds.end),
140 value_range: self.value_range.clone(),
141 bounds: self.bounds.clone(),
142 }
143 }
144}
145
146impl Mul for FloatGene {
147 type Output = FloatGene;
148
149 fn mul(self, other: FloatGene) -> FloatGene {
150 FloatGene {
151 allele: (self.allele * other.allele).clamp(self.bounds.start, self.bounds.end),
152 value_range: self.value_range.clone(),
153 bounds: self.bounds.clone(),
154 }
155 }
156}
157
158impl Div for FloatGene {
159 type Output = FloatGene;
160
161 fn div(self, other: FloatGene) -> FloatGene {
162 let denominator = if other.allele == 0.0 {
163 1.0
164 } else {
165 other.allele
166 };
167
168 FloatGene {
169 allele: (self.allele / denominator).clamp(self.bounds.start, self.bounds.end),
170 value_range: self.value_range.clone(),
171 bounds: self.bounds.clone(),
172 }
173 }
174}
175
176impl Default for FloatGene {
177 fn default() -> Self {
178 FloatGene {
179 allele: 0.0,
180 value_range: MIN..MAX,
181 bounds: MIN..MAX,
182 }
183 }
184}
185
186impl From<FloatGene> for f32 {
187 fn from(gene: FloatGene) -> f32 {
188 gene.allele
189 }
190}
191
192impl From<f32> for FloatGene {
193 fn from(allele: f32) -> Self {
194 FloatGene {
195 allele,
196 value_range: MIN..MAX,
197 bounds: MIN..MAX,
198 }
199 }
200}
201
202impl From<Range<f32>> for FloatGene {
203 fn from(range: Range<f32>) -> Self {
204 let (min, max) = (range.start.max(MIN), range.end.min(MAX));
205
206 FloatGene {
207 allele: random_provider::range(range),
208 value_range: min..max,
209 bounds: min..max,
210 }
211 }
212}
213
214impl From<(Range<f32>, Range<f32>)> for FloatGene {
215 fn from((value_range, bounds): (Range<f32>, Range<f32>)) -> Self {
216 let value_range = value_range.start.max(MIN)..value_range.end.min(MAX);
217 let bounds = bounds.start.max(MIN)..bounds.end.min(MAX);
218 let allele = random_provider::range(value_range.clone());
219
220 FloatGene {
221 allele,
222 value_range,
223 bounds,
224 }
225 }
226}
227
228impl Display for FloatGene {
229 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
230 write!(f, "{}", self.allele)
231 }
232}
233
234#[derive(Clone, PartialEq, Default)]
273#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
274pub struct FloatChromosome {
275 genes: Vec<FloatGene>,
276}
277
278impl FloatChromosome {
279 pub fn new(genes: Vec<FloatGene>) -> Self {
280 FloatChromosome { genes }
281 }
282}
283
284impl Chromosome for FloatChromosome {
285 type Gene = FloatGene;
286
287 fn genes(&self) -> &[Self::Gene] {
288 &self.genes
289 }
290
291 fn genes_mut(&mut self) -> &mut [Self::Gene] {
292 &mut self.genes
293 }
294}
295
296impl Valid for FloatChromosome {
297 fn is_valid(&self) -> bool {
298 self.genes.iter().all(|gene| gene.is_valid())
299 }
300}
301
302impl From<FloatGene> for FloatChromosome {
303 fn from(gene: FloatGene) -> Self {
304 FloatChromosome { genes: vec![gene] }
305 }
306}
307
308impl From<Vec<FloatGene>> for FloatChromosome {
309 fn from(genes: Vec<FloatGene>) -> Self {
310 FloatChromosome { genes }
311 }
312}
313
314impl From<Vec<f32>> for FloatChromosome {
315 fn from(alleles: Vec<f32>) -> Self {
316 FloatChromosome {
317 genes: alleles.into_iter().map(FloatGene::from).collect(),
318 }
319 }
320}
321
322impl From<(usize, Range<f32>)> for FloatChromosome {
323 fn from((size, range): (usize, Range<f32>)) -> Self {
324 FloatChromosome {
325 genes: (0..size).map(|_| FloatGene::from(range.clone())).collect(),
326 }
327 }
328}
329
330impl From<(usize, Range<f32>, Range<f32>)> for FloatChromosome {
331 fn from((size, range, bounds): (usize, Range<f32>, Range<f32>)) -> Self {
332 FloatChromosome {
333 genes: (0..size)
334 .map(|_| FloatGene::from((range.clone(), bounds.clone())))
335 .collect(),
336 }
337 }
338}
339
340impl FromIterator<FloatGene> for FloatChromosome {
341 fn from_iter<I: IntoIterator<Item = FloatGene>>(iter: I) -> Self {
342 FloatChromosome {
343 genes: iter.into_iter().collect(),
344 }
345 }
346}
347
348impl IntoIterator for FloatChromosome {
349 type Item = FloatGene;
350 type IntoIter = std::vec::IntoIter<FloatGene>;
351
352 fn into_iter(self) -> Self::IntoIter {
353 self.genes.into_iter()
354 }
355}
356
357impl Debug for FloatChromosome {
358 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
359 write!(f, "{:?}", self.genes)
360 }
361}
362
363#[cfg(test)]
364mod tests {
365
366 use super::*;
367
368 #[test]
369 fn test_new() {
370 let gene_one = FloatGene::from(0_f32..1_f32);
371 let gene_two = FloatGene::from((-1.0..1.0, -100.0..100.0));
372 let gene_three = FloatGene::new(10.0, (MIN * 10.0)..(MAX * 10.0), -1000.0..1000.0);
373
374 assert_eq!(*gene_one.max(), 1_f32);
376 assert_eq!(gene_one.bounds().0, &0_f32);
377 assert_eq!(gene_one.bounds().1, &1_f32);
378 assert!(gene_one.is_valid());
379
380 assert_eq!(*gene_two.max(), 1.0);
382 assert_eq!(gene_two.bounds().0, &-100.0);
383 assert_eq!(gene_two.bounds().1, &100.0);
384 assert!(gene_two.is_valid());
385
386 assert_eq!(*gene_three.allele(), 10.0);
387 assert_eq!(*gene_three.max(), MAX);
389 assert_eq!(gene_three.bounds().0, &-1000.0);
390 assert_eq!(gene_three.bounds().1, &1000.0);
391 }
392
393 #[test]
394 fn test_into() {
395 let gene = FloatGene::from(0_f32..1_f32);
396 let copy = gene.clone();
397 let allele: f32 = gene.into();
398 assert_eq!(allele, copy.allele);
399 }
400
401 #[test]
402 fn test_from() {
403 let gene = FloatGene::from(0_f32..1_f32);
404 let copy = gene.clone();
405 assert_eq!(gene, copy);
406 }
407
408 #[test]
409 fn test_is_valid() {
410 let gene = FloatGene::from(0_f32..1_f32);
411 assert!(gene.is_valid());
412 assert!(gene.allele >= 0_f32 && gene.allele <= 1_f32);
413 }
414
415 #[test]
416 fn test_gene_clamping() {
417 let one = FloatGene::new(5.0, 0.0..10.0, 0.0..10.0);
418 let two = FloatGene::new(5.0, 0.0..10.0, 0.0..10.0);
419 let really_big = FloatGene::new(100000.0, 0.0..10.0, 0.0..10.0);
420
421 let add = one.clone() + two.clone();
422 let sub = one.clone() - two.clone();
423 let mul = one.clone() * two.clone();
424 let div = one.clone() / two.clone();
425
426 assert_eq!(add.allele, 10.0);
427 assert_eq!(sub.allele, 0.0);
428 assert_eq!(mul.allele, 10.0);
429 assert_eq!(div.allele, 1.0);
430
431 let big_add = one.clone() + really_big.clone();
432 let big_sub = one.clone() - really_big.clone();
433 let big_mul = one.clone() * really_big.clone();
434 let big_div = really_big.clone() / one.clone();
435
436 assert_eq!(big_add.allele, 10.0);
437 assert_eq!(big_sub.allele, 0.0);
438 assert_eq!(big_mul.allele, 10.0);
439 assert_eq!(big_div.allele, 10.0);
440 }
441
442 #[test]
443 fn test_chromosome() {
444 let chromosome = FloatChromosome::from((10, -1.0..1.0));
445
446 assert_eq!(chromosome.len(), 10);
447 assert!(chromosome.is_valid());
448 for gene in chromosome.iter() {
449 assert!(gene.is_valid());
450 assert!(gene.allele >= -1.0 && gene.allele <= 1.0);
451 }
452 }
453
454 #[test]
455 fn test_chromosome_from_vec() {
456 let chromosome = FloatChromosome::from(vec![0.0, 1.0, 2.0]);
457
458 assert_eq!(chromosome.len(), 3);
459 assert!(chromosome.is_valid());
460 for (gene, allele) in chromosome.iter().zip(vec![0.0, 1.0, 2.0]) {
461 assert!(gene.is_valid());
462 assert_eq!(gene.allele, allele);
463 }
464 }
465
466 #[test]
467 fn test_chromosome_from_range_with_bounds() {
468 let chromosome = FloatChromosome::from((3, 0.0..10.0, -10.0..10.0));
469
470 assert_eq!(chromosome.len(), 3);
471 assert!(chromosome.is_valid());
472 for gene in chromosome.iter() {
473 assert!(gene.is_valid());
474 assert!(gene.allele >= 0.0 && gene.allele <= 10.0);
475 assert!(gene.bounds.start >= -10.0 && gene.bounds.end <= 10.0);
476 }
477 }
478
479 #[test]
480 fn test_gene_arithmetic() {
481 let gene_one = FloatGene::from(5_f32);
482 let gene_two = FloatGene::from(10_f32);
483 let zero_gene = FloatGene::from(0_f32);
484
485 let add = gene_one.clone() + gene_two.clone();
486 let sub = gene_one.clone() - gene_two.clone();
487 let mul = gene_one.clone() * gene_two.clone();
488 let div = gene_one.clone() / gene_two.clone();
489 let mean = gene_one.clone().mean(&gene_two.clone());
490 let div_zero = gene_one.clone() / zero_gene.clone();
491
492 assert_eq!(add.allele, 15_f32);
493 assert_eq!(sub.allele, -5_f32);
494 assert_eq!(mul.allele, 50_f32);
495 assert_eq!(div.allele, 0.5_f32);
496 assert_eq!(mean.allele, 7.5_f32);
497 assert_eq!(div_zero.allele, 5_f32);
498 }
499
500 #[test]
501 #[cfg(feature = "serde")]
502 fn test_float_gene_serialization() {
503 let gene = FloatGene::from(0.5_f32..1.5_f32);
504
505 assert!(gene.is_valid());
506
507 let serialized = serde_json::to_string(&gene).expect("Failed to serialize FloatGene");
508 let deserialized: FloatGene =
509 serde_json::from_str(&serialized).expect("Failed to deserialize FloatGene");
510
511 let chromosome = FloatChromosome::from((10, 0.0..1.0, -1.0..1.0));
512 let serialized_chromosome =
513 serde_json::to_string(&chromosome).expect("Failed to serialize FloatChromosome");
514 let deserialized_chromosome: FloatChromosome = serde_json::from_str(&serialized_chromosome)
515 .expect("Failed to deserialize FloatChromosome");
516
517 assert_eq!(gene, deserialized);
518 assert_eq!(chromosome, deserialized_chromosome);
519 }
520}