use num::complex::Complex;
use num::{Float, FromPrimitive};
pub trait CLn<T> {
fn cln(&self) -> T;
}
impl<T: Float + FromPrimitive> CLn<Complex<T>> for Complex<T> {
fn cln(&self) -> Complex<T> {
if self.im == T::zero() && self.re > T::zero() {
Complex::new(self.re.ln(), T::zero())
} else if self.im == T::zero() {
Complex::new((-self.re).ln(), T::from_f64(3.1415926535897932_f64).unwrap())
} else {
self.ln()
}
}
}
#[test]
fn test_cln() {
let x32 = Complex::new(1.0_f32, 0.0_f32);
let x64 = Complex::new(1.0_f64, 0.0_f64);
assert!(((-x32).cln() - Complex::new(0.0_f32, std::f32::consts::PI)).norm() < 4.0_f32*std::f32::EPSILON);
assert!(((-x32).ln() - Complex::new(0.0_f32, -std::f32::consts::PI)).norm() < 4.0_f32*std::f32::EPSILON);
assert!((-x64).cln() == Complex::new(0.0_f64, std::f64::consts::PI));
assert!((-x64).ln() == Complex::new(0.0_f64, -std::f64::consts::PI));
}