use std::fmt::{Debug, Display};
use std::iter::IntoIterator;
use std::ops::{
Add,
AddAssign,
Div,
DivAssign,
Index,
IndexMut,
Mul,
MulAssign,
Neg,
Sub,
SubAssign,
};
use num::Float;
pub mod prelude
{
pub use crate::ArithmeticType;
pub use crate::InnerSpace;
pub use crate::RealField;
pub use crate::VectorSpace;
}
pub trait ArithmeticType<S>:
Mul<S, Output = Self>
+ AddAssign<Self>
+ SubAssign<Self>
+ Add<Output = Self>
+ Sub<Output = Self>
+ Neg<Output = Self>
+ Clone
+ Sized
where
S: RealField + Mul<Self, Output = Self>,
{
}
impl<T, S> ArithmeticType<S> for T
where
T: Mul<S, Output = Self>
+ AddAssign<Self>
+ SubAssign<Self>
+ Add<Output = Self>
+ Sub<Output = Self>
+ Neg<Output = Self>
+ Clone
+ Sized,
S: RealField + Mul<Self, Output = Self>,
{
}
pub trait RealField:
Display
+ Debug
+ Default
+ Add
+ Sub
+ Mul
+ Div
+ AddAssign
+ DivAssign
+ SubAssign
+ MulAssign
+ Float
+ 'static
{
fn clamp(&self, min: Self, high: Self) -> Self
{
if *self < min
{
min
}
else if *self > high
{
high
}
else
{
self.clone()
}
}
}
impl<T> RealField for T where
T: Display
+ Debug
+ Default
+ Add
+ Sub
+ Mul
+ Div
+ AddAssign
+ DivAssign
+ SubAssign
+ MulAssign
+ Float
+ 'static
{
}
pub trait VMul<S> {}
impl<V, S> VMul<S> for V where S: Mul<V, Output = V> + RealField {}
pub trait VectorSpace:
ArithmeticType<Self::Scalar>
+ Index<usize, Output = Self::Scalar>
+ IndexMut<usize, Output = Self::Scalar>
+ Default
+ VMul<Self::Scalar>
{
type Scalar: RealField + Mul<Self, Output = Self>;
fn cross(&self, other: &Self) -> Self;
fn set_subset(&mut self, values: &[Self::Scalar])
{
for (i, v) in values.iter().enumerate()
{
self[i] = v.clone()
}
}
}
impl<V, S> VectorSpace for V
where
V: ArithmeticType<S>
+ Index<usize, Output = S>
+ IndexMut<usize, Output = S>
+ Default,
S: RealField + Mul<Self, Output = Self>,
{
type Scalar = S;
fn cross(&self, other: &Self) -> Self
{
let mut result = self.clone() * S::from(0.0).unwrap();
result[0] = self[1] * other[2] - self[2] * other[1];
result[1] = self[2] * other[0] - self[0] * other[2];
result[2] = self[0] * other[1] - self[1] * other[0];
result
}
}
pub trait RefIterable<I> {
type Iter<'a>: Iterator<Item = &'a I>
where
Self: 'a,
I: 'a;
fn iter<'a>(&'a self) -> Self::Iter<'a>
where
I: 'a;
}
impl<T, I> RefIterable<I> for T
where
for<'a> &'a T: IntoIterator<Item = &'a I>,
{
type Iter<'a>
= <&'a Self as IntoIterator>::IntoIter
where
Self: 'a,
I: 'a;
fn iter<'a>(&'a self) -> Self::Iter<'a>
where
I: 'a,
{
IntoIterator::into_iter(self)
}
}
pub trait InnerSpace<S>: VectorSpace<Scalar = S> + RefIterable<S>
where
S: RealField + Display + Debug,
{
fn normalized(&self) -> Self;
fn norm(&self) -> Self::Scalar;
fn norm_squared(&self) -> Self::Scalar;
fn dot(&self, other: &Self) -> S;
fn map(&self, f: impl FnMut(S) -> S) -> Self;
fn from_scalar(s: S) -> Self;
}
impl<V, S> InnerSpace<S> for V
where
V: VectorSpace<Scalar = S> + RefIterable<S>,
S: RealField,
{
fn normalized(&self) -> Self { self.clone() * (S::from(1.0).unwrap() / self.norm()) }
fn norm(&self) -> S { self.norm_squared().sqrt() }
fn norm_squared(&self) -> S { self.dot(&self) }
fn dot(&self, other: &Self) -> S
{
let mut result = S::from(0.0).unwrap();
for (v, w) in self.iter().zip(other.iter())
{
result += v.clone() * w.clone();
}
result
}
fn map(&self, mut f: impl FnMut(S) -> S) -> Self
{
let mut result = self.clone();
for (i, v) in self.iter().enumerate()
{
result[i] = f(v.clone());
}
result
}
fn from_scalar(s: S) -> Self
{
let mut result = V::default();
for (i, _) in V::default().iter().enumerate()
{
result[i] = s;
}
result
}
}