use crate::messages::errors;
use rand::Rng;
pub struct HawkesProcess {
pub mu: f64,
pub alpha: f64,
pub beta: f64,
}
impl HawkesProcess {
pub fn hawkes_valid_inputs(
mu: &f64,
alpha: &f64,
beta: &f64,
) -> Result<(), errors::GeneratorError> {
match mu >= &0.0 && alpha >= &0.0 && beta > &0.0 {
true => Ok(()),
false => Err(errors::GeneratorError::GeneratorInputTypeFailure),
}
}
pub fn new(mu: f64, alpha: f64, beta: f64) -> Result<Self, errors::GeneratorError> {
match Self::hawkes_valid_inputs(&mu, &alpha, &beta) {
Ok(()) => Ok(Self { mu, alpha, beta }),
Err(e) => Err(errors::GeneratorError::GeneratorInputTypeFailure),
_ => Err(errors::GeneratorError::GeneratorUndefinedError),
}
}
fn lambda(&self, t: f64, event_times: &[f64]) -> f64 {
let mut intensity = self.mu;
for &event_time in event_times {
if event_time < t {
intensity += self.alpha * (-self.beta * (t - event_time)).exp();
}
}
intensity
}
pub fn generate_values(&self, mut current_ts: f64, n: usize) -> Vec<f64> {
let mut rng = rand::thread_rng();
let mut event_times = Vec::new();
let mut current_time = current_ts.clone();
for _ in 0..n {
let intensity = self.lambda(current_time, &event_times);
let wait_time = rng.gen_range(0.0..1.0 / intensity);
current_time += wait_time;
event_times.push(current_time);
}
event_times
}
}