use nalgebra::{allocator::Allocator, DefaultAllocator, Dim, OVector, Scalar, U1}; use rand::RngCore; use crate::{binary_string::BinaryString, bounded::{Bounded, BoundedBinaryString}}; pub trait Initializer { fn initialize_single(&self, size: D, rng: &mut dyn RngCore) -> T; fn initialize(&self, size: D, count: usize, rng: &mut dyn RngCore) -> Vec { (0..count).map(|_| self.initialize_single(size, rng)).collect() } } // Always initializes with zeros pub struct ZeroInitializer; impl ZeroInitializer { pub fn new() -> Self { Self { } } } impl Initializer> for ZeroInitializer where D: Dim, DefaultAllocator: Allocator { fn initialize_single(&self, size: D, rng: &mut dyn RngCore) -> BinaryString { BinaryString::::from_ovector( >>::initialize_single(self, size, rng) ) } } impl Initializer> for ZeroInitializer where T: Scalar + Default, D: Dim, DefaultAllocator: Allocator { fn initialize_single(&self, size: D, _rng: &mut dyn RngCore) -> OVector { OVector::::from_element_generic(size, U1, Default::default()) } } pub struct RandomInitializer { bounded: Box> } impl RandomInitializer { pub fn new(bounded: Box>) -> Self { Self { bounded } } } impl RandomInitializer> where D: Dim, DefaultAllocator: Allocator { pub fn new_binary() -> Self { Self { bounded: Box::new(BoundedBinaryString::unbounded()) } } } impl Initializer> for RandomInitializer> where D: Dim, DefaultAllocator: Allocator { fn initialize_single(&self, size: D, rng: &mut dyn RngCore) -> BinaryString { self.bounded.next_random(size, rng) } } impl Initializer> for RandomInitializer> where T: Scalar + Default, D: Dim, DefaultAllocator: Allocator { fn initialize_single(&self, size: D, rng: &mut dyn RngCore) -> OVector { self.bounded.next_random(size, rng) } }