pub trait ExcitationKernel: Clone {
type State: Clone;
fn evaluate(&self, delta: f64) -> f64;
fn integrate(&self, s: f64) -> f64;
fn init_state(&self, t: f64, history: &[f64]) -> Self::State;
fn decay_state(&self, state: &Self::State, dt: f64) -> Self::State;
fn excite_state(&self, state: &Self::State) -> Self::State;
fn intensity_contribution(&self, state: &Self::State) -> f64;
fn integrated_intensity_contribution(&self, state: &Self::State, s: f64) -> f64;
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct ExponentialKernel {
pub alpha: f64,
pub beta: f64,
}
impl ExcitationKernel for ExponentialKernel {
type State = f64;
#[inline]
fn evaluate(&self, delta: f64) -> f64 {
self.alpha * (-self.beta * delta).exp()
}
#[inline]
fn integrate(&self, s: f64) -> f64 {
(self.alpha / self.beta) * (1.0 - (-self.beta * s).exp())
}
fn init_state(&self, t: f64, history: &[f64]) -> f64 {
let mut a = 0.0_f64;
for &ti in history {
if ti < t {
a += (-self.beta * (t - ti)).exp();
}
}
a
}
#[inline]
fn decay_state(&self, state: &f64, dt: f64) -> f64 {
state * (-self.beta * dt).exp()
}
#[inline]
fn excite_state(&self, state: &f64) -> f64 {
state + 1.0
}
#[inline]
fn intensity_contribution(&self, state: &f64) -> f64 {
self.alpha * state
}
#[inline]
fn integrated_intensity_contribution(&self, state: &f64, s: f64) -> f64 {
(self.alpha / self.beta) * state * (1.0 - (-self.beta * s).exp())
}
}