use radiate_utils::Integer;
use super::Codec;
use crate::genome::Gene;
use crate::genome::genotype::Genotype;
use crate::{Chromosome, IntChromosome};
use std::ops::Range;
#[derive(Clone)]
pub struct IntCodec<T: Integer, D = T> {
num_chromosomes: usize,
num_genes: usize,
value_range: Range<T>,
bounds: Range<T>,
_marker: std::marker::PhantomData<D>,
}
impl<T: Integer, D> IntCodec<T, D> {
pub fn with_bounds(mut self, bounds: Range<T>) -> Self {
self.bounds = bounds;
self
}
fn encode_common(&self) -> Genotype<IntChromosome<T>> {
Genotype::from(
(0..self.num_chromosomes)
.map(|_| {
IntChromosome::from((
self.num_genes,
self.value_range.clone(),
self.bounds.clone(),
))
})
.collect::<Vec<IntChromosome<T>>>(),
)
}
}
impl<T: Integer> IntCodec<T, Vec<Vec<T>>> {
pub fn matrix(rows: usize, cols: usize, range: Range<T>) -> Self {
IntCodec {
num_chromosomes: rows,
num_genes: cols,
value_range: range.clone(),
bounds: range,
_marker: std::marker::PhantomData,
}
}
}
impl<T: Integer> IntCodec<T, Vec<T>> {
pub fn vector(count: usize, range: Range<T>) -> Self {
IntCodec {
num_chromosomes: 1,
num_genes: count,
value_range: range.clone(),
bounds: range,
_marker: std::marker::PhantomData,
}
}
}
impl<T: Integer> IntCodec<T, T> {
pub fn scalar(range: Range<T>) -> Self {
IntCodec {
num_chromosomes: 1,
num_genes: 1,
value_range: range.clone(),
bounds: range,
_marker: std::marker::PhantomData,
}
}
}
impl<T: Integer> Codec<IntChromosome<T>, Vec<Vec<T>>> for IntCodec<T, Vec<Vec<T>>> {
fn encode(&self) -> Genotype<IntChromosome<T>> {
self.encode_common()
}
fn decode(&self, genotype: &Genotype<IntChromosome<T>>) -> Vec<Vec<T>> {
genotype
.iter()
.map(|chromosome| {
chromosome
.iter()
.map(|gene| *gene.allele())
.collect::<Vec<T>>()
})
.collect::<Vec<Vec<T>>>()
}
}
impl<T: Integer> Codec<IntChromosome<T>, Vec<T>> for IntCodec<T, Vec<T>> {
fn encode(&self) -> Genotype<IntChromosome<T>> {
self.encode_common()
}
fn decode(&self, genotype: &Genotype<IntChromosome<T>>) -> Vec<T> {
genotype
.iter()
.flat_map(|chromosome| {
chromosome
.iter()
.map(|gene| *gene.allele())
.collect::<Vec<T>>()
})
.collect::<Vec<T>>()
}
}
impl<T: Integer> Codec<IntChromosome<T>, T> for IntCodec<T, T> {
fn encode(&self) -> Genotype<IntChromosome<T>> {
self.encode_common()
}
fn decode(&self, genotype: &Genotype<IntChromosome<T>>) -> T {
genotype
.iter()
.flat_map(|chromosome| {
chromosome
.iter()
.map(|gene| *gene.allele())
.collect::<Vec<T>>()
})
.next()
.unwrap_or_default()
}
}
impl<T: Integer> Codec<IntChromosome<T>, Vec<Vec<T>>> for Vec<IntChromosome<T>> {
fn encode(&self) -> Genotype<IntChromosome<T>> {
Genotype::from(
self.iter()
.map(|chromosome| {
chromosome
.iter()
.map(|gene| gene.new_instance())
.collect::<IntChromosome<T>>()
})
.collect::<Vec<IntChromosome<T>>>(),
)
}
fn decode(&self, genotype: &Genotype<IntChromosome<T>>) -> Vec<Vec<T>> {
genotype
.iter()
.map(|chromosome| {
chromosome
.iter()
.map(|gene| *gene.allele())
.collect::<Vec<T>>()
})
.collect::<Vec<Vec<T>>>()
}
}
impl<T: Integer> Codec<IntChromosome<T>, Vec<T>> for IntChromosome<T> {
fn encode(&self) -> Genotype<IntChromosome<T>> {
Genotype::from(
self.iter()
.map(|gene| gene.new_instance())
.collect::<IntChromosome<T>>(),
)
}
fn decode(&self, genotype: &Genotype<IntChromosome<T>>) -> Vec<T> {
genotype
.iter()
.flat_map(|chromosome| {
chromosome
.iter()
.map(|gene| *gene.allele())
.collect::<Vec<T>>()
})
.collect::<Vec<T>>()
}
}