use ::binding::{CDouble, CFloat}; use ::real::Real; use ::trig::radian::Radian; /// The available trigonometric functions. pub trait Trig: Real { /// Computes the cosine of this angle. /// /// ``` /// use sigils::Radian; /// use std::f64; /// /// let x: Radian = Radian::from(2.0*f64::consts::PI); /// /// let abs_difference = (x.cos() - 1.0).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` fn cos(arg: T) -> Self where T: Into>; /// Computes the sine of this angle. /// /// ``` /// use sigils::Radian; /// use std::f64; /// /// let x: Radian = Radian::from(f64::consts::PI/2.0); /// /// let abs_difference = (x.sin() - 1.0).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` fn sin(arg: T) -> Self where T: Into>; /// Computes the tangent of this angle. /// /// ``` /// use sigils::Radian; /// use std::f64; /// /// let x: Radian = Radian::from(f64::consts::PI/4.0); /// /// let abs_difference = (x.tan() - 1.0).abs(); /// /// assert!(abs_difference < 1e-14); /// ``` fn tan(arg: T) -> Self where T: Into>; /// Computes the arccosine of a number. Return value is in Degrees in /// the range [0, pi] or NaN if the number is outside the range /// [-1, 1]. /// ///``` /// use sigils::{Constants, Radian, Real}; /// /// let f: Radian; /// /// f = Radian::from(f64::PI / 4.0f64); /// assert!(((f64::PI / 4.0f64) - *Radian::acos(f.cos())) < 1e-10); ///``` fn acos(arg: Self) -> T where T: From>; /// Computes the arcsine of a number. Return value is in Degrees in /// the range [-pi/2, pi/2] or NaN if the number is /// outside the range [-1, 1]. /// ///``` /// use sigils::{Constants, Radian, Real}; /// /// let f: Radian; /// /// f = Radian::from(f64::PI / 4.0f64); /// assert!(((f64::PI / 4.0f64) - *Radian::asin(f.sin())) < 1e-10); ///``` fn asin(arg: Self) -> T where T: From>; /// Computes the arctangent of a number. Return value is in degrees in the /// range [-pi/2, pi/2]; /// ///``` /// use sigils::{Constants, Radian, Real}; /// /// let f: Radian; /// /// f = Radian::from(f64::PI / 4.0f64); /// assert!(((f64::PI / 4.0f64) - *Radian::atan(f.tan())) < 1e-10); ///``` fn atan(arg: Self) -> T where T: From>; /// Computes the four quadrant arctangent of y and x. fn atan2(y: Self, x: Self) -> T where T: From>; /// Hyperbolic cosine function. /// /// ``` /// use sigils::Radian; /// use sigils::Constants; /// /// let e32: f32 = Constants::E; /// let x32: Radian = Radian::new(1.0f32); /// let f_val32 = x32.cosh(); /// let g_val32 = (e32*e32 + 1.0f32)/(2.0f32*e32); /// let abs_difference32 = (f_val32 - g_val32).abs(); /// /// let e64: f64 = Constants::E; /// let x64: Radian = Radian::new(1.0f64); /// let f_val64 = x64.cosh(); /// let g_val64 = (e64*e64 + 1.0f64)/(2.0f64*e64); /// let abs_difference64 = (f_val64 - g_val64).abs(); /// /// // Solving cosh() at 1 gives this result /// //assert!(abs_difference32 < 1.0e-10); /// assert!(abs_difference64 < 1.0e-10); /// ``` fn cosh(arg: Self) -> Self; /// Hyperbolic sine function. /// /// ``` /// use sigils::Radian; /// use sigils::Constants; /// /// let e32: f32 = Constants::E; /// let x32: Radian = Radian::from(1.0f32); /// /// let f_val32 = x32.sinh(); /// let g_val32 = (e32*e32 - 1.0f32)/(2.0f32*e32); /// let abs_difference32 = (f_val32 - g_val32).abs(); /// /// let e64: f64 = Constants::E; /// let x64: Radian = Radian::from(1.0f64); /// /// let f_val64 = x64.sinh(); /// let g_val64 = (e64*e64 - 1.0f64)/(2.0f64*e64); /// let abs_difference64 = (f_val64 - g_val64).abs(); /// /// // Solving sinh() at 1 gives `(e^2-1)/(2e)` /// //assert!(abs_difference32 < 1e-10); /// assert!(abs_difference64 < 1e-10); /// ``` fn sinh(arg: Self) -> Self; /// Hyperbolic tangent function. /// /// ``` /// use sigils::Radian; /// use sigils::Constants; /// /// let e32: f32 = Constants::E; /// let x32: Radian = Radian::from(1.0f32); /// /// let f_val32 = x32.tanh(); /// let g_val32 = (1.0f32 - e32.powi(-2i32))/(1.0f32 + e32.powi(-2i32)); /// let abs_difference32 = (f_val32 - g_val32).abs(); /// /// let e64: f64 = Constants::E; /// let x64: Radian = Radian::from(1.0f64); /// /// let f_val64 = x64.tanh(); /// let g_val64 = (1.0f64 - e64.powi(-2i32))/(1.0f64 + e64.powi(-2i32)); /// let abs_difference64 = (f_val64 - g_val64).abs(); /// /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))` /// //assert!(abs_difference32 < 1.0e-10); /// assert!(abs_difference64 < 1.0e-10); /// ``` fn tanh(arg: Self) -> Self; /// Inverse hyperbolic cosine function. fn acosh(arg: Self) -> Self; /// Inverse hyperbolic sine function. fn asinh(arg: Self) -> Self; /// Inverse hyperbolic tangent function. fn atanh(arg: Self) -> Self; } impl Trig for f32 { fn cos(arg: T) -> Self where T: Into> { unsafe { ::pact::cosf(*arg.into() as CFloat) as Self } } fn sin(arg: T) -> Self where T: Into> { unsafe { ::pact::sinf(*arg.into() as CFloat) as Self } } fn tan(arg: T) -> Self where T: Into> { unsafe { ::pact::tanf(*arg.into() as CFloat) as Self } } fn acos(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::acosf(arg as CFloat) as Self).into() } } fn asin(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::asinf(arg as CFloat) as Self).into() } } fn atan(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::atanf(arg as CFloat) as Self).into() } } fn atan2(y: Self, x: Self) -> T where T: From> { unsafe { Radian::new(::pact::atan2f(y as CFloat, x as CFloat) as Self).into() } } fn cosh(arg: Self) -> Self { unsafe { ::pact::coshf(arg as CFloat) as Self } } fn sinh(arg: Self) -> Self { unsafe { ::pact::sinhf(arg as CFloat) as Self } } fn tanh(arg: Self) -> Self { unsafe { ::pact::tanhf(arg as CFloat) as Self } } fn acosh(arg: Self) -> Self { unsafe { ::pact::acoshf(arg as CFloat) as Self } } fn asinh(arg: Self) -> Self { unsafe { ::pact::asinhf(arg as CFloat) as Self } } fn atanh(arg: Self) -> Self { unsafe { ::pact::atanhf(arg as CFloat) as Self } } } impl Trig for f64 { fn cos(arg: T) -> Self where T: Into> { unsafe { ::pact::cos(*arg.into() as CDouble) as Self } } fn sin(arg: T) -> Self where T: Into> { unsafe { ::pact::sin(*arg.into() as CDouble) as Self } } fn tan(arg: T) -> Self where T: Into> { unsafe { ::pact::tan(*arg.into() as CDouble) as Self } } fn acos(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::acos(arg as CDouble) as Self).into() } } fn asin(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::asin(arg as CDouble) as Self).into() } } fn atan(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::atan(arg as CDouble) as Self).into() } } fn atan2(y: Self, x: Self) -> T where T: From> { unsafe { Radian::new(::pact::atan2(y as CDouble, x as CDouble) as Self).into() } } fn cosh(arg: Self) -> Self { unsafe { ::pact::cosh(arg as CDouble) as Self } } fn sinh(arg: Self) -> Self { unsafe { ::pact::sinh(arg as CDouble) as Self } } fn tanh(arg: Self) -> Self { unsafe { ::pact::tanh(arg as CDouble) as Self } } fn acosh(arg: Self) -> Self { unsafe { ::pact::acosh(arg as CDouble) as Self } } fn asinh(arg: Self) -> Self { unsafe { ::pact::asinh(arg as CDouble) as Self } } fn atanh(arg: Self) -> Self { unsafe { ::pact::atanh(arg as CDouble) as Self } } }