From 92ef0f728c57466290fa1fdcba365dca871cbbf7 Mon Sep 17 00:00:00 2001 From: Joshua Coles Date: Sat, 4 Mar 2023 14:41:47 +0000 Subject: [PATCH] Cleanup a little --- src/clib.rs | 6 +-- src/example_systems.rs | 36 ++++++++++++++ src/main.rs | 13 ++++-- src/system/grid.rs | 104 +++++++++++++++++++++++++++++++++++++++++ src/system/mod.rs | 64 +++---------------------- src/system/model.rs | 41 ++++------------ src/system/nd.rs | 2 +- src/system/storage.rs | 46 ------------------ src/system/walker.rs | 4 +- 9 files changed, 168 insertions(+), 148 deletions(-) create mode 100644 src/example_systems.rs create mode 100644 src/system/grid.rs delete mode 100644 src/system/storage.rs diff --git a/src/clib.rs b/src/clib.rs index 75e612c..5a896ce 100644 --- a/src/clib.rs +++ b/src/clib.rs @@ -1,7 +1,7 @@ #![feature(array_zip)] -use crate::system::Position; -use crate::system::storage::{Storage, VectorStorage}; +use system::Storage; +use crate::system::grid::{Position, VectorStorage}; mod system; @@ -35,7 +35,7 @@ pub extern "C" fn walk(d: u32, i: i32, j: i32) -> CPosition { mod test { use num_integer::Integer; use crate::CPosition; - use crate::system::Position; + use crate::system::grid::Position; pub(crate) fn a(d: u32, i: i32, j: i32) -> CPosition { match d { diff --git a/src/example_systems.rs b/src/example_systems.rs new file mode 100644 index 0000000..f68e0d9 --- /dev/null +++ b/src/example_systems.rs @@ -0,0 +1,36 @@ +use rand::rngs::SmallRng; +use rand::SeedableRng; +use crate::system::grid::{Position, VectorStorage}; +use crate::system::model::DLASystem; +use crate::system::nd::{NDPosition, NDVectorStorage}; +use crate::system::walker::LocalRandomWalker; + +pub fn initial_config(seed: u64, max_particles: usize) -> DLASystem { + DLASystem::new_g( + SmallRng::seed_from_u64(seed), + VectorStorage::new(1600), + LocalRandomWalker, + 1.0, + max_particles, + ) +} + +pub fn stick_probability(seed: u64, max_particles: usize, stick_probability: f32) -> DLASystem { + DLASystem::new_g( + SmallRng::seed_from_u64(seed), + VectorStorage::new(1600), + LocalRandomWalker, + stick_probability, + max_particles, + ) +} + +pub fn three_dimensional(seed: u64, max_particles: usize, stick_probability: f32) -> DLASystem, NDVectorStorage<3>, LocalRandomWalker> { + DLASystem::new_g( + SmallRng::seed_from_u64(seed), + NDVectorStorage::new(1600), + LocalRandomWalker, + stick_probability, + max_particles, + ) +} diff --git a/src/main.rs b/src/main.rs index 8b2a1c6..466af4c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,15 +4,18 @@ use std::path::PathBuf; use rand::prelude::*; mod system; +mod example_systems; -use system::walker::{Walker, LocalRandomWalker}; -use system::storage::{Storage, VectorStorage}; +use system::walker::{LocalRandomWalker, Walker}; +use system::grid::VectorStorage; use num_integer::Integer; use rand::rngs::SmallRng; -use crate::system::{Position}; +use crate::system::grid::Position; use crate::system::model::DLASystem; +use crate::system::Storage; use clap::Parser; +use crate::example_systems::stick_probability; #[derive(Parser, Debug)] struct Cli { @@ -27,8 +30,8 @@ fn main() { println!("Running: {:?}", cli); - let mut sys = DLASystem::::new( - SmallRng::seed_from_u64(cli.seed), + let mut sys = stick_probability( + cli.seed, cli.max_particles, cli.stick_probability ); diff --git a/src/system/grid.rs b/src/system/grid.rs new file mode 100644 index 0000000..93ea1b1 --- /dev/null +++ b/src/system/grid.rs @@ -0,0 +1,104 @@ +use std::f32::consts::PI; +use std::ops::Add; +use num_integer::Integer; +use rand::Rng; +use crate::system::{GriddedPosition, Storage}; +use serde::{Serialize, Deserialize}; + +pub struct VectorStorage { + backing: Vec, + grid_size: u32, +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Position { + pub x: i32, + pub y: i32, +} + +impl Position { + pub fn in_direction(direction: u32, value: i32) -> Self { + if direction == 0 { Position { x: value, y: 0 } } else { Position { x: 0, y: value } } + } +} + +impl Add for Position { + type Output = Position; + + fn add(self, rhs: Self) -> Self::Output { + Position { x: self.x + rhs.x, y: self.y + rhs.y } + } +} + +impl GriddedPosition for Position { + const NEIGHBOURS: u32 = 4; + + fn zero() -> Position { + Position { x: 0, y: 0 } + } + + fn spawn(rng: &mut R, radius: f32) -> Self { + let theta = rng.gen_range(0f32..1.0) * 2.0 * PI; + let (x, y) = (radius * theta.cos(), radius * theta.sin()); + Position { x: x as i32, y: y as i32 } + } + + fn abs(&self) -> f32 { + ((self.x.pow(2) + self.y.pow(2)) as f32).powf(0.5) + } + + fn neighbour(&self, neighbour_index: u32) -> Self { + let (dim, sign) = neighbour_index.div_rem(&2); + let sign = if sign == 0 { 1 } else { -1 }; + let offset = Position::in_direction(dim, sign); + + self.clone() + offset + } + + fn linear_index(&self, grid_size: u32) -> usize { + let grid_size = grid_size as i32; + + assert!(self.x <= grid_size && -(grid_size) <= self.x); + assert!(self.y <= grid_size && -(grid_size) <= self.y); + + let x = (self.x + (grid_size) / 2) as usize; + let y = (self.y + (grid_size) / 2) as usize; + + return grid_size as usize * y + x; + } +} + +impl VectorStorage { + pub fn new(grid_size: u32) -> VectorStorage { + VectorStorage { grid_size, backing: vec![false; grid_size.pow(2) as usize] } + } + + pub fn linear_index(&self, position: &Position) -> usize { + assert!(position.x <= self.grid_size as i32 && -(self.grid_size as i32) <= position.x); + assert!(position.y <= self.grid_size as i32 && -(self.grid_size as i32) <= position.y); + + let x = (position.x + (self.grid_size as i32) / 2) as usize; + let y = (position.y + (self.grid_size as i32) / 2) as usize; + + return self.grid_size as usize * y + x + } + + /* + * Convenience function for c-binding + * */ + pub fn write(&mut self, position: &Position, val: bool) { + let index = self.linear_index(position); + self.backing[index] = val; + } +} + +impl Storage for VectorStorage { + fn at(&self, position: &Position) -> bool { + return self.backing[self.linear_index(position)] + } + + fn deposit(&mut self, position: &Position) { + let index = self.linear_index(position); + self.backing[index] = true; + } +} diff --git a/src/system/mod.rs b/src/system/mod.rs index 2e230fe..6bfb55c 100644 --- a/src/system/mod.rs +++ b/src/system/mod.rs @@ -2,10 +2,11 @@ use std::f32::consts::PI; use std::ops::Add; use num_integer::Integer; use rand::Rng; -use serde::{Serialize, Deserialize, Serializer}; +use serde::{Deserialize, Serialize, Serializer}; +use crate::system::grid::VectorStorage; pub mod walker; -pub mod storage; +pub mod grid; pub mod model; pub mod nd; @@ -19,60 +20,7 @@ pub trait GriddedPosition: Add + Serialize + Clone { fn linear_index(&self, grid_size: u32) -> usize; } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct Position { - pub x: i32, - pub y: i32, -} - -impl Position { - pub fn in_direction(direction: u32, value: i32) -> Self { - if direction == 0 { Position { x: value, y: 0 } } else { Position { x: 0, y: value } } - } -} - -impl Add for Position { - type Output = Position; - - fn add(self, rhs: Self) -> Self::Output { - Position { x: self.x + rhs.x, y: self.y + rhs.y } - } -} - -impl GriddedPosition for Position { - const NEIGHBOURS: u32 = 4; - - fn zero() -> Position { - Position { x: 0, y: 0 } - } - - fn spawn(rng: &mut R, radius: f32) -> Self { - let theta = rng.gen_range(0f32..1.0) * 2.0 * PI; - let (x, y) = (radius * theta.cos(), radius * theta.sin()); - Position { x: x as i32, y: y as i32 } - } - - fn abs(&self) -> f32 { - ((self.x.pow(2) + self.y.pow(2)) as f32).powf(0.5) - } - - fn neighbour(&self, neighbour_index: u32) -> Self { - let (dim, sign) = neighbour_index.div_rem(&2); - let sign = if sign == 0 { 1 } else { -1 }; - let offset = Position::in_direction(dim, sign); - - self.clone() + offset - } - - fn linear_index(&self, grid_size: u32) -> usize { - let grid_size = grid_size as i32; - - assert!(self.x <= grid_size && -(grid_size) <= self.x); - assert!(self.y <= grid_size && -(grid_size) <= self.y); - - let x = (self.x + (grid_size) / 2) as usize; - let y = (self.y + (grid_size) / 2) as usize; - - return grid_size as usize * y + x; - } +pub trait Storage { + fn at(&self, position: &P) -> bool; + fn deposit(&mut self, position: &P); } diff --git a/src/system/model.rs b/src/system/model.rs index ecbdbb0..f4c02c3 100644 --- a/src/system/model.rs +++ b/src/system/model.rs @@ -4,10 +4,10 @@ use std::io::Write; use std::io; use std::path::Path; use rand::prelude::*; -use crate::system::{GriddedPosition, Position}; -use crate::system::storage::{Storage, VectorStorage}; +use crate::system::{GriddedPosition, grid::Position, Storage}; +use crate::system::grid::VectorStorage; use crate::system::walker::{LocalRandomWalker, Walker}; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use crate::system::nd::{NDPosition, NDVectorStorage}; pub struct DLASystem, W: Walker

> { @@ -31,15 +31,15 @@ pub struct DLASystem, W: Walker

> { } impl, W: Walker

> DLASystem { - pub fn new(rng: R, max_particles: usize, stick_probability: f32) -> DLASystem { - let mut sys: DLASystem = DLASystem { + pub fn new_g(rng: R, space: S, walker: W, stick_probability: f32, max_particles: usize) -> Self { + let mut sys = DLASystem { rng, stick_probability, max_particles, running: true, - space: VectorStorage::new(1600), - walker: LocalRandomWalker, + space, + walker, particles: vec![], active_particle: None, @@ -51,32 +51,7 @@ impl, W: Walker

> DLASystem(rng: R, max_particles: usize, stick_probability: f32) -> DLASystem, NDVectorStorage, LocalRandomWalker> { - let mut sys: DLASystem, NDVectorStorage, LocalRandomWalker> = DLASystem { - rng, - stick_probability, - max_particles, - running: true, - - space: NDVectorStorage::new(1600), - walker: LocalRandomWalker, - particles: vec![], - active_particle: None, - - add_ratio: 1.2, - kill_ratio: 1.7, - - add_circle: 10.0, - kill_circle: 20.0, - cluster_radius: 0.0, - }; - - sys.deposit(&NDPosition::zero()); + sys.deposit(&P::zero()); sys } diff --git a/src/system/nd.rs b/src/system/nd.rs index 1a84b92..bd6aa0a 100644 --- a/src/system/nd.rs +++ b/src/system/nd.rs @@ -4,7 +4,7 @@ use rand::Rng; use serde::{Serialize, Serializer}; use serde::ser::SerializeMap; use crate::system::GriddedPosition; -use crate::system::storage::Storage; +use crate::system::Storage; pub struct NDVectorStorage { backing: Vec, diff --git a/src/system/storage.rs b/src/system/storage.rs deleted file mode 100644 index 65c2039..0000000 --- a/src/system/storage.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::system::{GriddedPosition, Position}; - -pub trait Storage { - fn at(&self, position: &P) -> bool; - fn deposit(&mut self, position: &P); -} - -pub struct VectorStorage { - backing: Vec, - grid_size: u32, -} - -impl VectorStorage { - pub fn new(grid_size: u32) -> VectorStorage { - VectorStorage { grid_size, backing: vec![false; grid_size.pow(2) as usize] } - } - - pub fn linear_index(&self, position: &Position) -> usize { - assert!(position.x <= self.grid_size as i32 && -(self.grid_size as i32) <= position.x); - assert!(position.y <= self.grid_size as i32 && -(self.grid_size as i32) <= position.y); - - let x = (position.x + (self.grid_size as i32) / 2) as usize; - let y = (position.y + (self.grid_size as i32) / 2) as usize; - - return self.grid_size as usize * y + x - } - - /* - * Convenience function for c-binding - * */ - pub fn write(&mut self, position: &Position, val: bool) { - let index = self.linear_index(position); - self.backing[index] = val; - } -} - -impl Storage for VectorStorage { - fn at(&self, position: &Position) -> bool { - return self.backing[self.linear_index(position)] - } - - fn deposit(&mut self, position: &Position) { - let index = self.linear_index(position); - self.backing[index] = true; - } -} diff --git a/src/system/walker.rs b/src/system/walker.rs index c563dd4..fbe8ad8 100644 --- a/src/system/walker.rs +++ b/src/system/walker.rs @@ -1,6 +1,6 @@ use num_integer::Integer; use rand::prelude::Rng; -use crate::system::{GriddedPosition, Position}; +use crate::system::{GriddedPosition, grid::Position}; pub trait Walker { fn walk(&self, rng: &mut R, position: &P) -> P; @@ -17,7 +17,7 @@ impl Walker for LocalRandomWalker { mod test { use rand::rngs::SmallRng; use rand::{SeedableRng, thread_rng}; - use crate::system::{GriddedPosition, Position}; + use crate::system::{GriddedPosition, grid::Position}; use crate::system::walker::{LocalRandomWalker, Walker}; #[test]