radiate_core/genome/chromosomes/
float.rs1use super::{
2 Chromosome,
3 gene::{ArithmeticGene, Gene, Valid},
4};
5use crate::random_provider;
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8use std::{
9 fmt::{Debug, Display},
10 ops::{Add, Bound, Div, Mul, Range, RangeBounds, 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 pub fn bounds(&self) -> &Range<f32> {
59 &self.bounds
60 }
61}
62
63impl Valid for FloatGene {
69 fn is_valid(&self) -> bool {
70 self.allele >= self.bounds.start && self.allele <= self.bounds.end
71 }
72}
73
74impl Gene for FloatGene {
75 type Allele = f32;
76
77 fn allele(&self) -> &f32 {
78 &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 ArithmeticGene 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 mean(&self, other: &FloatGene) -> FloatGene {
108 FloatGene {
109 allele: (self.allele + other.allele) / 2_f32,
110 value_range: self.value_range.clone(),
111 bounds: self.bounds.clone(),
112 }
113 }
114
115 fn from_f32(&self, value: f32) -> Self {
116 FloatGene {
117 allele: value,
118 value_range: self.value_range.clone(),
119 bounds: self.bounds.clone(),
120 }
121 }
122}
123
124impl RangeBounds<f32> for FloatGene {
125 fn start_bound(&self) -> Bound<&f32> {
126 self.bounds.start_bound()
127 }
128
129 fn end_bound(&self) -> Bound<&f32> {
130 self.bounds.end_bound()
131 }
132}
133
134impl Add for FloatGene {
135 type Output = FloatGene;
136
137 fn add(self, other: FloatGene) -> FloatGene {
138 FloatGene {
139 allele: self.allele + other.allele,
140 value_range: self.value_range.clone(),
141 bounds: self.bounds.clone(),
142 }
143 }
144}
145
146impl Sub for FloatGene {
147 type Output = FloatGene;
148
149 fn sub(self, other: FloatGene) -> FloatGene {
150 FloatGene {
151 allele: self.allele - other.allele,
152 value_range: self.value_range.clone(),
153 bounds: self.bounds.clone(),
154 }
155 }
156}
157
158impl Mul for FloatGene {
159 type Output = FloatGene;
160
161 fn mul(self, other: FloatGene) -> FloatGene {
162 FloatGene {
163 allele: self.allele * other.allele,
164 value_range: self.value_range.clone(),
165 bounds: self.bounds.clone(),
166 }
167 }
168}
169
170impl Div for FloatGene {
171 type Output = FloatGene;
172
173 fn div(self, other: FloatGene) -> FloatGene {
174 let denominator = if other.allele == 0.0 {
175 1.0
176 } else {
177 other.allele
178 };
179
180 FloatGene {
181 allele: self.allele / denominator,
182 value_range: self.value_range.clone(),
183 bounds: self.bounds.clone(),
184 }
185 }
186}
187
188impl Default for FloatGene {
189 fn default() -> Self {
190 FloatGene {
191 allele: 0.0,
192 value_range: MIN..MAX,
193 bounds: MIN..MAX,
194 }
195 }
196}
197
198impl From<FloatGene> for f32 {
199 fn from(gene: FloatGene) -> f32 {
200 gene.allele
201 }
202}
203
204impl From<f32> for FloatGene {
205 fn from(allele: f32) -> Self {
206 FloatGene {
207 allele,
208 value_range: MIN..MAX,
209 bounds: MIN..MAX,
210 }
211 }
212}
213
214impl From<Range<f32>> for FloatGene {
215 fn from(range: Range<f32>) -> Self {
216 let (min, max) = (range.start.max(MIN), range.end.min(MAX));
217
218 FloatGene {
219 allele: random_provider::range(range),
220 value_range: min..max,
221 bounds: min..max,
222 }
223 }
224}
225
226impl From<(Range<f32>, Range<f32>)> for FloatGene {
227 fn from((value_range, bounds): (Range<f32>, Range<f32>)) -> Self {
228 let value_range = value_range.start.max(MIN)..value_range.end.min(MAX);
229 let bounds = bounds.start.max(MIN)..bounds.end.min(MAX);
230 let allele = random_provider::range(value_range.clone());
231
232 FloatGene {
233 allele,
234 value_range,
235 bounds,
236 }
237 }
238}
239
240impl Display for FloatGene {
241 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
242 write!(f, "{}", self.allele)
243 }
244}
245
246#[derive(Clone, PartialEq, Default)]
283#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
284pub struct FloatChromosome {
285 genes: Vec<FloatGene>,
286}
287
288impl FloatChromosome {
289 pub fn new(genes: Vec<FloatGene>) -> Self {
290 FloatChromosome { genes }
291 }
292}
293
294impl Chromosome for FloatChromosome {
295 type Gene = FloatGene;
296
297 fn genes(&self) -> &[Self::Gene] {
298 &self.genes
299 }
300
301 fn genes_mut(&mut self) -> &mut [Self::Gene] {
302 &mut self.genes
303 }
304}
305
306impl Valid for FloatChromosome {
307 fn is_valid(&self) -> bool {
308 self.genes.iter().all(|gene| gene.is_valid())
309 }
310}
311
312impl From<Vec<FloatGene>> for FloatChromosome {
313 fn from(genes: Vec<FloatGene>) -> Self {
314 FloatChromosome { genes }
315 }
316}
317
318impl From<Vec<f32>> for FloatChromosome {
319 fn from(alleles: Vec<f32>) -> Self {
320 FloatChromosome {
321 genes: alleles.into_iter().map(FloatGene::from).collect(),
322 }
323 }
324}
325
326impl From<(usize, Range<f32>)> for FloatChromosome {
327 fn from((size, range): (usize, Range<f32>)) -> Self {
328 FloatChromosome {
329 genes: (0..size).map(|_| FloatGene::from(range.clone())).collect(),
330 }
331 }
332}
333
334impl From<(usize, Range<f32>, Range<f32>)> for FloatChromosome {
335 fn from((size, range, bounds): (usize, Range<f32>, Range<f32>)) -> Self {
336 FloatChromosome {
337 genes: (0..size)
338 .map(|_| FloatGene::from((range.clone(), bounds.clone())))
339 .collect(),
340 }
341 }
342}
343
344impl Debug for FloatChromosome {
345 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
346 write!(f, "{:?}", self.genes)
347 }
348}
349
350#[cfg(test)]
351mod tests {
352
353 use super::*;
354
355 #[test]
356 fn test_new() {
357 let gene_one = FloatGene::from(0_f32..1_f32);
358 let gene_two = FloatGene::from((-1.0..1.0, -100.0..100.0));
359 let gene_three = FloatGene::new(10.0, (MIN * 10.0)..(MAX * 10.0), -1000.0..1000.0);
360
361 assert_eq!(*gene_one.min(), 0_f32);
362 assert_eq!(*gene_one.max(), 1_f32);
363 assert_eq!(gene_one.start_bound(), Bound::Included(&0_f32));
364 assert_eq!(gene_one.end_bound(), Bound::Excluded(&1_f32));
365 assert!(gene_one.is_valid());
366
367 assert_eq!(*gene_two.min(), -1.0);
368 assert_eq!(*gene_two.max(), 1.0);
369 assert_eq!(gene_two.start_bound(), Bound::Included(&-100.0));
370 assert_eq!(gene_two.end_bound(), Bound::Excluded(&100.0));
371 assert!(gene_two.is_valid());
372
373 assert_eq!(*gene_three.allele(), 10.0);
374 assert_eq!(*gene_three.min(), MIN);
375 assert_eq!(*gene_three.max(), MAX);
376 assert_eq!(gene_three.start_bound(), Bound::Included(&-1000.0));
377 assert_eq!(gene_three.end_bound(), Bound::Excluded(&1000.0));
378 }
379
380 #[test]
381 fn test_into() {
382 let gene = FloatGene::from(0_f32..1_f32);
383 let copy = gene.clone();
384 let allele: f32 = gene.into();
385 assert_eq!(allele, copy.allele);
386 }
387
388 #[test]
389 fn test_from() {
390 let gene = FloatGene::from(0_f32..1_f32);
391 let copy = gene.clone();
392 assert_eq!(gene, copy);
393 }
394
395 #[test]
396 fn test_is_valid() {
397 let gene = FloatGene::from(0_f32..1_f32);
398 assert!(gene.is_valid());
399 assert!(gene.allele >= 0_f32 && gene.allele <= 1_f32);
400 }
401
402 #[test]
403 fn test_chromosome() {
404 let chromosome = FloatChromosome::from((10, -1.0..1.0));
405
406 assert_eq!(chromosome.len(), 10);
407 assert!(chromosome.is_valid());
408 for gene in chromosome.iter() {
409 assert!(gene.is_valid());
410 assert!(gene.allele >= -1.0 && gene.allele <= 1.0);
411 }
412 }
413
414 #[test]
415 fn test_chromosome_from_vec() {
416 let chromosome = FloatChromosome::from(vec![0.0, 1.0, 2.0]);
417
418 assert_eq!(chromosome.len(), 3);
419 assert!(chromosome.is_valid());
420 for (gene, allele) in chromosome.iter().zip(vec![0.0, 1.0, 2.0]) {
421 assert!(gene.is_valid());
422 assert_eq!(gene.allele, allele);
423 }
424 }
425
426 #[test]
427 fn test_chromosome_from_range_with_bounds() {
428 let chromosome = FloatChromosome::from((3, 0.0..10.0, -10.0..10.0));
429
430 assert_eq!(chromosome.len(), 3);
431 assert!(chromosome.is_valid());
432 for gene in chromosome.iter() {
433 assert!(gene.is_valid());
434 assert!(gene.allele >= 0.0 && gene.allele <= 10.0);
435 assert!(gene.bounds.start >= -10.0 && gene.bounds.end <= 10.0);
436 }
437 }
438
439 #[test]
440 fn test_gene_arithmetic() {
441 let gene_one = FloatGene::from(5_f32);
442 let gene_two = FloatGene::from(10_f32);
443 let zero_gene = FloatGene::from(0_f32);
444
445 let add = gene_one.clone() + gene_two.clone();
446 let sub = gene_one.clone() - gene_two.clone();
447 let mul = gene_one.clone() * gene_two.clone();
448 let div = gene_one.clone() / gene_two.clone();
449 let mean = gene_one.clone().mean(&gene_two.clone());
450 let div_zero = gene_one.clone() / zero_gene.clone();
451
452 assert_eq!(add.allele, 15_f32);
453 assert_eq!(sub.allele, -5_f32);
454 assert_eq!(mul.allele, 50_f32);
455 assert_eq!(div.allele, 0.5_f32);
456 assert_eq!(mean.allele, 7.5_f32);
457 assert_eq!(div_zero.allele, 5_f32);
458 }
459
460 #[test]
461 #[cfg(feature = "serde")]
462 fn test_float_gene_serialization() {
463 let gene = FloatGene::from(0.5_f32..1.5_f32);
464
465 assert!(gene.is_valid());
466
467 let serialized = serde_json::to_string(&gene).expect("Failed to serialize FloatGene");
468 let deserialized: FloatGene =
469 serde_json::from_str(&serialized).expect("Failed to deserialize FloatGene");
470
471 let chromosome = FloatChromosome::from((10, 0.0..1.0, -1.0..1.0));
472 let serialized_chromosome =
473 serde_json::to_string(&chromosome).expect("Failed to serialize FloatChromosome");
474 let deserialized_chromosome: FloatChromosome = serde_json::from_str(&serialized_chromosome)
475 .expect("Failed to deserialize FloatChromosome");
476
477 assert_eq!(gene, deserialized);
478 assert_eq!(chromosome, deserialized_chromosome);
479 }
480}