Cleanup a little

This commit is contained in:
Joshua Coles 2023-03-04 14:41:47 +00:00
parent 973bcf0381
commit 92ef0f728c
9 changed files with 168 additions and 148 deletions

View File

@ -1,7 +1,7 @@
#![feature(array_zip)] #![feature(array_zip)]
use crate::system::Position; use system::Storage;
use crate::system::storage::{Storage, VectorStorage}; use crate::system::grid::{Position, VectorStorage};
mod system; mod system;
@ -35,7 +35,7 @@ pub extern "C" fn walk(d: u32, i: i32, j: i32) -> CPosition {
mod test { mod test {
use num_integer::Integer; use num_integer::Integer;
use crate::CPosition; use crate::CPosition;
use crate::system::Position; use crate::system::grid::Position;
pub(crate) fn a(d: u32, i: i32, j: i32) -> CPosition { pub(crate) fn a(d: u32, i: i32, j: i32) -> CPosition {
match d { match d {

36
src/example_systems.rs Normal file
View File

@ -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<SmallRng, Position, VectorStorage, LocalRandomWalker> {
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<SmallRng, Position, VectorStorage, LocalRandomWalker> {
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<SmallRng, NDPosition<3>, NDVectorStorage<3>, LocalRandomWalker> {
DLASystem::new_g(
SmallRng::seed_from_u64(seed),
NDVectorStorage::new(1600),
LocalRandomWalker,
stick_probability,
max_particles,
)
}

View File

@ -4,15 +4,18 @@ use std::path::PathBuf;
use rand::prelude::*; use rand::prelude::*;
mod system; mod system;
mod example_systems;
use system::walker::{Walker, LocalRandomWalker}; use system::walker::{LocalRandomWalker, Walker};
use system::storage::{Storage, VectorStorage}; use system::grid::VectorStorage;
use num_integer::Integer; use num_integer::Integer;
use rand::rngs::SmallRng; use rand::rngs::SmallRng;
use crate::system::{Position}; use crate::system::grid::Position;
use crate::system::model::DLASystem; use crate::system::model::DLASystem;
use crate::system::Storage;
use clap::Parser; use clap::Parser;
use crate::example_systems::stick_probability;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
struct Cli { struct Cli {
@ -27,8 +30,8 @@ fn main() {
println!("Running: {:?}", cli); println!("Running: {:?}", cli);
let mut sys = DLASystem::<SmallRng, Position, VectorStorage, LocalRandomWalker>::new( let mut sys = stick_probability(
SmallRng::seed_from_u64(cli.seed), cli.seed,
cli.max_particles, cli.max_particles,
cli.stick_probability cli.stick_probability
); );

104
src/system/grid.rs Normal file
View File

@ -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<bool>,
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<R: Rng>(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<Position> 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;
}
}

View File

@ -2,10 +2,11 @@ use std::f32::consts::PI;
use std::ops::Add; use std::ops::Add;
use num_integer::Integer; use num_integer::Integer;
use rand::Rng; use rand::Rng;
use serde::{Serialize, Deserialize, Serializer}; use serde::{Deserialize, Serialize, Serializer};
use crate::system::grid::VectorStorage;
pub mod walker; pub mod walker;
pub mod storage; pub mod grid;
pub mod model; pub mod model;
pub mod nd; pub mod nd;
@ -19,60 +20,7 @@ pub trait GriddedPosition: Add<Output=Self> + Serialize + Clone {
fn linear_index(&self, grid_size: u32) -> usize; fn linear_index(&self, grid_size: u32) -> usize;
} }
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub trait Storage<P: GriddedPosition> {
pub struct Position { fn at(&self, position: &P) -> bool;
pub x: i32, fn deposit(&mut self, position: &P);
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<R: Rng>(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;
}
} }

View File

@ -4,10 +4,10 @@ use std::io::Write;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
use rand::prelude::*; use rand::prelude::*;
use crate::system::{GriddedPosition, Position}; use crate::system::{GriddedPosition, grid::Position, Storage};
use crate::system::storage::{Storage, VectorStorage}; use crate::system::grid::VectorStorage;
use crate::system::walker::{LocalRandomWalker, Walker}; use crate::system::walker::{LocalRandomWalker, Walker};
use serde::{Serialize, Deserialize}; use serde::{Deserialize, Serialize};
use crate::system::nd::{NDPosition, NDVectorStorage}; use crate::system::nd::{NDPosition, NDVectorStorage};
pub struct DLASystem<R: Rng, P: GriddedPosition, S: Storage<P>, W: Walker<P>> { pub struct DLASystem<R: Rng, P: GriddedPosition, S: Storage<P>, W: Walker<P>> {
@ -31,15 +31,15 @@ pub struct DLASystem<R: Rng, P: GriddedPosition, S: Storage<P>, W: Walker<P>> {
} }
impl<R: Rng, P: GriddedPosition, S: Storage<P>, W: Walker<P>> DLASystem<R, P, S, W> { impl<R: Rng, P: GriddedPosition, S: Storage<P>, W: Walker<P>> DLASystem<R, P, S, W> {
pub fn new(rng: R, max_particles: usize, stick_probability: f32) -> DLASystem<R, Position, VectorStorage, LocalRandomWalker> { pub fn new_g(rng: R, space: S, walker: W, stick_probability: f32, max_particles: usize) -> Self {
let mut sys: DLASystem<R, Position, VectorStorage, LocalRandomWalker> = DLASystem { let mut sys = DLASystem {
rng, rng,
stick_probability, stick_probability,
max_particles, max_particles,
running: true, running: true,
space: VectorStorage::new(1600), space,
walker: LocalRandomWalker, walker,
particles: vec![], particles: vec![],
active_particle: None, active_particle: None,
@ -51,32 +51,7 @@ impl<R: Rng, P: GriddedPosition, S: Storage<P>, W: Walker<P>> DLASystem<R, P, S,
cluster_radius: 0.0, cluster_radius: 0.0,
}; };
sys.deposit(&Position::zero()); sys.deposit(&P::zero());
sys
}
pub fn new_nd<const DIM: usize>(rng: R, max_particles: usize, stick_probability: f32) -> DLASystem<R, NDPosition<DIM>, NDVectorStorage<DIM>, LocalRandomWalker> {
let mut sys: DLASystem<R, NDPosition<DIM>, NDVectorStorage<DIM>, 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 sys
} }

View File

@ -4,7 +4,7 @@ use rand::Rng;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use serde::ser::SerializeMap; use serde::ser::SerializeMap;
use crate::system::GriddedPosition; use crate::system::GriddedPosition;
use crate::system::storage::Storage; use crate::system::Storage;
pub struct NDVectorStorage<const DIM: usize> { pub struct NDVectorStorage<const DIM: usize> {
backing: Vec<bool>, backing: Vec<bool>,

View File

@ -1,46 +0,0 @@
use crate::system::{GriddedPosition, Position};
pub trait Storage<P: GriddedPosition> {
fn at(&self, position: &P) -> bool;
fn deposit(&mut self, position: &P);
}
pub struct VectorStorage {
backing: Vec<bool>,
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<Position> 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;
}
}

View File

@ -1,6 +1,6 @@
use num_integer::Integer; use num_integer::Integer;
use rand::prelude::Rng; use rand::prelude::Rng;
use crate::system::{GriddedPosition, Position}; use crate::system::{GriddedPosition, grid::Position};
pub trait Walker<P: GriddedPosition> { pub trait Walker<P: GriddedPosition> {
fn walk<R: Rng>(&self, rng: &mut R, position: &P) -> P; fn walk<R: Rng>(&self, rng: &mut R, position: &P) -> P;
@ -17,7 +17,7 @@ impl<Position: GriddedPosition> Walker<Position> for LocalRandomWalker {
mod test { mod test {
use rand::rngs::SmallRng; use rand::rngs::SmallRng;
use rand::{SeedableRng, thread_rng}; use rand::{SeedableRng, thread_rng};
use crate::system::{GriddedPosition, Position}; use crate::system::{GriddedPosition, grid::Position};
use crate::system::walker::{LocalRandomWalker, Walker}; use crate::system::walker::{LocalRandomWalker, Walker};
#[test] #[test]