use crate::atan;
use num::complex::Complex;
use mixed_num::*;
pub fn to_polar<T>( x: Complex<T> ) -> Polar<T>
where T: MixedNum + MixedNumSigned + MixedSqrt + MixedAbs + MixedOps + MixedPowi + MixedReal + MixedPi
{
let c_polar = Polar::<T>{
r: abs(x),
theta: atan::atan2( x.im, x.re )
};
return c_polar;
}
pub fn abs<T>( a: Complex<T> ) -> T
where T: MixedNum + MixedNumSigned + MixedSqrt + MixedOps
{
let r_sqr = super::powi( a.re, 2) + super::powi( a.im, 2);
return r_sqr.mixed_sqrt();
}
pub struct Polar<T> {
pub r: T,
pub theta: T,
}
pub fn to_cartsian<T>( a: Polar<T> ) -> Complex<T>
where T: MixedNum + MixedNumSigned + MixedTrigonometry + MixedOps + MixedPi
{
let theta = crate::wrap_phase(a.theta);
let (imag_s, real_s) = theta.mixed_sincos();
let c_cartesian = Complex::<T>{
re: a.r*real_s,
im: a.r*imag_s
};
return c_cartesian;
}
pub fn add<T>( a: Complex<T>, b: Complex<T> ) -> Complex<T>
where T: MixedNum + MixedOps
{
let c_cartesian = Complex::<T>{
re: a.re + b.re,
im: a.im + b.im
};
return c_cartesian;
}
pub fn sub<T>( a: Complex<T>, b: Complex<T> ) -> Complex<T>
where T: MixedNum + MixedNumSigned + MixedOps
{
let c_cartesian = Complex::<T>{
re: a.re - b.re,
im: a.im - b.im
};
return c_cartesian;
}
pub fn mul_polar<T>( a: Polar<T>, b: Polar<T> ) -> Polar<T>
where T: MixedNum + MixedNumSigned + MixedOps
{
if a.r==T::mixed_from_num(0) || b.r==T::mixed_from_num(0)
{
let c = Polar::<T>{
r: T::mixed_from_num(0),
theta: T::mixed_from_num(0)
};
return c;
}
else
{
let c = Polar::<T>{
r: a.r*b.r,
theta: a.theta+b.theta
};
return c;
}
}
pub fn mul_cartesian<T>( ab: Complex<T>, bc: Complex<T> ) -> Complex<T>
where T: MixedNum + MixedNumSigned + MixedOps
{
let a = ab.re;
let b = ab.im;
let c = bc.re;
let d = bc.im;
let re = (a*c) - (b*d);
let im = (a*d) + (b*c);
return Complex{re:re, im:im}
}
pub fn powi<T>( base: num::complex::Complex<T>, power:usize ) -> num::complex::Complex<T>
where T: fixed::traits::FixedSigned + cordic::CordicNumber + MixedNum + MixedZero + MixedReal + MixedAbs + MixedPowi + MixedNumSigned + MixedOps + MixedPi
{
let temp:T = super::powi( base.re, 2 ) + super::powi( base.im, 2 );
let mag:T = super::powi( trigonometry::sqrt::niirf(temp, 2), power );
let phi:T = super::atan::atan2( base.im, base.re )*<T>::from_num(power);
let (imag_s, real_s) = cordic::sin_cos( phi );
let real = mag*real_s;
let imag = mag*imag_s;
return num::complex::Complex::new( real, imag);
}
pub fn div_cartesian<T>( a: Complex<T>, b: T ) -> Complex<T>
where T: MixedNum + MixedReal + MixedNumSigned + MixedOps
{
let mut c = a;
if b == T::mixed_from_num(0)
{
c.re = T::mixed_max_value();
c.im = T::mixed_max_value();
}
else
{
c.re = a.re / b;
c.im = a.im / b;
}
return c;
}