Try out surface_probability measurement

This commit is contained in:
Joshua Coles 2023-03-08 23:59:05 +00:00
parent 183293fe7e
commit cef9024bc5
3 changed files with 90 additions and 23 deletions

View File

@ -25,13 +25,22 @@ pub struct BallsCli {
pub walk_step: f32,
}
#[derive(Args, Debug)]
pub struct SurfaceProbabilityMeasureCli {
pub grid_size: u32,
pub stick_probability: f32,
pub initial_data: PathBuf,
pub particles: u32,
}
#[derive(Subcommand, Debug)]
pub enum PCM {
Initial(InitialCli),
StickProbability(StickProbabilityCli),
Grid3(StickProbabilityCli),
Hex(StickProbabilityCli),
Balls(BallsCli)
Balls(BallsCli),
SurfaceProbabilityMeasure(SurfaceProbabilityMeasureCli),
}
#[derive(Parser, Debug)]

View File

@ -2,11 +2,13 @@
#![feature(generic_const_exprs)]
#![feature(let_chains)]
use std::ops::Deref;
use clap::Parser;
use rand::prelude::*;
use crate::cli::{drive_system};
use crate::cli::cli::{StickProbabilityCli, InitialCli, BallsCli, PCM, ModelCli};
use crate::cli::cli::{StickProbabilityCli, InitialCli, BallsCli, PCM, ModelCli, SurfaceProbabilityMeasureCli};
use crate::cli::output::write;
use crate::surface_probability_measure::{LoggerSticker, ReadOnlyVectorStorage};
use crate::system::model::DLASystem;
use crate::system::spaces::continuous::{ContinuousSticker, ContinuousStorage, ContinuousWalker};
use crate::system::spaces::hexagonal::HexPosition;
@ -95,5 +97,39 @@ fn main() {
drive_system(&mut sys, cli.max_frames, cli.notify_every);
write(&sys, cli.format, &cli.output);
}
PCM::SurfaceProbabilityMeasure(SurfaceProbabilityMeasureCli { grid_size, stick_probability, particles, initial_data }) => {
let logger_sticker = LoggerSticker::new(stick_probability);
let mut sys = DLASystem::new(
SmallRng::seed_from_u64(cli.seed),
ReadOnlyVectorStorage::new(&initial_data, grid_size),
LocalRandomWalker,
UniformSpawner,
&logger_sticker,
cli.max_particles,
);
let particles = particles as usize;
while sys.running && logger_sticker.stick_positions.borrow().len() < particles {
sys.update();
}
let mut writer = csv::Writer::from_path(cli.output)
.expect("Failed to open output path");
let stick_positions = logger_sticker.stick_positions.borrow();
stick_positions
.iter()
.for_each(|pos|
writer.serialize(pos)
.expect("Failed to write position")
);
writer.flush()
.unwrap();
}
}
}

View File

@ -1,3 +1,5 @@
use std::cell::RefCell;
use std::path::{Path, PathBuf};
use rand::rngs::SmallRng;
use rand::{Rng, SeedableRng};
use crate::system::model::DLASystem;
@ -8,41 +10,61 @@ use crate::system::spawner::UniformSpawner;
use crate::system::sticker::{ProbabilisticSticking, SimpleSticking, Sticker};
use crate::system::walker::LocalRandomWalker;
struct LoggerSticker {
inner: SimpleSticking
pub struct LoggerSticker {
inner: ProbabilisticSticking,
pub stick_positions: RefCell<Vec<Grid2D>>,
}
impl<S: Storage<Grid2D>> Sticker<Grid2D, S> for LoggerSticker {
impl LoggerSticker {
pub fn new(stick_probability: f32) -> LoggerSticker {
LoggerSticker {
inner: ProbabilisticSticking { stick_probability },
stick_positions: RefCell::new(Vec::new()),
}
}
}
impl<S: Storage<Grid2D>> Sticker<Grid2D, S> for &LoggerSticker {
fn should_stick<R: Rng>(&self, rng: &mut R, space: &S, position: &Grid2D) -> bool {
if self.inner.should_stick(rng, space, position) {
println!("{:?}", position);
let should_stick = self.inner.should_stick(rng, space, position);
if should_stick {
self.stick_positions.borrow_mut()
.push(position.clone());
}
false
// Writes are ignored so we deposit to delete the particle but it is not written
should_stick
}
}
struct ReadOnlyVectorStorage {
pub struct ReadOnlyVectorStorage {
inner: VectorStorage,
}
impl ReadOnlyVectorStorage {
pub fn new(path: &Path, grid_size: u32) -> ReadOnlyVectorStorage {
let mut inner = VectorStorage::new(grid_size, 2);
let positions: Vec<Grid2D> = csv::Reader::from_path(path)
.expect("Failed to read initial data")
.deserialize::<Grid2D>()
.map(|row| row.expect("Failed to read row"))
.collect();
for pos in positions {
inner.deposit(&pos);
}
ReadOnlyVectorStorage { inner }
}
}
impl Storage<Grid2D> for ReadOnlyVectorStorage {
fn is_occupied(&self, position: &Grid2D) -> bool {
self.inner.is_occupied(position)
}
fn deposit(&mut self, position: &Grid2D) {
eprintln!("Write ignore for space at {position:?}");
eprintln!("Write ignored for space at {position:?}");
}
}
pub fn surface_probability_measure(seed: u64, max_particles: usize, stick_probability: f32) -> DLASystem<SmallRng, Grid2D, VectorStorage, LocalRandomWalker, UniformSpawner, ProbabilisticSticking> {
DLASystem::new(
SmallRng::seed_from_u64(seed),
VectorStorage::new(1600, 3),
LocalRandomWalker,
UniformSpawner,
ProbabilisticSticking { stick_probability },
max_particles,
)
}