use core::fmt::{Debug, Display};
use core::iter::Sum;
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use num_traits::{FromPrimitive, NumAssign, One, Zero};
pub trait Scalar:
Copy
+ Clone
+ Debug
+ Display
+ Default
+ Send
+ Sync
+ PartialEq
+ Zero
+ One
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Output = Self>
+ Div<Output = Self>
+ AddAssign
+ SubAssign
+ MulAssign
+ DivAssign
+ Neg<Output = Self>
+ Sum
+ NumAssign
+ FromPrimitive
+ 'static
{
type Real: Real;
fn abs(self) -> Self::Real;
fn conj(self) -> Self;
fn is_real() -> bool;
fn real(self) -> Self::Real;
fn imag(self) -> Self::Real;
fn from_real_imag(re: Self::Real, im: Self::Real) -> Self;
fn from_real(re: Self::Real) -> Self {
Self::from_real_imag(re, Self::Real::zero())
}
fn abs_sq(self) -> Self::Real {
let re = self.real();
let im = self.imag();
re * re + im * im
}
fn epsilon() -> Self::Real;
fn min_positive() -> Self::Real;
fn max_value() -> Self::Real;
const SIZE: usize = core::mem::size_of::<Self>();
const ALIGN: usize = core::mem::align_of::<Self>();
}
pub trait Real: Scalar<Real = Self> + num_traits::Float + PartialOrd {
fn sqrt(self) -> Self;
fn ln(self) -> Self;
fn exp(self) -> Self;
fn sin(self) -> Self;
fn cos(self) -> Self;
fn atan2(self, other: Self) -> Self;
fn powf(self, n: Self) -> Self;
fn signum(self) -> Self;
fn mul_add(self, a: Self, b: Self) -> Self;
fn floor(self) -> Self;
fn ceil(self) -> Self;
fn round(self) -> Self;
fn trunc(self) -> Self;
fn safe_recip(self) -> Option<Self> {
if Scalar::abs(self) < Self::min_positive() {
None
} else {
Some(Self::one() / self)
}
}
fn hypot(self, other: Self) -> Self;
}
pub trait ComplexScalar: Scalar {
fn new(re: Self::Real, im: Self::Real) -> Self;
fn arg(self) -> Self::Real;
fn to_polar(self) -> (Self::Real, Self::Real) {
(self.abs(), self.arg())
}
fn from_polar(r: Self::Real, theta: Self::Real) -> Self;
fn cexp(self) -> Self;
fn cln(self) -> Self;
fn csqrt(self) -> Self;
}
pub trait Field: Scalar {
#[inline]
fn scale_add(self, alpha: Self, other: Self, beta: Self) -> Self {
self * alpha + other * beta
}
fn mul_conj(self, other: Self) -> Self;
fn conj_mul(self, other: Self) -> Self;
fn recip(self) -> Self;
fn powi(self, n: i32) -> Self;
}