Add 1D random walk dynamics and example
All checks were successful
CI / Format (push) Successful in 1m9s
CI / Clippy (push) Successful in 2m27s
CI / Test (push) Successful in 2m42s

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:
2026-05-05 19:28:06 +09:00
parent 8d2d261564
commit 88eb05ae94
5 changed files with 82 additions and 6 deletions

View 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(())
}

View File

@@ -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"
}
}

View File

@@ -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;
}

View File

@@ -1 +0,0 @@

View File

@@ -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