use std::{f32, f64, i8, i16, i32, i64, u8, u16, u32, u64, isize, usize};
use std::num::Float;
use std::slice::{Iter, IterMut};
use std::ops::{Add, Sub, Mul, Div, Rem, Index, IndexMut};
use traits::operations::{RMul, LMul, Axpy, Transpose, Inv, Absolute};
use traits::geometry::{Dot, Norm, Orig};
pub trait BaseNum: Copy + Zero + One +
Add<Self, Output = Self> + Sub<Self, Output = Self> +
Mul<Self, Output = Self> + Div<Self, Output = Self> +
Rem<Self, Output = Self> + PartialEq +
Absolute<Self> + Axpy<Self> {
}
pub trait BaseFloat: Float + Cast<f64> + BaseNum {
fn pi() -> Self;
fn two_pi() -> Self;
fn frac_pi_2() -> Self;
fn frac_pi_3() -> Self;
fn frac_pi_4() -> Self;
fn frac_pi_6() -> Self;
fn frac_pi_8() -> Self;
fn frac_1_pi() -> Self;
fn frac_2_pi() -> Self;
fn frac_2_sqrt_pi() -> Self;
fn e() -> Self;
fn log2_e() -> Self;
fn log10_e() -> Self;
fn ln_2() -> Self;
fn ln_10() -> Self;
}
pub trait Cast<T> {
fn from(t: T) -> Self;
}
pub trait Mat<N, R, C>: Row<R> + Col<C> + RMul<R> + LMul<C> + Index<(usize, usize), Output = N> { }
impl<N, M, R, C> Mat<N, R, C> for M
where M: Row<R> + Col<C> + RMul<R> + LMul<C> + Index<(usize, usize), Output = N> {
}
pub trait SquareMat<N, V>: Mat<N, V, V> +
Mul<Self, Output = Self> + Eye + Transpose + Diag<V> + Inv + Dim + One {
}
impl<N, V, M> SquareMat<N, V> for M
where M: Mat<N, V, V> + Mul<M, Output = M> + Eye + Transpose + Diag<V> + Inv + Dim + One {
}
pub trait Eye {
fn new_identity(dim: usize) -> Self;
}
pub trait Zero {
fn zero() -> Self;
fn is_zero(&self) -> bool;
}
pub trait One {
fn one() -> Self;
}
pub trait Bounded {
#[inline]
fn min_value() -> Self;
#[inline]
fn max_value() -> Self;
}
pub trait Basis {
fn canonical_basis<F: FnMut(Self) -> bool>(F);
fn orthonormal_subspace_basis<F: FnMut(Self) -> bool>(&Self, F);
fn canonical_basis_element(i: usize) -> Option<Self>;
}
pub trait Row<R> {
fn nrows(&self) -> usize;
fn row(&self, i: usize) -> R;
fn set_row(&mut self, i: usize, R);
}
pub trait Col<C> {
fn ncols(&self) -> usize;
fn col(&self, i: usize) -> C;
fn set_col(&mut self, i: usize, C);
}
pub trait ColSlice<C> {
fn col_slice(&self, col_id: usize, row_start: usize, row_end: usize) -> C;
}
pub trait RowSlice<R> {
fn row_slice(&self, row_id: usize, col_start: usize, col_end: usize) -> R;
}
pub trait Dim {
fn dim(unused_mut: Option<Self>) -> usize;
}
pub trait Diag<V> {
fn from_diag(diag: &V) -> Self;
fn set_diag(&mut self, diag: &V);
fn diag(&self) -> V;
}
pub trait Shape<I>: Index<I> {
fn shape(&self) -> I;
}
pub trait Indexable<I, N>: Shape<I> + IndexMut<I, Output = N> {
#[deprecated = "use the Index `[]` overloaded operator instead"]
fn at(&self, i: I) -> N;
#[deprecated = "use the IndexMut `[]` overloaded operator instead"]
fn set(&mut self, i: I, N);
fn swap(&mut self, i: I, j: I);
unsafe fn unsafe_at(&self, i: I) -> N;
unsafe fn unsafe_set(&mut self, i: I, N);
}
pub trait Iterable<N> {
fn iter<'l>(&'l self) -> Iter<'l, N>;
}
pub trait IterableMut<N> {
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N>;
}
#[deprecated = "This will be removed in the future. Use point + vector operations instead."]
pub trait VecAsPnt<P> {
fn to_pnt(self) -> P;
fn as_pnt<'a>(&'a self) -> &'a P;
}
pub trait NumVec<N>: Dim +
Sub<Self, Output = Self> + Add<Self, Output = Self> +
Mul<N, Output = Self> + Div<N, Output = Self> +
Index<usize, Output = N> +
Zero + PartialEq + Dot<N> + Axpy<N> {
}
pub trait FloatVec<N: BaseFloat>: NumVec<N> + Norm<N> + Basis {
}
pub trait PntAsVec<V> {
fn to_vec(self) -> V;
fn as_vec<'a>(&'a self) -> &'a V;
fn set_coords(&mut self, coords: V);
}
pub trait NumPnt<N, V>:
Copy +
PntAsVec<V> +
Dim +
Orig +
PartialEq +
Axpy<N> +
Sub<Self, Output = V> +
Mul<N, Output = Self> +
Div<N, Output = Self> +
Add<V, Output = Self> +
Index<usize, Output = N> { }
pub trait FloatPnt<N: BaseFloat, V: Norm<N>>: NumPnt<N, V> + Sized {
#[inline]
fn sqdist(&self, other: &Self) -> N {
(*self - *other).sqnorm()
}
#[inline]
fn dist(&self, other: &Self) -> N {
(*self - *other).norm()
}
}
macro_rules! impl_zero_one(
($n: ty, $zero: expr, $one: expr) => {
impl Zero for $n {
#[inline]
fn zero() -> $n {
$zero
}
#[inline]
fn is_zero(&self) -> bool {
*self == $zero
}
}
impl One for $n {
fn one() -> $n {
$one
}
}
}
);
impl_zero_one!(f32, 0.0, 1.0);
impl_zero_one!(f64, 0.0, 1.0);
impl_zero_one!(i8, 0, 1);
impl_zero_one!(i16, 0, 1);
impl_zero_one!(i32, 0, 1);
impl_zero_one!(i64, 0, 1);
impl_zero_one!(isize, 0, 1);
impl_zero_one!(u8, 0, 1);
impl_zero_one!(u16, 0, 1);
impl_zero_one!(u32, 0, 1);
impl_zero_one!(u64, 0, 1);
impl_zero_one!(usize, 0, 1);
macro_rules! impl_bounded(
($n: ty, $min: expr, $max: expr) => {
impl Bounded for $n {
#[inline]
fn min_value() -> $n {
$min
}
#[inline]
fn max_value() -> $n {
$max
}
}
}
);
impl_bounded!(f32, f32::MIN, f32::MAX);
impl_bounded!(f64, f64::MIN, f64::MAX);
impl_bounded!(i8, i8::MIN, i8::MAX);
impl_bounded!(i16, i16::MIN, i16::MAX);
impl_bounded!(i32, i32::MIN, i32::MAX);
impl_bounded!(i64, i64::MIN, i64::MAX);
impl_bounded!(isize, isize::MIN, isize::MAX);
impl_bounded!(u8, u8::MIN, u8::MAX);
impl_bounded!(u16, u16::MIN, u16::MAX);
impl_bounded!(u32, u32::MIN, u32::MAX);
impl_bounded!(u64, u64::MIN, u64::MAX);
impl_bounded!(usize, usize::MIN, usize::MAX);
macro_rules! impl_base_float(
($n: ident) => {
impl BaseFloat for $n {
fn pi() -> $n {
$n::consts::PI
}
fn two_pi() -> $n {
2.0 * $n::consts::PI
}
fn frac_pi_2() -> $n {
$n::consts::FRAC_PI_2
}
fn frac_pi_3() -> $n {
$n::consts::FRAC_PI_3
}
fn frac_pi_4() -> $n {
$n::consts::FRAC_PI_4
}
fn frac_pi_6() -> $n {
$n::consts::FRAC_PI_6
}
fn frac_pi_8() -> $n {
$n::consts::FRAC_PI_8
}
fn frac_1_pi() -> $n {
$n::consts::FRAC_1_PI
}
fn frac_2_pi() -> $n {
$n::consts::FRAC_2_PI
}
fn frac_2_sqrt_pi() -> $n {
$n::consts::FRAC_2_SQRT_PI
}
fn e() -> $n {
$n::consts::E
}
fn log2_e() -> $n {
$n::consts::LOG2_E
}
fn log10_e() -> $n {
$n::consts::LOG10_E
}
fn ln_2() -> $n {
$n::consts::LN_2
}
fn ln_10() -> $n {
$n::consts::LN_10
}
}
}
);
impl BaseNum for i8 { }
impl BaseNum for i16 { }
impl BaseNum for i32 { }
impl BaseNum for i64 { }
impl BaseNum for isize { }
impl BaseNum for u8 { }
impl BaseNum for u16 { }
impl BaseNum for u32 { }
impl BaseNum for u64 { }
impl BaseNum for usize { }
impl BaseNum for f32 { }
impl BaseNum for f64 { }
impl_base_float!(f32);
impl_base_float!(f64);