use mixed_num::traits::*;
fn atan_poly_1<T>( y: T, x: T ) -> T
where T: MixedNum + MixedNumSigned + MixedPowi + MixedNumConversion<i32> + MixedNumConversion<f32> + MixedOps
{
let phi = (x*y) / ( x.mixed_powi(2) + T::mixed_from_num( 0.28125 )*y.mixed_powi(2) );
return phi;
}
fn atan_poly_2<T>( y: T, x: T ) -> T
where T: MixedNum + MixedNumSigned + MixedPowi + MixedNumConversion<f32> + MixedOps
{
let phi = (x*y) / ( y.mixed_powi( 2) + T::mixed_from_num( 0.28125 )*x.mixed_powi(2) );
return phi;
}
pub fn atan2<T>( y: T, x: T ) -> T
where T: MixedNum + MixedNumSigned + MixedOps + MixedAbs + MixedPi + MixedReal + MixedPowi
{
let y_abs = y.mixed_abs();
let x_abs = x.mixed_abs();
let pi = T::mixed_pi();
let pi_half = T::mixed_pi()/T::mixed_from_num(2);
if y == T::mixed_from_num(0)
{
if x.mixed_is_negative()
{
return T::mixed_pi();
}
else
{
return T::mixed_from_num( 0 );
}
}
else if y.mixed_is_positive()
{
if x == T::mixed_from_num( 0 )
{
return T::mixed_pi()/T::mixed_from_num( 2 );
}
else if x.mixed_is_positive()
{
if y_abs - x_abs < T::mixed_from_num( 0.0 )
{
return atan_poly_1( y, x );
}
else
{
return pi_half -atan_poly_2( y, x );
}
}
else
{
if T::mixed_from_num( 0.0 ) <= y_abs - x_abs
{
return pi_half - atan_poly_2( y, x );
}
else
{
return pi + atan_poly_1( y, x );
}
}
}
else
{
if x == T::mixed_from_num( 0 )
{
return -T::mixed_pi()/T::mixed_from_num( 2 );
}
if x.mixed_is_positive()
{
if y_abs - x_abs < T::mixed_from_num( 0.0 )
{
return atan_poly_1( y, x );
}
else
{
return - pi_half -atan_poly_2( y, x );
}
}
else
{
if T::mixed_from_num( 0.0 ) <= y_abs - x_abs
{
return -pi_half - atan_poly_2( y, x );
}
else
{
return -pi + atan_poly_1( y, x );
}
}
}
}
pub fn atan<T>( x: T ) -> T
where T: MixedNum + MixedNumSigned + MixedOps + MixedAbs + MixedPi + MixedReal + MixedPowi
{
return atan2(x,T::mixed_from_num(1));
}