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