use crate::core::integer::{FullInt, IntConvert};
use crate::core::undefined::*;
use crate::{
Circle, CircleConstants, ExponentConstants, FractionConstants, Integer, Scalar, ScalarConstants,
};
use i256::I256;
use num_traits::{AsPrimitive, WrappingAdd, WrappingMul, WrappingNeg, WrappingSub};
use core::ops::*;
#[allow(private_bounds)]
impl<
F: Integer
+ FractionConstants
+ FullInt
+ Shl<isize, Output = F>
+ Shr<isize, Output = F>
+ Shl<F, Output = F>
+ Shr<F, Output = F>
+ Shl<E, Output = F>
+ Shr<E, Output = F>
+ WrappingNeg
+ WrappingAdd
+ WrappingMul
+ WrappingSub,
E: Integer
+ ExponentConstants
+ FullInt
+ Shl<isize, Output = E>
+ Shr<isize, Output = E>
+ Shl<E, Output = E>
+ Shr<E, Output = E>
+ Shl<F, Output = E>
+ Shr<F, Output = E>
+ WrappingNeg
+ WrappingAdd
+ WrappingMul
+ WrappingSub,
> Circle<F, E>
where
Circle<F, E>: CircleConstants,
Scalar<F, E>: ScalarConstants,
u8: AsPrimitive<F>,
u16: AsPrimitive<F>,
u32: AsPrimitive<F>,
u64: AsPrimitive<F>,
u128: AsPrimitive<F>,
usize: AsPrimitive<F>,
i8: AsPrimitive<F>,
i16: AsPrimitive<F>,
i32: AsPrimitive<F>,
i64: AsPrimitive<F>,
i128: AsPrimitive<F>,
isize: AsPrimitive<F>,
I256: From<F>,
u8: AsPrimitive<E>,
u16: AsPrimitive<E>,
u32: AsPrimitive<E>,
u64: AsPrimitive<E>,
u128: AsPrimitive<E>,
usize: AsPrimitive<E>,
i8: AsPrimitive<E>,
i16: AsPrimitive<E>,
i32: AsPrimitive<E>,
i64: AsPrimitive<E>,
i128: AsPrimitive<E>,
isize: AsPrimitive<E>,
I256: From<E>,
{
pub fn sin(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.exploded() {
let prefix: F = SINE.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return *self; }
Circle::from((
self.r().sin() * self.i().cosh(),
self.r().cos() * self.i().sinh(),
))
}
pub fn cos(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.is_undefined() {
return *self;
}
if self.exploded() {
let prefix: F = COSINE.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
if self.is_zero() {
return Self::ONE;
}
return Self::EFFECTIVELY_POS_ONE;
}
Circle::from((
self.r().cos() * self.i().cosh(),
-self.r().sin() * self.i().sinh(),
))
}
pub fn tan(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.exploded() {
let prefix: F = TANGENT.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return *self; }
let sin_z = self.sin();
let cos_z = self.cos();
if cos_z.magnitude().is_negligible() {
let prefix: F = TANGENT.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
sin_z / cos_z
}
pub fn sinh(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.exploded() {
let prefix: F = SINE.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return *self;
}
Circle::from((
self.r().sinh() * self.i().cos(),
self.r().cosh() * self.i().sin(),
))
}
pub fn cosh(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.is_undefined() {
return *self;
}
if self.exploded() {
let prefix: F = COSINE.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return Self::ONE;
}
Circle::from((
self.r().cosh() * self.i().cos(),
self.r().sinh() * self.i().sin(),
))
}
pub fn tanh(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.exploded() {
let prefix: F = TANGENT.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return *self;
}
let sinh_z = self.sinh();
let cosh_z = self.cosh();
if cosh_z.is_negligible() {
let prefix: F = TANGENT.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
sinh_z / cosh_z
}
pub fn asin(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.exploded() {
let prefix: F = SINE.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return *self;
}
let iz = Self::POS_I * *self;
let one_minus_z_squared = Self::ONE - self.square();
let sqrt_term = one_minus_z_squared.sqrt();
let sum = iz + sqrt_term;
Self::NEG_I * sum.ln()
}
pub fn acos(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.is_undefined() {
return *self;
}
if self.exploded() {
let prefix: F = ARCCOSINE.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return Self::PI_OVER_TWO;
}
let one_minus_z_squared = Self::ONE - self.square();
let i_sqrt = Self::POS_I * one_minus_z_squared.sqrt();
let sum = *self + i_sqrt;
Self::NEG_I * sum.ln()
}
pub fn atan(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.exploded() {
let prefix: F = TANGENT.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return *self;
}
let i_plus_z = Self::POS_I + *self;
let i_minus_z = Self::POS_I - *self;
let quotient = i_plus_z / i_minus_z;
let ln_result = quotient.ln();
(Self::POS_I * Scalar::<F, E>::HALF) * ln_result
}
pub fn asinh(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.exploded() {
let prefix: F = ARCSINE.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return *self;
}
let z_squared_plus_one = self.square() + 1i8;
let sqrt_term = z_squared_plus_one.sqrt();
let sum = *self + sqrt_term;
sum.ln()
}
pub fn acosh(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.is_undefined() {
return *self;
}
if self.exploded() {
let prefix: F = ARCCOSINE.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return Self::POS_I * Self::PI_OVER_TWO;
}
let z_squared_minus_one = self.square() - Self::ONE;
let sqrt_term = z_squared_minus_one.sqrt();
let sum = *self + sqrt_term;
sum.ln()
}
pub fn atanh(&self) -> Circle<F, E> {
if !self.is_normal() {
if self.exploded() {
let prefix: F = TANGENT.prefix.sa();
return Self {
real: prefix,
imaginary: prefix,
exponent: E::AMBIGUOUS_EXPONENT,
};
}
return *self;
}
let one_plus_z = Self::ONE + *self;
let one_minus_z = Self::ONE - *self;
let quotient = one_plus_z / one_minus_z;
let ln_result = quotient.ln();
Scalar::<F, E>::HALF * ln_result
}
}