Skip to content

Commit

Permalink
Merge pull request #28 from mfajnberg/draft_mutation
Browse files Browse the repository at this point in the history
Add our first reference implementations for crossover and mutation functions
  • Loading branch information
daniil-berg authored Mar 29, 2024
2 parents 35e4063 + 9652624 commit 503468b
Show file tree
Hide file tree
Showing 7 changed files with 443 additions and 132 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ ndarray = { version = "0.15.6", features = ["serde"] }
num-traits = "*"
ordered-float = "*"
rand = "*"
rand_distr = "*"
serde = { version = "*", features = ["derive"] }
serde_json = "*"
tempfile = "*"
Expand Down
22 changes: 22 additions & 0 deletions src/individual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::fs::read_to_string;
use std::io::Error as IOError;
use std::path::Path;
use std::ops::Index;
use std::slice::Iter;

use log::trace;
use num_traits::FromPrimitive;
Expand Down Expand Up @@ -97,6 +98,16 @@ impl<T: Tensor> Individual<T> {
self.layers.len()
}

/// Returns an iterator over the individual's layers.
pub fn iter(&self) -> Iter<'_, Layer<T>> {
self.into_iter()
}

/// Returns a reference to the individual's cost function.
pub fn get_cost_function(&self) -> &CostFunction<T> {
&self.cost_function
}

/// Passes the `input` through the network and returns the intermediate results of each layer.
///
/// # Arguments
Expand Down Expand Up @@ -339,6 +350,17 @@ impl<T: Tensor> Index<usize> for Individual<T> {
}


/// Allows turning a reference to an `Individual` into an iterator over [`Layer`] references.
impl<'a, T: Tensor> IntoIterator for &'a Individual<T> {
type Item = &'a Layer<T>;
type IntoIter = Iter<'a, Layer<T>>;

fn into_iter(self) -> Self::IntoIter {
self.layers.iter()
}
}


#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 4 additions & 0 deletions src/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ impl<T: Tensor> Layer<T> {
let activation = (self.activation)(&weighted_input);
(weighted_input, activation)
}

pub fn size(&self) -> usize {
self.weights.shape().0
}
}


Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub mod component;
pub mod cost_function;
pub mod individual;
pub mod layer;
pub mod population;
pub mod tensor;
pub mod utils;
pub mod world;

130 changes: 0 additions & 130 deletions src/population.rs

This file was deleted.

64 changes: 63 additions & 1 deletion src/tensor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use std::fmt::{Debug, Display};
use std::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign};

use ndarray::{Array2, Axis};
use ndarray::{Array2, Axis, ArrayView};
use num_traits::FromPrimitive;
use num_traits::real::Real;
use serde::Serialize;
Expand All @@ -30,6 +30,11 @@ pub trait TensorBase:

/// Creates a tensor of the specified `shape` with all components equal to `num`.
fn from_num(num: Self::Component, shape: (usize, usize)) -> Self;

fn from_iter<I, J>(iterator: I) -> Self
where
I: IntoIterator<Item = J>,
J: IntoIterator<Item = Self::Component>;

/// Returns the shape of the tensor as a tuple of unsigned integers.
fn shape(&self) -> (usize, usize);
Expand All @@ -40,6 +45,12 @@ pub trait TensorBase:
/// Returns the transpose of itself as a new tensor.
fn transpose(&self) -> Self;

/// Append a row to the tensor.
fn append_row(&mut self, row: &[Self::Component]);

/// Append a column to the tensor.
fn append_column(&mut self, column: &[Self::Component]);

/// Calls function `f` on each component and returns the result as a new tensor.
fn map<F>(&self, f: F) -> Self
where F: FnMut(Self::Component) -> Self::Component;
Expand All @@ -48,6 +59,12 @@ pub trait TensorBase:
fn map_inplace<F>(&mut self, f: F)
where F: FnMut(Self::Component) -> Self::Component;

fn indexed_iter(&self) -> impl Iterator<Item = ((usize, usize), &Self::Component)>;

fn indexed_iter_mut(&mut self) -> impl Iterator<Item = ((usize, usize), &mut Self::Component)>;

fn iter(&self) -> impl Iterator<Item = &Self::Component>;

/// Returns the sum of all rows (0) or columns (1) as a new tensor.
fn sum_axis(&self, axis: usize) -> Self;
}
Expand Down Expand Up @@ -158,6 +175,31 @@ impl<C: TensorComponent> TensorBase for Array2<C> {
fn from_num(num: Self::Component, shape: (usize, usize)) -> Self {
Self::from_elem(shape, num)
}

fn from_iter<I, J>(iterator: I) -> Self
where
I: IntoIterator<Item = J>,
J: IntoIterator<Item = Self::Component>,
{
let mut data = Vec::new();
let mut num_rows: usize = 0;
let mut num_columns: Option<usize> = None;
for row in iterator {
num_rows += 1;
let row_vec: Vec<Self::Component> = row.into_iter().collect();
match num_columns {
Some(n) => {
if n != row_vec.len() { panic!() }
},
None => num_columns = Some(row_vec.len()),
}
data.extend_from_slice(&row_vec);
}
Array2::from_shape_vec(
(num_rows, num_columns.unwrap_or(0)),
data,
).unwrap()
}

fn shape(&self) -> (usize, usize) {
self.dim()
Expand All @@ -174,6 +216,14 @@ impl<C: TensorComponent> TensorBase for Array2<C> {
self.t().to_owned()
}

fn append_row(&mut self, row: &[Self::Component]) {
self.push_row(ArrayView::from(row)).unwrap()
}

fn append_column(&mut self, column: &[Self::Component]) {
self.push_column(ArrayView::from(column)).unwrap()
}

fn map<F>(&self, f: F) -> Self
where F: FnMut(C) -> C {
self.mapv(f)
Expand All @@ -184,6 +234,18 @@ impl<C: TensorComponent> TensorBase for Array2<C> {
self.mapv_inplace(f)
}

fn indexed_iter(&self) -> impl Iterator<Item = ((usize, usize), &Self::Component)> {
Array2::<C>::indexed_iter(self)
}

fn indexed_iter_mut(&mut self) -> impl Iterator<Item = ((usize, usize), &mut Self::Component)> {
Array2::<C>::indexed_iter_mut(self)
}

fn iter(&self) -> impl Iterator<Item = &Self::Component> {
Array2::<C>::iter(self)
}

fn sum_axis(&self, axis: usize) -> Self {
self.sum_axis(Axis(axis)).insert_axis(Axis(axis))
}
Expand Down
Loading

0 comments on commit 503468b

Please sign in to comment.