Skip to content

Commit

Permalink
added optimize method and half benchmark for bna
Browse files Browse the repository at this point in the history
  • Loading branch information
samyhaff committed Feb 23, 2024
1 parent b0bacad commit 1a6bb59
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 18 deletions.
14 changes: 6 additions & 8 deletions src/bin/bna.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use std::f64::consts::PI;
use neuroevolution::vneuron::*;
use neuroevolution::bna::*;

fn main() {
let input = vec![1., PI / 8.];
let dim = 2;
let bend = PI / 4.;
let angles = vec![PI / 4.];
let bias = 0.;
let vneuron = VNeuron::from_params(dim, bias, angles, bend);
println!("{:?}", vneuron.evaluate(&input));
let mut vneuron = VNeuron::new(2);

vneuron.optimize(half, 1000);
println!("half fitness: {}", half(&vneuron));
println!("Half: {}", vneuron);
}
2 changes: 1 addition & 1 deletion src/bin/oneplusone_na.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use neuroevolution::one_plus_one_na::*;
use neuroevolution::oneplusone_na::*;
use neuroevolution::network::Network;

fn main() {
Expand Down
16 changes: 16 additions & 0 deletions src/bna.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::f64::consts::PI;
use crate::vneuron::*;

const UNIT_CIRCLE_STEPS: u32 = 1000;

pub fn half(vneuron: &VNeuron) -> f64 {
let mut sum = 0;
for i in 0..UNIT_CIRCLE_STEPS {
let angle = 2. * PI * i as f64 / UNIT_CIRCLE_STEPS as f64;
let output = vneuron.evaluate(&vec![1., angle]);
if output && angle < PI || !output && angle > PI {
sum += 1;
}
}
sum as f64 / UNIT_CIRCLE_STEPS as f64
}
10 changes: 5 additions & 5 deletions src/cma_es.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@ use crate::network::*;

pub fn half<const N: usize>(x: &DVector<f64>) -> f64 {
let network: Network<N,2> = get_network(&x);
crate::one_plus_one_na::half(&network)
crate::oneplusone_na::half(&network)
}

pub fn quarter<const N: usize>(x: &DVector<f64>) -> f64 {
let network: Network<N,2> = get_network(&x);
crate::one_plus_one_na::quarter(&network)
crate::oneplusone_na::quarter(&network)
}

pub fn two_quarters<const N: usize>(x: &DVector<f64>) -> f64 {
let network: Network<N,2> = get_network(&x);
crate::one_plus_one_na::two_quarters(&network)
crate::oneplusone_na::two_quarters(&network)
}

pub fn square<const N: usize>(x: &DVector<f64>) -> f64 {
let network: Network<N,2> = get_network(&x);
crate::one_plus_one_na::square(&network)
crate::oneplusone_na::square(&network)
}

pub fn cube<const N: usize>(x: &DVector<f64>) -> f64 {
let network: Network<N,3> = get_network(&x);
crate::one_plus_one_na::cube(&network)
crate::oneplusone_na::cube(&network)
}
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod one_plus_one_na;
pub mod oneplusone_na;
pub mod cma_es;
pub mod network;
pub mod vneuron;
pub mod utils;
pub mod bna;
File renamed without changes.
55 changes: 52 additions & 3 deletions src/vneuron.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::fmt;
use std::f64::consts::PI;
use rand::prelude::*;
use rand_distr::{Exp, Distribution};
use crate::utils::*;

#[derive(Debug, Clone)]
Expand All @@ -10,13 +12,32 @@ pub struct VNeuron {
pub bend: f64,
}

impl fmt::Display for VNeuron {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut formatted_angles = String::new();
for angle in &self.angles {
let formatted_angle = format!("{:.2}", angle * 2.0 * PI);
formatted_angles.push_str(&formatted_angle);
formatted_angles.push_str(", ");
}

let formatted_bias = format!("{:.2}", self.bias * 2.0 - 1.0);
let formatted_bend = format!("{:.2}", self.bend * PI);

write!(
f,
"VNeuron {{ dim: {}, bias: {}, angles: [{}], bend: {} }}",
self.dim, formatted_bias, formatted_angles, formatted_bend
)
}
}

impl VNeuron {
pub fn new(dim: usize) -> Self {
// genereate random values between 0 and 1
Self {
dim,
bias: random(),
angles: vec![random(); dim],
angles: vec![random(); dim - 1],
bend: random(),
}
}
Expand All @@ -26,7 +47,35 @@ impl VNeuron {
dim,
bias: (bias + 1.) / 2.,
angles: angles.iter().map(|x| x / (2. * PI)).collect(),
bend: bend / (2. * PI),
bend: bend / PI,
}
}

fn mutate_component(component: &mut f64) {
let exp = Exp::new(1.).unwrap();
let sign = if random::<f64>() < 0.5 { 1. } else { -1. };
*component += sign * exp.sample(&mut thread_rng());
*component -= component.floor();
}

pub fn optimize(&mut self, evaluation_function: fn(&VNeuron) -> f64, n_iters: u32) {
for _ in 0..n_iters {
let mut new_vneuron = self.clone();
if random::<f64>() < 1. / 3. {
VNeuron::mutate_component(&mut new_vneuron.bend);
}
for i in 0..self.dim-1 {
if random::<f64>() < 1. / 3. {
VNeuron::mutate_component(&mut new_vneuron.angles[i]);
}
}
if random::<f64>() < 1. / 3. {
VNeuron::mutate_component(&mut new_vneuron.bias);
}

if evaluation_function(&new_vneuron) > evaluation_function(self) {
*self = new_vneuron;
}
}
}

Expand Down

0 comments on commit 1a6bb59

Please sign in to comment.