use num_complex::Complex;
use crate::machine::BesselFloat;
#[inline]
pub(crate) fn zshch<T: BesselFloat>(z: Complex<T>) -> (Complex<T>, Complex<T>) {
let sh = z.re.sinh();
let ch = z.re.cosh();
let sn = z.im.sin();
let cn = z.im.cos();
let csh = Complex::new(sh * cn, ch * sn);
let cch = Complex::new(ch * cn, sh * sn);
(csh, cch)
}
#[cfg(test)]
mod tests {
use super::*;
use num_complex::Complex64;
#[test]
fn shch_real() {
let z = Complex64::new(1.0, 0.0);
let (csh, cch) = zshch(z);
assert!((csh.re - 1.0_f64.sinh()).abs() < 1e-15);
assert!(csh.im.abs() < 1e-15);
assert!((cch.re - 1.0_f64.cosh()).abs() < 1e-15);
assert!(cch.im.abs() < 1e-15);
}
#[test]
fn shch_imaginary() {
let y = 1.5;
let z = Complex64::new(0.0, y);
let (csh, cch) = zshch(z);
assert!(csh.re.abs() < 1e-15);
assert!((csh.im - y.sin()).abs() < 1e-15);
assert!((cch.re - y.cos()).abs() < 1e-15);
assert!(cch.im.abs() < 1e-15);
}
#[test]
fn shch_identity() {
let z = Complex64::new(1.5, 2.3);
let (csh, cch) = zshch(z);
let lhs = cch * cch - csh * csh;
assert!((lhs.re - 1.0).abs() < 1e-13);
assert!(lhs.im.abs() < 1e-13);
}
#[test]
fn shch_zero() {
let z = Complex64::new(0.0, 0.0);
let (csh, cch) = zshch(z);
assert!(csh.re.abs() < 1e-15);
assert!(csh.im.abs() < 1e-15);
assert!((cch.re - 1.0).abs() < 1e-15);
assert!(cch.im.abs() < 1e-15);
}
}