pub struct Population<B: Backend, K: TensorGenome> { /* private fields */ }Expand description
Population stored on a Burn backend device.
The concrete tensor type depends on the genome kind K, chosen at compile
time through TensorGenome::Tensor: Real is backed by Tensor<B, 2>,
Binary and Integer by Tensor<B, 2, Int>. Because the storage type is a
function of K, there is a single tensor field and no run-time tag — a
population can never hold the wrong tensor flavour for its kind, so the
tensor accessor is total (it cannot fail).
The K: TensorGenome bound is what keeps this honest: kinds without a
rectangular tensor form (e.g. Tree) do not implement
TensorGenome, so Population<B, Tree> does not type-check.
Implementations§
Source§impl<B: Backend, K: TensorGenome> Population<B, K>
impl<B: Backend, K: TensorGenome> Population<B, K>
Sourcepub fn pop_size(&self) -> usize
pub fn pop_size(&self) -> usize
Returns the number of individuals (rows) in the population.
This value equals tensor.dims()[0].
Sourcepub fn genome_dim(&self) -> usize
pub fn genome_dim(&self) -> usize
Returns the genome dimensionality (number of genes, i.e. columns).
This value equals tensor.dims()[1].
Sourcepub fn tensor(&self) -> &K::Tensor<B>
pub fn tensor(&self) -> &K::Tensor<B>
Borrows the backing tensor for this population’s kind.
The concrete type is K::Tensor<B> — a
Tensor<B, 2> for Real, a Tensor<B, 2, Int> for Binary/Integer
— with shape [pop_size, genome_dim]. Use it to pass the population to
fitness functions or operator kernels without giving up ownership.
Sourcepub fn into_tensor(self) -> K::Tensor<B>
pub fn into_tensor(self) -> K::Tensor<B>
Consumes the wrapper and returns the owned tensor.
Prefer this over tensor when handing the
population off to a strategy or operator that needs ownership (e.g. to
avoid a clone on the hot path).
Source§impl<B: Backend> Population<B, Real>
impl<B: Backend> Population<B, Real>
Sourcepub fn new_real(tensor: Tensor<B, 2>) -> Result<Self, ConfigError>
pub fn new_real(tensor: Tensor<B, 2>) -> Result<Self, ConfigError>
Constructs a real-valued population from a Tensor<B, 2>.
Shape is read from tensor.dims() at construction time; subsequent
calls to pop_size and
genome_dim reflect those dimensions.
§Errors
Returns ConstraintKind::Zero
(as field "pop_size" or "genome_dim") if the tensor has zero rows
or zero columns. Rejecting the empty case here names Population as the
source instead of surfacing later as an opaque operator panic.
§Examples
use burn::backend::Flex;
use burn::tensor::{Tensor, TensorData};
use rlevo_evolution::genome::Real;
use rlevo_evolution::population::Population;
let device = Default::default();
let data = TensorData::new(vec![1.0f32, 2.0, 3.0, 4.0], [2, 2]);
let pop = Population::<Flex, Real>::new_real(
Tensor::from_data(data, &device),
).unwrap();
assert_eq!(pop.pop_size(), 2);
assert_eq!(pop.genome_dim(), 2);Source§impl<B: Backend> Population<B, Binary>
impl<B: Backend> Population<B, Binary>
Sourcepub fn new_binary(tensor: Tensor<B, 2, Int>) -> Result<Self, ConfigError>
pub fn new_binary(tensor: Tensor<B, 2, Int>) -> Result<Self, ConfigError>
Constructs a binary population from a Tensor<B, 2, Int>.
Each element is expected to be 0 or 1; the constructor does not
validate element values. Shape is read from tensor.dims().
§Errors
Returns ConstraintKind::Zero
(as field "pop_size" or "genome_dim") if the tensor has zero rows
or zero columns.
§Examples
use burn::backend::Flex;
use burn::tensor::{Int, Tensor, TensorData};
use rlevo_evolution::genome::Binary;
use rlevo_evolution::population::Population;
let device = Default::default();
// 3 individuals, each with a 4-bit binary genome.
let data = TensorData::new(vec![0i64, 1, 0, 1,
1, 0, 1, 0,
0, 0, 1, 1], [3, 4]);
let pop = Population::<Flex, Binary>::new_binary(
Tensor::from_data(data, &device),
).unwrap();
assert_eq!(pop.pop_size(), 3);
assert_eq!(pop.genome_dim(), 4);Source§impl<B: Backend> Population<B, Integer>
impl<B: Backend> Population<B, Integer>
Sourcepub fn new_integer(tensor: Tensor<B, 2, Int>) -> Result<Self, ConfigError>
pub fn new_integer(tensor: Tensor<B, 2, Int>) -> Result<Self, ConfigError>
Constructs an integer population from a Tensor<B, 2, Int>.
Elements represent non-negative integer indices (e.g. node indices in
CGP, symbol indices in integer-coded GA). The constructor does not
validate element bounds. Shape is read from tensor.dims().
§Errors
Returns ConstraintKind::Zero
(as field "pop_size" or "genome_dim") if the tensor has zero rows
or zero columns.
§Examples
use burn::backend::Flex;
use burn::tensor::{Int, Tensor, TensorData};
use rlevo_evolution::genome::Integer;
use rlevo_evolution::population::Population;
let device = Default::default();
// 2 individuals, each with a 5-gene integer-valued genome.
let data = TensorData::new(vec![0i64, 3, 1, 4, 2,
2, 0, 4, 1, 3], [2, 5]);
let pop = Population::<Flex, Integer>::new_integer(
Tensor::from_data(data, &device),
).unwrap();
assert_eq!(pop.pop_size(), 2);
assert_eq!(pop.genome_dim(), 5);Source§impl<B: Backend> Population<B, Permutation>
impl<B: Backend> Population<B, Permutation>
Sourcepub fn new_permutation(tensor: Tensor<B, 2, Int>) -> Result<Self, ConfigError>
pub fn new_permutation(tensor: Tensor<B, 2, Int>) -> Result<Self, ConfigError>
Constructs a permutation population from a Tensor<B, 2, Int>.
Each row is assumed to be a permutation of 0..genome_dim, but the
constructor validates only shape — the per-row bijection invariant is
not checked, mirroring how new_binary and
new_integer leave element values unchecked.
Shape is read from tensor.dims().
The permutation operators (Ant Colony Optimization over TSP/QAP) are
planned for a future release; this constructor exists so downstream code
can allocate and reference Population<B, Permutation> today.
§Errors
Returns ConstraintKind::Zero
(as field "pop_size" or "genome_dim") if the tensor has zero rows
or zero columns.
§Examples
use burn::backend::Flex;
use burn::tensor::{Int, Tensor, TensorData};
use rlevo_evolution::genome::Permutation;
use rlevo_evolution::population::Population;
let device = Default::default();
// 2 ants, each a permutation of a 4-node tour.
let data = TensorData::new(vec![0i64, 1, 2, 3,
2, 0, 3, 1], [2, 4]);
let pop = Population::<Flex, Permutation>::new_permutation(
Tensor::from_data(data, &device),
).unwrap();
assert_eq!(pop.pop_size(), 2);
assert_eq!(pop.genome_dim(), 4);Trait Implementations§
Source§impl<B: Clone + Backend, K: Clone + TensorGenome> Clone for Population<B, K>
impl<B: Clone + Backend, K: Clone + TensorGenome> Clone for Population<B, K>
Source§fn clone(&self) -> Population<B, K>
fn clone(&self) -> Population<B, K>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl<B, K> Freeze for Population<B, K>
impl<B, K> RefUnwindSafe for Population<B, K>
impl<B, K> Send for Population<B, K>
impl<B, K> Sync for Population<B, K>
impl<B, K> Unpin for Population<B, K>
impl<B, K> UnsafeUnpin for Population<B, K>
impl<B, K> UnwindSafe for Population<B, K>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<C> CloneExpand for Cwhere
C: Clone,
impl<C> CloneExpand for Cwhere
C: Clone,
fn __expand_clone_method(&self, _scope: &mut Scope) -> C
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more