al_jabr/
column_vector.rs

1//! `N`-element column vector.
2use super::*;
3
4/// `N`-element column vector.
5///
6/// Column vectors can be constructed from arrays of any type and size. There are
7/// convenience constructor functions provided for the most common sizes.
8///
9/// ```
10/// # use al_jabr::*;
11/// let a: ColumnVector::<u32, 4> = column_vector!( 0u32, 1, 2, 3 );
12/// assert_eq!(
13///     a,
14///     ColumnVector::<u32, 4>::from([ 0u32, 1, 2, 3 ])
15/// );
16/// ```
17/// # Swizzling
18/// [Swizzling](https://en.wikipedia.org/wiki/Swizzling_(computer_graphics))
19/// is supported for up to four elements. Swizzling is a technique for easily
20/// rearranging and accessing elements of a vector, used commonly in graphics
21/// shader programming. Swizzling is available on vectors whose element type
22/// implements `Clone`.
23/// Single-element accessors return the element itself. Multi-element accessors
24/// return vectors of the appropriate size.
25/// ## Element names
26/// Only the first four elements of a vector may be swizzled. If you have vectors
27/// larger than length four and want to manipulate their elements, you must do so
28/// manually.
29/// Because swizzling is often used in compute graphics contexts when dealing with
30/// colors, both 'xyzw' and 'rgba' element names are available.
31///
32/// | Element Index | xyzw Name | rgba Name |
33/// |---------------|-----------|-----------|
34/// | 0             | x         | r         |
35/// | 1             | y         | g         |
36/// | 2             | z         | b         |
37/// | 3             | w         | a         |
38///
39/// ## Restrictions
40/// It is a runtime error to attempt to access an element beyond the bounds of a vector.
41/// For example, `vec2(1i32, 2).z()` will panic because `z()` is only available on vectors
42/// of length 3 or greater. Previously, this was a compilation error. However, for newer
43/// versions of rustc this is no longer always the case.
44/// ```should_panic
45/// # use al_jabr::*;
46/// let z = column_vector!(1i32, 2).z(); // Will panic.
47/// ```
48/// ### Mixing
49/// swizzle methods are not implemented for mixed xyzw/rgba methods.
50/// ```
51/// # use al_jabr::*;
52/// let v = column_vector!(1i32, 2, 3, 4);
53/// let xy = v.xy(); // OK, only uses xyzw names.
54/// let ba = v.ba(); // OK, only uses rgba names.
55/// assert_eq!(xy, column_vector!(1i32, 2));
56/// assert_eq!(ba, column_vector!(3i32, 4));
57/// ```
58/// ```compile_fail
59/// # use al_jabr::*;
60/// let v = column_vector!(1i32, 2, 3, 4);
61/// let bad = v.xyrg(); // Compile error, mixes xyzw and rgba names.
62/// ```
63/// ## Examples
64/// To get the first two elements of a 4-vector.
65/// ```
66/// # use al_jabr::*;
67/// let v = column_vector!(1i32, 2, 3, 4).xy();
68/// ```
69/// To get the first and last element of a 4-vector.
70/// ```
71/// # use al_jabr::*;
72/// let v = column_vector!(1i32, 2, 3, 4).xw();
73/// ```
74/// To reverse the order of a 3-vector.
75/// ```
76/// # use al_jabr::*;
77/// let v = column_vector!(1i32, 2, 3).zyx();
78/// ```
79/// To select the first and third elements into the second and fourth elements,
80/// respectively.
81/// ```
82/// # use al_jabr::*;
83/// let v = column_vector!(1i32, 2, 3, 4).xxzz();
84/// ```
85pub type ColumnVector<T, const N: usize> = Matrix<T, N, 1>;
86
87impl<T> ColumnVector<T, 1>
88where
89    T: One,
90{
91    /// Construct a Vector1 in the positive x direction.
92    pub fn unit_x() -> Self {
93        Matrix([[T::one()]])
94    }
95}
96
97impl<T> ColumnVector<T, 2>
98where
99    T: One + Zero,
100{
101    /// Construct a ColumnVector2 in the positive x direction.
102    pub fn unit_x() -> Self {
103        Matrix([[T::one(), T::zero()]])
104    }
105
106    /// Construct a ColumnVector2 in the positive y direction.
107    pub fn unit_y() -> Self {
108        Matrix([[T::zero(), T::one()]])
109    }
110}
111
112impl<T> ColumnVector<T, 3>
113where
114    T: One + Zero,
115{
116    /// Construct a ColumnVector3 in the positive x direction.
117    pub fn unit_x() -> Self {
118        Matrix([[T::one(), T::zero(), T::zero()]])
119    }
120
121    /// Construct a ColumnVector3 in the positive y direction.
122    pub fn unit_y() -> Self {
123        Matrix([[T::zero(), T::one(), T::zero()]])
124    }
125
126    /// Construct a ColumnVector3 in the positive z direction.
127    pub fn unit_z() -> Self {
128        Matrix([[T::zero(), T::zero(), T::one()]])
129    }
130}
131
132impl<T> ColumnVector<T, 4>
133where
134    T: One + Zero,
135{
136    /// Construct a ColumnVector4 in the positive x direction.
137    pub fn unit_x() -> Self {
138        Matrix([[T::one(), T::zero(), T::zero(), T::zero()]])
139    }
140
141    /// Construct a ColumnVector4 in the positive y direction.
142    pub fn unit_y() -> Self {
143        Matrix([[T::zero(), T::one(), T::zero(), T::zero()]])
144    }
145
146    /// Construct a ColumnVector4 in the positive z direction.
147    pub fn unit_z() -> Self {
148        Matrix([[T::zero(), T::zero(), T::one(), T::zero()]])
149    }
150
151    /// Construct a ColumnVector4 in the positive w direction.
152    pub fn unit_w() -> Self {
153        Matrix([[T::zero(), T::zero(), T::zero(), T::one()]])
154    }
155}
156
157impl<T, const N: usize> ColumnVector<T, N> {
158    /// Convert the Vector into its inner array.
159    pub fn into_inner(self) -> [T; N] {
160        let Matrix([inner]) = self;
161        inner
162    }
163
164    /// Constructs a new vector whose elements are equal to the value of the
165    /// given function evaluated at the element's index.
166    pub fn from_fn<Out, F>(mut f: F) -> ColumnVector<Out, N>
167    where
168        F: FnMut(usize) -> Out,
169    {
170        let mut to = MaybeUninit::<ColumnVector<Out, N>>::uninit();
171        let top = &mut to as *mut MaybeUninit<Matrix<Out, N, 1>> as *mut Out;
172        for i in 0..N {
173            unsafe { top.add(i).write(f(i)) }
174        }
175        unsafe { to.assume_init() }
176    }
177
178    pub fn indexed_map<Out, F>(self, mut f: F) -> ColumnVector<Out, N>
179    where
180        F: FnMut(usize, T) -> Out,
181    {
182        let mut from = MaybeUninit::new(self);
183        let mut to = MaybeUninit::<ColumnVector<Out, N>>::uninit();
184        let fromp = &mut from as *mut MaybeUninit<Matrix<T, N, 1>> as *mut MaybeUninit<T>;
185        let top = &mut to as *mut MaybeUninit<Matrix<Out, N, 1>> as *mut Out;
186        for i in 0..N {
187            unsafe {
188                top.add(i).write(f(
189                    i,
190                    fromp.add(i).replace(MaybeUninit::uninit()).assume_init(),
191                ));
192            }
193        }
194        unsafe { to.assume_init() }
195    }
196}
197
198/*
199/// A `Vector` with one fewer dimension than `N`.
200///
201/// Not particularly useful other than as the return value of the
202/// [truncate](Vector::truncate) method.
203#[doc(hidden)]
204pub type TruncatedVector<T, const N: usize> = Vector<T, { N - 1 }>;
205
206/// A `Vector` with one more additional dimension than `N`.
207///
208/// Not particularly useful other than as the return value of the
209/// [extend](Vector::extend) method.
210#[doc(hidden)]
211pub type ExtendedVector<T, const N: usize> = Vector<T, { N + 1 }>;
212*/
213
214impl<T, const N: usize> ColumnVector<T, N>
215where
216    T: Clone,
217{
218    /// Returns the first `M` elements of `self` in an appropriately sized
219    /// `Vector`.
220    ///
221    /// Calling `first` with `M > N` is a compile error.
222    pub fn first<const M: usize>(&self) -> ColumnVector<T, { M }> {
223        if M > N {
224            panic!("attempt to return {} elements from a {}-vector", M, N);
225        }
226        let mut head = MaybeUninit::<ColumnVector<T, { M }>>::uninit();
227        let headp = &mut head as *mut MaybeUninit<Matrix<T, M, 1>> as *mut T;
228        for i in 0..M {
229            unsafe {
230                headp.add(i).write(self.0[0][i].clone());
231            }
232        }
233        unsafe { head.assume_init() }
234    }
235
236    /// Returns the last `M` elements of `self` in an appropriately sized
237    /// `Vector`.
238    ///
239    /// Calling `last` with `M > N` is a compile error.
240    pub fn last<const M: usize>(&self) -> ColumnVector<T, { M }> {
241        if M > N {
242            panic!("attempt to return {} elements from a {}-vector", M, N);
243        }
244        let mut tail = MaybeUninit::<ColumnVector<T, { M }>>::uninit();
245        let tailp = &mut tail as *mut MaybeUninit<Matrix<T, M, 1>> as *mut T;
246        for i in 0..M {
247            unsafe {
248                tailp.add(i + N - M).write(self.0[0][i].clone());
249            }
250        }
251        unsafe { tail.assume_init() }
252    }
253}
254
255impl<T> ColumnVector3<T>
256where
257    T: Add<T, Output = T> + Sub<T, Output = T> + Mul<T, Output = T> + Clone,
258{
259    /// Return the cross product of the two vectors.
260    pub fn cross(self, rhs: ColumnVector3<T>) -> Self {
261        let Matrix([[x0, y0, z0]]) = self;
262        let Matrix([[x1, y1, z1]]) = rhs;
263        Self::from([[
264            (y0.clone() * z1.clone()) - (z0.clone() * y1.clone()),
265            (z0 * x1.clone()) - (x0.clone() * z1),
266            (x0 * y1) - (y0 * x1),
267        ]])
268    }
269}
270
271impl<T, const N: usize> ColumnVector<T, N>
272where
273    T: Clone + PartialOrd,
274{
275    /// Return the largest value found in the vector, along with the
276    /// associated index.
277    pub fn argmax(&self) -> (usize, T) {
278        let mut i_max = 0;
279        let mut v_max = self.0[0][0].clone();
280        for i in 1..N {
281            if self.0[0][i] > v_max {
282                i_max = i;
283                v_max = self.0[0][i].clone();
284            }
285        }
286        (i_max, v_max)
287    }
288
289    /// Return the largest value in the vector.
290    pub fn max(&self) -> T {
291        let mut v_max = self.0[0][0].clone();
292        for i in 1..N {
293            if self.0[0][i] > v_max {
294                v_max = self.0[0][i].clone();
295            }
296        }
297        v_max
298    }
299
300    /// Return the smallest value found in the vector, along with the
301    /// associated index.
302    pub fn argmin(&self) -> (usize, T) {
303        let mut i_min = 0;
304        let mut v_min = self.0[0][0].clone();
305        for i in 1..N {
306            if self.0[0][i] < v_min {
307                i_min = i;
308                v_min = self.0[0][i].clone();
309            }
310        }
311        (i_min, v_min)
312    }
313
314    /// Return the smallest value in the vector.
315    pub fn min(&self) -> T {
316        let mut v_min = self.0[0][0].clone();
317        for i in 1..N {
318            if self.0[0][i] < v_min {
319                v_min = self.0[0][i].clone();
320            }
321        }
322        v_min
323    }
324}
325
326impl<T, const N: usize> From<[T; N]> for ColumnVector<T, N> {
327    fn from(array: [T; N]) -> Self {
328        Matrix([array])
329    }
330}
331
332impl<T, const N: usize> From<ColumnVector<T, N>> for [T; N] {
333    fn from(v: ColumnVector<T, N>) -> [T; N] {
334        let Matrix([vec]) = v;
335        vec
336    }
337}
338
339/// 1-element vector.
340pub type ColumnVector1<T> = ColumnVector<T, 1>;
341
342/// 2-element vector.
343pub type ColumnVector2<T> = ColumnVector<T, 2>;
344
345impl<T> ColumnVector2<T> {
346    /// Extend a Vector1 into a Vector2.
347    pub fn from_vec1(v: ColumnVector1<T>, y: T) -> Self {
348        let Matrix([[x]]) = v;
349        Matrix([[x, y]])
350    }
351}
352
353/// 3-element vector.
354pub type ColumnVector3<T> = ColumnVector<T, 3>;
355
356impl<T> ColumnVector3<T> {
357    /// Extend a Vector1 into a Vector3.
358    pub fn from_vec1(v: ColumnVector1<T>, y: T, z: T) -> Self {
359        let Matrix([[x]]) = v;
360        Matrix([[x, y, z]])
361    }
362
363    /// Extend a Vector2 into a Vector3.
364    pub fn from_vec2(v: ColumnVector2<T>, z: T) -> Self {
365        let Matrix([[x, y]]) = v;
366        Matrix([[x, y, z]])
367    }
368}
369
370/// 4-element vector.
371pub type ColumnVector4<T> = ColumnVector<T, 4>;
372
373impl<T> ColumnVector4<T> {
374    /// Extend a Vector1 into a Vector4.
375    pub fn from_vec1(v: ColumnVector1<T>, y: T, z: T, w: T) -> Self {
376        let Matrix([[x]]) = v;
377        Matrix([[x, y, z, w]])
378    }
379
380    /// Extend a Vector2 into a Vector4.
381    pub fn from_vec2(v: ColumnVector2<T>, z: T, w: T) -> Self {
382        let Matrix([[x, y]]) = v;
383        Matrix([[x, y, z, w]])
384    }
385
386    /// Extend a Vector3 into a Vector4.
387    pub fn from_vec3(v: ColumnVector3<T>, w: T) -> Self {
388        let Matrix([[x, y, z]]) = v;
389        Matrix([[x, y, z, w]])
390    }
391}
392
393/// Construct a new [ColumnVector] of any size.
394///
395/// ```
396/// # use al_jabr::*;
397/// let v: ColumnVector<u32, 0> = column_vector![];
398/// let v = column_vector![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
399/// let v = column_vector![true, false, false, true];
400/// ```
401#[macro_export]
402macro_rules! column_vector {
403    ( $($elem:expr),* $(,)? ) => {
404        $crate::matrix![
405            $([ $elem ]),*
406        ]
407    }
408}
409
410// @EkardNT: The cool thing about this is that Rust apparently monomorphizes
411// only those functions which are actually used. This means that this impl for
412// vectors of any length N is able to support vectors of length N < 4. For
413// example, calling x() on a Vector2 works, but attempting to call z() will
414// result in a nice compile error.
415//
416// @maplant: Unfortunately, I think due to a compiler change this is no longer
417// the case. I sure hope it's brought back, however...
418impl<T, const N: usize> ColumnVector<T, N> {
419    /// Alias for `.get(0)`.
420    ///
421    /// # Panics
422    /// When `N` = 0.
423    pub fn x(&self) -> &T {
424        &self.0[0][0]
425    }
426
427    pub fn x_mut(&mut self) -> &mut T {
428        &mut self.0[0][0]
429    }
430
431    /// Alias for `.get(1)`.
432    ///
433    /// # Panics
434    /// When `N` < 2.
435    pub fn y(&self) -> &T {
436        &self.0[0][1]
437    }
438
439    pub fn y_mut(&mut self) -> &mut T {
440        &mut self.0[0][1]
441    }
442
443    /// Alias for `.get(2)`.
444    ///
445    /// # Panics
446    /// When `N` < 3.
447    pub fn z(&self) -> &T {
448        &self.0[0][2]
449    }
450
451    pub fn z_mut(&mut self) -> &mut T {
452        &mut self.0[0][2]
453    }
454
455    /// Alias for `.get(3)`.
456    ///
457    /// # Panics
458    /// When `N` < 4.
459    pub fn w(&self) -> &T {
460        &self.0[0][3]
461    }
462
463    pub fn w_mut(&mut self) -> &mut T {
464        &mut self.0[0][3]
465    }
466
467    /// Alias for `.x()`.
468    pub fn r(&self) -> &T {
469        self.x()
470    }
471
472    pub fn r_mut(&mut self) -> &mut T {
473        self.x_mut()
474    }
475
476    /// Alias for `.y()`.
477    pub fn g(&self) -> &T {
478        self.y()
479    }
480
481    pub fn g_mut(&mut self) -> &mut T {
482        self.y_mut()
483    }
484
485    /// Alias for `.z()`.
486    pub fn b(&self) -> &T {
487        self.z()
488    }
489
490    pub fn b_mut(&mut self) -> &mut T {
491        self.z_mut()
492    }
493
494    /// Alias for `.w()`.
495    pub fn a(&self) -> &T {
496        self.w()
497    }
498
499    pub fn a_mut(&mut self) -> &mut T {
500        self.w_mut()
501    }
502}
503
504// Generates all the 2, 3, and 4-level swizzle functions.
505macro_rules! swizzle {
506    // First level. Doesn't generate any functions itself because the one-letter functions
507    // are manually provided in the Swizzle trait.
508    ($a:ident, $x:ident, $y:ident, $z:ident, $w:ident) => {
509        // Pass the alphabet so the second level can choose the next letters.
510        swizzle!{ $a, $x, $x, $y, $z, $w }
511        swizzle!{ $a, $y, $x, $y, $z, $w }
512        swizzle!{ $a, $z, $x, $y, $z, $w }
513        swizzle!{ $a, $w, $x, $y, $z, $w }
514    };
515    // Second level. Generates all 2-element swizzle functions, and recursively calls the
516    // third level, specifying the third letter.
517    ($a:ident, $b:ident, $x:ident, $y:ident, $z:ident, $w:ident) => {
518        paste::item! {
519            #[doc(hidden)]
520            pub fn [< $a $b >](&self) -> ColumnVector<T, 2> {
521                ColumnVector::<T, 2>::from([
522                    self.$a().clone(),
523                    self.$b().clone(),
524                ])
525            }
526        }
527
528        // Pass the alphabet so the third level can choose the next letters.
529        swizzle!{ $a, $b, $x, $x, $y, $z, $w }
530        swizzle!{ $a, $b, $y, $x, $y, $z, $w }
531        swizzle!{ $a, $b, $z, $x, $y, $z, $w }
532        swizzle!{ $a, $b, $w, $x, $y, $z, $w }
533    };
534    // Third level. Generates all 3-element swizzle functions, and recursively calls the
535    // fourth level, specifying the fourth letter.
536    ($a:ident, $b:ident, $c:ident, $x:ident, $y:ident, $z:ident, $w:ident) => {
537        paste::item! {
538            #[doc(hidden)]
539            pub fn [< $a $b $c >](&self) -> ColumnVector<T, 3> {
540                ColumnVector::<T, 3>::from([
541                    self.$a().clone(),
542                    self.$b().clone(),
543                    self.$c().clone(),
544                ])
545            }
546        }
547
548        // Do not need to pass the alphabet because the fourth level does not need to choose
549        // any more letters.
550        swizzle!{ $a, $b, $c, $x }
551        swizzle!{ $a, $b, $c, $y }
552        swizzle!{ $a, $b, $c, $z }
553        swizzle!{ $a, $b, $c, $w }
554    };
555    // Final level which halts the recursion. Generates all 4-element swizzle functions.
556    // No $x, $y, $z, $w parameters because this function does not need to know the alphabet,
557    // because it already has all the names assigned.
558    ($a:ident, $b:ident, $c:ident, $d:ident) => {
559        paste::item! {
560            #[doc(hidden)]
561            pub fn [< $a $b $c $d >](&self) -> ColumnVector<T, 4> {
562                ColumnVector::<T, 4>::from([
563                    self.$a().clone(),
564                    self.$b().clone(),
565                    self.$c().clone(),
566                    self.$d().clone(),
567                ])
568            }
569        }
570    };
571}
572
573impl<T, const N: usize> ColumnVector<T, N>
574where
575    T: Clone,
576{
577    swizzle! {x, x, y, z, w}
578    swizzle! {y, x, y, z, w}
579    swizzle! {z, x, y, z, w}
580    swizzle! {w, x, y, z, w}
581    swizzle! {r, r, g, b, a}
582    swizzle! {g, r, g, b, a}
583    swizzle! {b, r, g, b, a}
584    swizzle! {a, r, g, b, a}
585}
586
587impl<T, const N: usize> VectorSpace for ColumnVector<T, N>
588where
589    T: Clone + Zero,
590    T: Add<T, Output = T>,
591    T: Sub<T, Output = T>,
592    T: Mul<T, Output = T>,
593    T: Div<T, Output = T>,
594{
595    type Scalar = T;
596}
597
598impl<T, const N: usize> MetricSpace for ColumnVector<T, N>
599where
600    Self: InnerSpace,
601{
602    type Metric = <Self as VectorSpace>::Scalar;
603
604    fn distance2(self, other: Self) -> Self::Metric {
605        (other - self).magnitude2()
606    }
607}
608
609impl<T, const N: usize> InnerSpace for ColumnVector<T, N>
610where
611    T: Clone + Zero,
612    T: Add<T, Output = T>,
613    T: Sub<T, Output = T>,
614    T: Mul<T, Output = T>,
615    T: Div<T, Output = T>,
616    Self: Clone,
617{
618    fn dot(self, rhs: Self) -> T {
619        let mut lhs = MaybeUninit::new(self);
620        let mut rhs = MaybeUninit::new(rhs);
621        let mut sum = <T as Zero>::zero();
622        let lhsp = &mut lhs as *mut MaybeUninit<Matrix<T, N, 1>> as *mut MaybeUninit<T>;
623        let rhsp = &mut rhs as *mut MaybeUninit<Matrix<T, N, 1>> as *mut MaybeUninit<T>;
624        for i in 0..N {
625            sum = sum
626                + unsafe {
627                    lhsp.add(i).replace(MaybeUninit::uninit()).assume_init()
628                        * rhsp.add(i).replace(MaybeUninit::uninit()).assume_init()
629                };
630        }
631        sum
632    }
633}
634
635#[cfg(feature = "mint")]
636impl<T: Copy> From<ColumnVector<T, 2>> for mint::Vector2<T> {
637    fn from(v: ColumnVector<T, 2>) -> mint::Vector2<T> {
638        mint::Vector2 {
639            x: *v.x(),
640            y: *v.y(),
641        }
642    }
643}
644
645#[cfg(feature = "mint")]
646impl<T> From<mint::Vector2<T>> for ColumnVector<T, 2> {
647    fn from(mint_vec: mint::Vector2<T>) -> Self {
648        Matrix([[mint_vec.x, mint_vec.y]])
649    }
650}
651
652#[cfg(feature = "mint")]
653impl<T: Copy> From<ColumnVector<T, 3>> for mint::Vector3<T> {
654    fn from(v: ColumnVector<T, 3>) -> mint::Vector3<T> {
655        mint::Vector3 {
656            x: *v.x(),
657            y: *v.y(),
658            z: *v.z(),
659        }
660    }
661}
662
663#[cfg(feature = "mint")]
664impl<T> From<mint::Vector3<T>> for ColumnVector<T, 3> {
665    fn from(mint_vec: mint::Vector3<T>) -> Self {
666        Matrix([[mint_vec.x, mint_vec.y, mint_vec.z]])
667    }
668}
669
670#[cfg(feature = "mint")]
671impl<T: Copy> From<ColumnVector<T, 4>> for mint::Vector4<T> {
672    fn from(v: ColumnVector<T, 4>) -> mint::Vector4<T> {
673        mint::Vector4 {
674            x: *v.x(),
675            y: *v.y(),
676            z: *v.z(),
677            w: *v.w(),
678        }
679    }
680}
681
682#[cfg(feature = "mint")]
683impl<T> From<mint::Vector4<T>> for ColumnVector<T, 4> {
684    fn from(mint_vec: mint::Vector4<T>) -> Self {
685        Matrix([[mint_vec.x, mint_vec.y, mint_vec.z, mint_vec.w]])
686    }
687}
688
689#[cfg(test)]
690mod tests {
691    use super::*;
692
693    type Vector1<T> = ColumnVector<T, 1>;
694    type Vector2<T> = ColumnVector<T, 2>;
695    type Vector3<T> = ColumnVector<T, 3>;
696    type Vector4<T> = ColumnVector<T, 4>;
697
698    #[test]
699    fn test_zero() {
700        let a = Vector3::<u32>::zero();
701        assert_eq!(a, column_vector![0, 0, 0]);
702    }
703
704    #[test]
705    fn test_index() {
706        let a = Vector1::<u32>::from([0]);
707        assert_eq!(*a.x(), 0_u32);
708        let mut b = Vector2::<u32>::from([1, 2]);
709        *b.y_mut() += 3;
710        assert_eq!(*b.y(), 5);
711    }
712
713    #[test]
714    fn test_eq() {
715        let a = Vector1::<u32>::from([0]);
716        let b = Vector1::<u32>::from([1]);
717        let c = Vector1::<u32>::from([0]);
718        let d = [[0u32]];
719        assert_ne!(a, b);
720        assert_eq!(a, c);
721        assert_eq!(a, &d);
722    }
723
724    #[test]
725    fn test_addition() {
726        let a = Vector1::<u32>::from([0]);
727        let b = Vector1::<u32>::from([1]);
728        let c = Vector1::<u32>::from([2]);
729        assert_eq!(a + b, b);
730        assert_eq!(b + b, c);
731        // We shouldn't need to have to test more dimensions, but we shall test
732        // one more.
733        let a = Vector2::<u32>::from([0, 1]);
734        let b = Vector2::<u32>::from([1, 2]);
735        let c = Vector2::<u32>::from([1, 3]);
736        let d = Vector2::<u32>::from([2, 5]);
737        assert_eq!(a + b, c);
738        assert_eq!(b + c, d);
739        let mut c = Vector2::<u32>::from([1, 3]);
740        let d = Vector2::<u32>::from([2, 5]);
741        c += d;
742        let e = Vector2::<u32>::from([3, 8]);
743        assert_eq!(c, e);
744    }
745
746    #[test]
747    fn test_subtraction() {
748        let mut a = Vector1::<u32>::from([3]);
749        let b = Vector1::<u32>::from([1]);
750        let c = Vector1::<u32>::from([2]);
751        assert_eq!(a - c, b);
752        a -= b;
753        assert_eq!(a, c);
754    }
755
756    #[test]
757    fn test_negation() {
758        let a = Vector4::<i32>::from([1, 2, 3, 4]);
759        let b = Vector4::<i32>::from([-1, -2, -3, -4]);
760        assert_eq!(-a, b);
761    }
762
763    #[test]
764    fn test_scale() {
765        let a = Vector4::<f32>::from([2.0, 4.0, 2.0, 4.0]);
766        let b = Vector4::<f32>::from([4.0, 8.0, 4.0, 8.0]);
767        let c = Vector4::<f32>::from([1.0, 2.0, 1.0, 2.0]);
768        assert_eq!(a * 2.0, b);
769        assert_eq!(a / 2.0, c);
770    }
771
772    #[test]
773    fn test_cross() {
774        let a = column_vector!(1isize, 2isize, 3isize);
775        let b = column_vector!(4isize, 5isize, 6isize);
776        let r = column_vector!(-3isize, 6isize, -3isize);
777        assert_eq!(a.cross(b), r);
778    }
779
780    #[test]
781    fn test_distance() {
782        let a = Vector1::<f32>::from([0.0]);
783        let b = Vector1::<f32>::from([1.0]);
784        assert_eq!(a.distance2(b), 1.0);
785        let a = Vector1::<f32>::from([0.0]);
786        let b = Vector1::<f32>::from([2.0]);
787        assert_eq!(a.distance2(b), 4.0);
788        assert_eq!(a.distance(b), 2.0);
789        let a = Vector2::<f32>::from([0.0, 0.0]);
790        let b = Vector2::<f32>::from([1.0, 1.0]);
791        assert_eq!(a.distance2(b), 2.0);
792
793        let a = column_vector!(1i32, 1);
794        let b = column_vector!(5i32, 5);
795        assert_eq!(a.distance2(b), 32); // distance method not implemented.
796        assert_eq!((b - a).magnitude2(), 32);
797    }
798
799    #[test]
800    fn test_normalize() {
801        let a = column_vector!(5.0);
802        assert_eq!(a.magnitude(), 5.0);
803        let a_norm = a.normalize();
804        assert_eq!(a_norm, column_vector!(1.0));
805    }
806
807    #[test]
808    fn test_transpose() {
809        let v = column_vector!(1i32, 2, 3, 4);
810        let m = Matrix::<i32, 1, 4>::from([[1i32], [2], [3], [4]]);
811        assert_eq!(v.transpose(), m);
812    }
813
814    #[test]
815    fn test_from_fn() {
816        let indices: ColumnVector<usize, 10> = column_vector!(0usize, 1, 2, 3, 4, 5, 6, 7, 8, 9);
817        assert_eq!(ColumnVector::<usize, 10>::from_fn(|i| i), indices);
818    }
819
820    #[test]
821    fn test_map() {
822        let int = column_vector!(1i32, 0, 1, 1, 0, 1, 1, 0, 0, 0);
823        let boolean =
824            column_vector!(true, false, true, true, false, true, true, false, false, false);
825        assert_eq!(int.map(|i| i != 0), boolean);
826    }
827
828    #[test]
829    fn test_indexed_map() {
830        let boolean =
831            column_vector!(true, false, true, true, false, true, true, false, false, false);
832        let indices = column_vector!(0usize, 1, 2, 3, 4, 5, 6, 7, 8, 9);
833        assert_eq!(boolean.indexed_map(|i, _| i), indices);
834    }
835
836    #[test]
837    fn test_from_iter() {
838        let v = vec![1i32, 2, 3, 4];
839        let vec = ColumnVector::<i32, 4>::from_iter(v);
840        assert_eq!(vec, column_vector![1i32, 2, 3, 4])
841    }
842
843    #[test]
844    fn test_linear_interpolate() {
845        let v1 = column_vector!(0.0, 0.0, 0.0);
846        let v2 = column_vector!(1.0, 2.0, 3.0);
847        assert_eq!(v1.lerp(v2, 0.5), column_vector!(0.5, 1.0, 1.5));
848    }
849
850    #[test]
851    fn test_reflect() {
852        // Incident straight on to the surface.
853        let v = column_vector!(1, 0);
854        let n = column_vector!(-1, 0);
855        let r = v.reflect(unsafe { Unit::new_unchecked(n) });
856        assert_eq!(r, column_vector!(-1, 0));
857
858        // Incident at 45 degree angle to the surface.
859        let v = column_vector!(1, 1);
860        let n = column_vector!(-1, 0);
861        let r = v.reflect(unsafe { Unit::new_unchecked(n) });
862        assert_eq!(r, column_vector!(-1, 1));
863    }
864}