Add 1D random walk dynamics and example
Implement RandomWalk1D dynamics for lattice-based simulations and provide an example that demonstrates diffusive scaling. Move prelude into lib.rs for simpler module organization. Use () for lattice momentum since discrete walks don't have meaningful momenta.
This commit is contained in:
47
simul-lattice/examples/random_walk_1d.rs
Normal file
47
simul-lattice/examples/random_walk_1d.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
//! Example: 1D simple random walk
|
||||
//!
|
||||
//! Runs N_TRIAL independent walks of TIME steps each, then verifies the
|
||||
//! diffusive scaling: for a 1D simple random walk, <x(t)> = 0 and <x^2(t)> = t.
|
||||
|
||||
use nalgebra::SVector;
|
||||
use rand::{SeedableRng, rngs::StdRng};
|
||||
use simul_core::dynamics::Dynamics;
|
||||
use simul_core::state::SystemState;
|
||||
use simul_lattice::prelude::*;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
const N_TRIAL: usize = 10000;
|
||||
const TIME: usize = 1000;
|
||||
|
||||
let mut rng = StdRng::seed_from_u64(42);
|
||||
let dynamics = RandomWalk1D;
|
||||
|
||||
let mut sum_x = 0.0_f64;
|
||||
let mut sum_x2 = 0.0_f64;
|
||||
|
||||
for _ in 0..N_TRIAL {
|
||||
let mut state: SystemState<Lattice<1>> = SystemState::new();
|
||||
state.positions.push(SVector::<i32, 1>::zeros());
|
||||
|
||||
for _ in 0..TIME {
|
||||
dynamics.step(&mut state, &mut rng);
|
||||
}
|
||||
|
||||
let x = state.positions[0][0] as f64;
|
||||
sum_x += x;
|
||||
sum_x2 += x * x;
|
||||
}
|
||||
|
||||
let mean = sum_x / N_TRIAL as f64;
|
||||
let var = sum_x2 / N_TRIAL as f64;
|
||||
|
||||
println!("RandomWalk1D - 1D simple random walk");
|
||||
println!("=====================================");
|
||||
println!(" Trials : {}", N_TRIAL);
|
||||
println!(" Steps / trial : {}", TIME);
|
||||
println!();
|
||||
println!(" <x> = {:>8.3} (expected ~ 0)", mean);
|
||||
println!(" <x^2> = {:>8.3} (expected ~ {})", var, TIME);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1 +1,28 @@
|
||||
//! Dynamics implementations for Lattice space
|
||||
|
||||
use crate::space::Lattice;
|
||||
use rand::Rng;
|
||||
use simul_core::dynamics::{Dynamics, TimeType};
|
||||
use simul_core::state::SystemState;
|
||||
|
||||
/// Single particle 1D Random Walk dynamics
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct RandomWalk1D;
|
||||
|
||||
impl Dynamics<Lattice<1>> for RandomWalk1D {
|
||||
fn step<R: Rng>(&self, state: &mut SystemState<Lattice<1>>, rng: &mut R) -> f64 {
|
||||
for p in state.positions.iter_mut() {
|
||||
p[0] += if rng.random_bool(0.5) { 1 } else { -1 };
|
||||
}
|
||||
1.0 // discrete step
|
||||
}
|
||||
fn time_type(&self) -> TimeType {
|
||||
TimeType::Discrete
|
||||
}
|
||||
fn is_deterministic(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn name(&self) -> &'static str {
|
||||
"RandomWalk1D"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,10 @@
|
||||
//! - Brownian dynamics (overdamped)
|
||||
|
||||
pub mod dynamics;
|
||||
pub mod prelude;
|
||||
pub mod space;
|
||||
|
||||
pub mod prelude {
|
||||
//! Convenient re-exports for common use
|
||||
pub use crate::dynamics::RandomWalk1D;
|
||||
pub use crate::space::Lattice;
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -14,7 +14,7 @@ impl<const D: usize> StateSpace for Lattice<D> {
|
||||
const DIM: usize = D;
|
||||
|
||||
type Point = SVector<i32, D>;
|
||||
type Momentum = SVector<i32, D>;
|
||||
type Momentum = ();
|
||||
|
||||
fn is_continuous() -> bool {
|
||||
false
|
||||
@@ -33,9 +33,7 @@ impl<const D: usize> StateSpace for Lattice<D> {
|
||||
SVector::zeros()
|
||||
}
|
||||
|
||||
fn zero_momentum() -> Self::Momentum {
|
||||
SVector::zeros()
|
||||
}
|
||||
fn zero_momentum() -> Self::Momentum {}
|
||||
}
|
||||
|
||||
/// Type alias for 1D Lattice space
|
||||
|
||||
Reference in New Issue
Block a user