ndvec/
general.rs

1#[cfg(test)]
2mod tests;
3
4use std::fmt::Debug;
5use std::iter::Sum;
6use std::ops::Add;
7use std::ops::AddAssign;
8use std::ops::Div;
9use std::ops::DivAssign;
10use std::ops::Mul;
11use std::ops::MulAssign;
12use std::ops::Neg;
13use std::ops::Sub;
14use std::ops::SubAssign;
15
16use num_traits::Float;
17use num_traits::Zero;
18#[cfg(feature = "serde_arrays")]
19use serde::Deserialize;
20#[cfg(feature = "serde_arrays")]
21use serde::Serialize;
22
23use crate::array::arr_zip_map;
24use crate::Component;
25use crate::Vector;
26
27/// General-fixed-size low-dimensional vector.
28///
29/// Does not any heap allocation.
30#[derive(Clone, Copy, PartialEq, Eq)]
31#[cfg_attr(feature = "serde_arrays", derive(Serialize, Deserialize))]
32#[cfg_attr(
33    feature = "serde_arrays",
34    serde(bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'de>"))
35)]
36pub struct VecND<T, const N: usize> {
37    #[cfg_attr(feature = "serde_arrays", serde(with = "serde_arrays"))]
38    arr: [T; N],
39}
40
41impl<T: Component, const N: usize> Vector for VecND<T, N> {
42    type Cmp = T;
43
44    const DIM: usize = N;
45
46    fn norm_sqr(self) -> Self::Cmp {
47        self.arr.into_iter().map(|c| c * c).sum::<T>()
48    }
49
50    fn dot(self, rhs: Self) -> Self::Cmp {
51        self.arr.into_iter().zip(rhs.arr).map(|(a, b)| a * b).sum()
52    }
53
54    fn is_finite(self) -> bool {
55        self.arr.into_iter().all(|c| c.is_finite())
56    }
57
58    fn has_nan(self) -> bool {
59        self.arr.into_iter().any(|c| c.is_nan())
60    }
61}
62
63impl<T: Copy + Debug, const N: usize> Debug for VecND<T, N> {
64    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65        f.debug_list().entries(self.arr.iter()).finish()
66    }
67}
68
69impl<T: Copy + Zero, const N: usize> Zero for VecND<T, N> {
70    fn zero() -> Self {
71        Self {
72            arr: [T::zero(); N],
73        }
74    }
75
76    fn is_zero(&self) -> bool {
77        self.arr.iter().all(|c| c.is_zero())
78    }
79}
80
81impl<T: Copy + Neg, const N: usize> Neg for VecND<T, N> {
82    type Output = VecND<T::Output, N>;
83
84    #[inline]
85    fn neg(self) -> Self::Output {
86        VecND {
87            arr: self.arr.map(|v| -v),
88        }
89    }
90}
91
92impl<T: Copy + Neg, const N: usize> Neg for &VecND<T, N> {
93    type Output = VecND<T::Output, N>;
94
95    #[inline]
96    fn neg(self) -> Self::Output {
97        VecND {
98            arr: self.arr.map(|v| -v),
99        }
100    }
101}
102
103macro_rules! impl_vec_vec_op {
104    ($($LB:ident)?; $($RB:ident)?; $Op:ident, $op:ident, $L:ty, $R:ty, $sym:tt) => {
105        impl<T: $Op<S>$(+ $LB)? , S$(: $RB)?, const N: usize> $Op<$R> for $L {
106            type Output = VecND<T::Output, N>;
107
108            #[inline]
109            fn $op(self, rhs: $R) -> Self::Output {
110                VecND {
111                    arr: arr_zip_map(self.arr, rhs.arr, |a, b| a $sym b),
112                }
113            }
114        }
115    };
116}
117
118impl_vec_vec_op!(; ; Add, add, VecND<T, N>, VecND<S, N>, +);
119impl_vec_vec_op!(; Copy; Add, add, VecND<T, N>, &VecND<S, N>, +);
120impl_vec_vec_op!(Copy; ; Add, add, &VecND<T, N>, VecND<S, N>, +);
121impl_vec_vec_op!(Copy; Copy; Add, add, &VecND<T, N>, &VecND<S, N>, +);
122
123impl_vec_vec_op!(; ; Sub, sub, VecND<T, N>, VecND<S, N>, -);
124impl_vec_vec_op!(; Copy; Sub, sub, VecND<T, N>, &VecND<S, N>, -);
125impl_vec_vec_op!(Copy; ; Sub, sub, &VecND<T, N>, VecND<S, N>, -);
126impl_vec_vec_op!(Copy; Copy; Sub, sub, &VecND<T, N>, &VecND<S, N>, -);
127
128macro_rules! impl_vec_num_op {
129    ($($LB:ident)?; $Op:ident, $op:ident, $L:ty, $R:ty, $sym:tt) => {
130        impl<T: $Op<S>$(+ $LB)? , S: Copy, const N: usize> $Op<$R> for $L {
131            type Output = VecND<T::Output, N>;
132
133            #[inline]
134            fn $op(self, rhs: $R) -> Self::Output {
135                VecND {
136                    arr: self.arr.map(|l| l $sym rhs)
137                }
138            }
139        }
140    };
141}
142
143impl_vec_num_op!(; Mul, mul, VecND<T, N>, S, *);
144impl_vec_num_op!(Copy; Mul, mul, &VecND<T, N>, S, *);
145
146impl_vec_num_op!(; Div, div, VecND<T, N>, S, /);
147impl_vec_num_op!(Copy; Div, div, &VecND<T, N>, S, /);
148
149macro_rules! impl_mul_num_vec {
150    ($L:ty, $R:ty, $O:ty) => {
151        impl<const N: usize> Mul<$R> for $L {
152            type Output = $O;
153
154            #[inline]
155            fn mul(self, rhs: $R) -> Self::Output {
156                VecND {
157                    arr: rhs.arr.map(|r| self * r),
158                }
159            }
160        }
161    };
162}
163
164impl_mul_num_vec!(f64, VecND<f64, N>, VecND<f64, N>);
165impl_mul_num_vec!(f64, &VecND<f64, N>, VecND<f64, N>);
166impl_mul_num_vec!(&f64, VecND<f64, N>, VecND<f64, N>);
167impl_mul_num_vec!(&f64, &VecND<f64, N>, VecND<f64, N>);
168
169impl_mul_num_vec!(f32, VecND<f32, N>, VecND<f32, N>);
170impl_mul_num_vec!(f32, &VecND<f32, N>, VecND<f32, N>);
171impl_mul_num_vec!(&f32, VecND<f32, N>, VecND<f32, N>);
172impl_mul_num_vec!(&f32, &VecND<f32, N>, VecND<f32, N>);
173
174macro_rules! impl_assign_vec {
175    ($($RB:ident)?; $Op:ident, $op:ident, $R:ty, $sym:tt) => {
176        impl<T: $Op<S>, S$(: $RB)?, const N: usize> $Op<$R> for VecND<T, N> {
177            #[inline]
178            fn $op(&mut self, rhs: $R) {
179                for (l, r) in self.arr.iter_mut().zip(rhs.arr.into_iter()) {
180                    *l $sym r;
181                }
182            }
183        }
184    };
185}
186
187impl_assign_vec!(; AddAssign, add_assign, VecND<S, N>, +=);
188impl_assign_vec!(Copy; AddAssign, add_assign, &VecND<S, N>, +=);
189impl_assign_vec!(; SubAssign, sub_assign, VecND<S, N>, -=);
190impl_assign_vec!(Copy; SubAssign, sub_assign, &VecND<S, N>, -=);
191
192impl<T: MulAssign<S>, S: Copy, const N: usize> MulAssign<S> for VecND<T, N> {
193    #[inline]
194    fn mul_assign(&mut self, rhs: S) {
195        for c in self.arr.iter_mut() {
196            *c *= rhs;
197        }
198    }
199}
200
201impl<T: DivAssign<S>, S: Copy, const N: usize> DivAssign<S> for VecND<T, N> {
202    #[inline]
203    fn div_assign(&mut self, rhs: S) {
204        for c in self.arr.iter_mut() {
205            *c /= rhs;
206        }
207    }
208}
209
210impl<T: Float, const N: usize> Sum for VecND<T, N> {
211    #[inline]
212    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
213        iter.fold(VecND::zero(), |a, b| a + b)
214    }
215}
216
217impl<T, const N: usize> From<[T; N]> for VecND<T, N> {
218    #[inline]
219    fn from(arr: [T; N]) -> Self {
220        Self { arr }
221    }
222}
223
224impl<T, const N: usize> From<VecND<T, N>> for [T; N] {
225    #[inline]
226    fn from(vec: VecND<T, N>) -> Self {
227        vec.arr
228    }
229}
230
231impl<T, const N: usize> AsRef<[T; N]> for VecND<T, N> {
232    fn as_ref(&self) -> &[T; N] {
233        &self.arr
234    }
235}
236
237impl<T, const N: usize> AsMut<[T; N]> for VecND<T, N> {
238    fn as_mut(&mut self) -> &mut [T; N] {
239        &mut self.arr
240    }
241}