use ffi;
use enums;
pub struct DiscreteHankel {
t: *mut ffi::gsl_dht,
}
impl DiscreteHankel {
pub fn new(size: usize) -> Option<DiscreteHankel> {
let tmp = unsafe { ffi::gsl_dht_alloc(size) };
if tmp.is_null() {
None
} else {
Some(DiscreteHankel {
t: tmp,
})
}
}
pub fn new_with_init(size: usize, nu: f64, xmax: f64) -> Option<DiscreteHankel> {
let tmp = unsafe { ffi::gsl_dht_new(size, nu, xmax) };
if tmp.is_null() {
None
} else {
Some(DiscreteHankel {
t: tmp,
})
}
}
pub fn init(&mut self, nu: f64, xmax: f64) -> enums::Value {
enums::Value::from(unsafe { ffi::gsl_dht_init(self.t, nu, xmax) })
}
pub fn apply(&self, f_in: &[f64]) -> Result<Vec<f64>, enums::Value> {
unsafe {
assert!((*self.t).size == f_in.len(),
"f_in and f_out must have the same length as this struct");
let mut f_out: Vec<f64> = ::std::iter::repeat(0.).take(f_in.len()).collect();
match enums::Value::from(ffi::gsl_dht_apply(self.t, f_in.as_ptr(), f_out.as_mut_ptr())) {
enums::Value::Success => Ok(f_out),
err => Err(err),
}
}
}
pub fn x_sample(&self, n: i32) -> f64 {
unsafe { ffi::gsl_dht_x_sample(self.t, n) }
}
pub fn k_sample(&self, n: i32) -> f64 {
unsafe { ffi::gsl_dht_k_sample(self.t, n) }
}
}
impl Drop for DiscreteHankel {
fn drop(&mut self) {
unsafe { ffi::gsl_dht_free(self.t) };
self.t = ::std::ptr::null_mut();
}
}
impl ffi::FFI<ffi::gsl_dht> for DiscreteHankel {
fn wrap(t: *mut ffi::gsl_dht) -> DiscreteHankel {
DiscreteHankel {
t: t
}
}
fn soft_wrap(t: *mut ffi::gsl_dht) -> DiscreteHankel {
Self::wrap(t)
}
fn unwrap_shared(t: &DiscreteHankel) -> *const ffi::gsl_dht {
t.t as *const _
}
fn unwrap_unique(t: &mut DiscreteHankel) -> *mut ffi::gsl_dht {
t.t
}
}
#[test]
fn discrete_hankel() {
let mut d = DiscreteHankel::new(3).unwrap();
assert_eq!(d.init(3., 2.), ::Value::Success);
assert_eq!(&format!("{:.4} {:.4}", d.x_sample(1), d.k_sample(1)), "1.2033 4.8805");
let v = d.apply(&[100., 2., 3.]);
assert_eq!(true, v.is_ok());
let v = v.unwrap();
assert_eq!(&format!("{:.4} {:.4} {:.4}", v[0], v[1], v[2]), "8.5259 13.9819 11.7320");
}