#![deny(missing_docs)]
use inner_space::{DotProduct, VectorSpace};
use scalars::{Real, Zero};
use vector_basis::Basis;
use std::{
iter::Sum,
ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign},
};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Vector<T, const N: usize>([T; N]);
impl<T, const N: usize> Vector<T, N> {
pub const fn new(elements: [T; N]) -> Self {
Self(elements)
}
}
impl<T: Real, const N: usize, const I: usize> Basis<I> for Vector<T, N> {
fn unit_basis() -> Self {
let mut result = Self::zero();
result.0[I] = T::one();
result
}
fn basis_of(magnitude: T) -> Self {
let mut result = Self::zero();
result.0[I] = magnitude;
result
}
fn basis(&self) -> Self::Scalar {
self.0[I]
}
fn basis_mut(&mut self) -> &mut Self::Scalar {
&mut self.0[I]
}
}
impl<T: Default + Copy, const N: usize> Default for Vector<T, N> {
fn default() -> Self {
Self([T::default(); N])
}
}
impl<T, const N: usize> Add<Self> for Vector<T, N>
where
T: Add<Output = T> + Copy,
{
type Output = Self;
fn add(mut self, other: Self) -> Self {
for i in 0..N {
self.0[i] = self.0[i] + other.0[i];
}
self
}
}
impl<T, const N: usize> AddAssign<Self> for Vector<T, N>
where
T: AddAssign + Copy,
{
fn add_assign(&mut self, other: Self) {
for i in 0..N {
self.0[i] += other.0[i];
}
}
}
impl<T, const N: usize> Sub<Self> for Vector<T, N>
where
T: Sub<Output = T> + Copy,
{
type Output = Self;
fn sub(mut self, other: Self) -> Self {
for i in 0..N {
self.0[i] = self.0[i] - other.0[i];
}
self
}
}
impl<T, const N: usize> SubAssign<Self> for Vector<T, N>
where
T: SubAssign + Copy,
{
fn sub_assign(&mut self, other: Self) {
for i in 0..N {
self.0[i] -= other.0[i];
}
}
}
impl<T, const N: usize> Neg for Vector<T, N>
where
T: Neg<Output = T> + Copy,
{
type Output = Self;
fn neg(mut self) -> Self {
for i in 0..N {
self.0[i] = -self.0[i];
}
self
}
}
impl<T, const N: usize> Mul<T> for Vector<T, N>
where
T: Mul<Output = T> + Copy,
{
type Output = Self;
fn mul(mut self, other: T) -> Self {
for i in 0..N {
self.0[i] = self.0[i] * other;
}
self
}
}
impl<T, const N: usize> MulAssign<T> for Vector<T, N>
where
T: MulAssign + Copy,
{
fn mul_assign(&mut self, other: T) {
for i in 0..N {
self.0[i] *= other;
}
}
}
impl<T, const N: usize> Div<T> for Vector<T, N>
where
T: Div<Output = T> + Copy,
{
type Output = Self;
fn div(mut self, other: T) -> Self {
for i in 0..N {
self.0[i] = self.0[i] / other;
}
self
}
}
impl<T, const N: usize> DivAssign<T> for Vector<T, N>
where
T: DivAssign + Copy,
{
fn div_assign(&mut self, other: T) {
for i in 0..N {
self.0[i] /= other;
}
}
}
impl<T, const N: usize> Mul<Self> for Vector<T, N>
where
T: Add<Output = T> + Mul<Output = T> + Zero + Copy,
{
type Output = T;
fn mul(self, other: Self) -> T {
self.0
.iter()
.zip(other.0.iter())
.fold(T::zero(), |result, (&left, &right)| result + left * right)
}
}
impl<T: Zero + Copy, const N: usize> Zero for Vector<T, N> {
fn zero() -> Self {
Self([T::zero(); N])
}
fn is_zero(&self) -> bool {
for i in 0..N {
if !self.0[i].is_zero() {
return false;
}
}
true
}
}
impl<T: Real, const N: usize> VectorSpace for Vector<T, N> {
type Scalar = T;
}
impl<T: Real, const N: usize> DotProduct for Vector<T, N> {
type Output = Self::Scalar;
fn dot(&self, other: &Self) -> T {
*self * *other
}
}
impl<T, const N: usize> From<[T; N]> for Vector<T, N> {
fn from(elements: [T; N]) -> Self {
Self::new(elements)
}
}
impl<T, const N: usize> From<Vector<T, N>> for [T; N] {
fn from(val: Vector<T, N>) -> Self {
val.0
}
}
impl<'a, T, const N: usize> From<&'a Vector<T, N>> for &'a [T; N] {
fn from(val: &'a Vector<T, N>) -> Self {
&val.0
}
}
impl<'a, T, const N: usize> From<&'a mut Vector<T, N>> for &'a mut [T; N] {
fn from(val: &'a mut Vector<T, N>) -> Self {
&mut val.0
}
}
impl<'a, T, const N: usize> From<&'a Vector<T, N>> for &'a [T] {
fn from(val: &'a Vector<T, N>) -> Self {
&val.0
}
}
impl<'a, T, const N: usize> From<&'a mut Vector<T, N>> for &'a mut [T] {
fn from(val: &'a mut Vector<T, N>) -> Self {
&mut val.0
}
}
impl<I, T, const N: usize> Index<I> for Vector<T, N>
where
[T; N]: Index<I>,
{
type Output = <[T; N] as Index<I>>::Output;
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
}
impl<I, T, const N: usize> IndexMut<I> for Vector<T, N>
where
[T; N]: IndexMut<I>,
{
fn index_mut(&mut self, index: I) -> &mut Self::Output {
&mut self.0[index]
}
}
impl<T, const N: usize> Sum for Vector<T, N>
where
T: Add<Output = T> + Zero + Copy,
{
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = Self>,
{
iter.fold(Self::zero(), |acc, v| acc + v)
}
}
mod point;
pub use point::Point;
#[cfg(feature = "parsable")]
mod parsable;