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