use crate::err::try_vec;
use crate::sample::CwtSample;
use crate::{CwtWavelet, ScaletError};
use num_complex::Complex;
use num_traits::{AsPrimitive, Zero};
use std::cmp::Ordering;
#[derive(Debug, Copy, Clone, Hash)]
pub struct GaborWavelet<T> {
mu: T,
alpha: T,
alpha_s2: T,
mx0: T,
}
impl<T: CwtSample> GaborWavelet<T>
where
f64: AsPrimitive<T>,
{
pub fn new(alpha: T, mu: T, x0: T) -> Self {
Self {
mu,
alpha,
alpha_s2: alpha * alpha,
mx0: -x0,
}
}
}
impl<T: CwtSample> Default for GaborWavelet<T>
where
f64: AsPrimitive<T>,
{
fn default() -> Self {
Self::new(1f64.as_(), 13.4.as_(), 0.0.as_())
}
}
impl<T: CwtSample> CwtWavelet<T> for GaborWavelet<T>
where
f64: AsPrimitive<T>,
{
fn make_wavelet(&self, omegas: &[T]) -> Result<Vec<Complex<T>>, ScaletError> {
let mut out = try_vec![Complex::<T>::zero(); omegas.len()];
if self.mx0.partial_cmp(&T::zero()).unwrap_or(Ordering::Equal) == Ordering::Equal {
for (dst, &w) in out.iter_mut().zip(omegas.iter()) {
let dwmu = w - self.mu;
let z0 = (-dwmu * dwmu * self.alpha_s2).exp();
*dst = Complex::new(self.alpha * z0, T::zero());
}
} else {
for (dst, &w) in out.iter_mut().zip(omegas.iter()) {
let dwmu = w - self.mu;
let z0 = (-dwmu * dwmu * self.alpha_s2).exp();
let ubd = (self.mx0 * dwmu).sincos();
let z1 = Complex::new(ubd.1, ubd.0);
*dst = z1 * self.alpha * z0;
}
}
Ok(out)
}
}