pointprocesses/temporal/
poisson.rs1use super::traits::*;
3use rand::prelude::*;
4use rand_distr::{Uniform, Poisson, Distribution};
5
6use ndarray::array;
7use ndarray::prelude::*;
8use ndarray_parallel::prelude::*;
9
10use rayon::prelude::*;
11
12
13#[derive(Debug)]
21pub struct PoissonProcess {
22 lambda: f64
24}
25
26impl PoissonProcess {
27 pub fn new(lambda: f64) -> Self {
28 PoissonProcess {
29 lambda
30 }
31 }
32}
33
34impl DeterministicIntensity for PoissonProcess {
35 fn intensity(&self, _t: f64) -> f64 {
36 self.lambda
37 }
38}
39
40#[derive(Debug)]
45pub struct VariablePoissonProcess<F>
46where F: Fn(f64) -> f64 + Send + Sync
47{
48 max_lambda: f64,
50 func: F
52}
53
54impl<F> VariablePoissonProcess<F>
55where F: Fn(f64) -> f64 + Send + Sync
56{
57 pub fn new(func: F, max_lambda: f64) -> Self {
58 VariablePoissonProcess {
59 max_lambda,
60 func
61 }
62 }
63
64 pub fn get_max_lambda(&self) -> f64 {
66 self.max_lambda
67 }
68}
69
70impl<F> DeterministicIntensity for VariablePoissonProcess<F>
71where F: Fn(f64) -> f64 + Send + Sync
72{
73 fn intensity(&self, t: f64) -> f64 {
74 (self.func)(t)
75 }
76}
77
78
79impl TemporalProcess for PoissonProcess {
80 fn sample(&self, tmax: f64) -> TimeProcessResult {
81 let lambda = self.lambda;
82 let mut rng = thread_rng();
83 let fish = Poisson::new(tmax * lambda).unwrap();
84 let num_events: u64 = fish.sample(&mut rng);
85 let num_events = num_events as usize;
86
87 let mut events_vec: Vec<_> = (0..num_events).into_par_iter()
88 .map(|_| {
89 let mut rng = thread_rng();
91 let u = Uniform::new(0.0, tmax);
92 u.sample(&mut rng)
93 }).collect();
94 events_vec.sort_by(|a, b| a.partial_cmp(b).unwrap());
95 let timestamps = Array1::<f64>::from_vec(events_vec);
96 let mut intensities = Array1::<f64>::zeros(num_events as usize);
97 for i in 0..num_events as usize {
98 intensities[i] = lambda;
99 }
100 TimeProcessResult {
101 timestamps, intensities
102 }
103 }
104}
105
106impl<F> TemporalProcess for VariablePoissonProcess<F>
107where F: Fn(f64) -> f64 + Send + Sync
108{
109 fn sample(&self, tmax: f64) -> TimeProcessResult {
110 let mut rng = thread_rng();
114 let max_lambda = self.max_lambda;
115 let lambda = &self.func;
116 let fish = Poisson::new(tmax*max_lambda).unwrap();
117 let num_events: u64 = fish.sample(&mut rng);
118 let num_events = num_events as usize;
119 let lambda = std::sync::Arc::from(lambda);
120
121 let mut events: Vec<Array1<f64>> = (0..num_events)
125 .into_par_iter().filter_map(|_| {
126 let mut rng = thread_rng();
127 let timestamp = rng.gen::<f64>()*tmax;
128 let lambda_val = rng.gen::<f64>()*max_lambda;
129
130 if lambda_val < lambda(timestamp) {
131 Some(array![timestamp, lambda(timestamp)])
132 } else {
133 None
134 }
135 }).collect();
136 events.sort_by(|a, b| a[0].partial_cmp(&b[0]).unwrap());
137
138 let num_events = events.len();
139
140 let mut timestamps = Array1::<f64>::zeros(num_events);
141 let mut intensities = Array1::<f64>::zeros(num_events);
142 if num_events > 0 {
143 for i in 0..num_events {
144 timestamps[i] = events[i][0];
145 intensities[i] = events[i][1];
146
147 }
148 }
149 TimeProcessResult { timestamps, intensities }
150 }
151}