vectora/types/
vector.rs

1//! Vector types.
2
3use std::{
4    borrow::{Borrow, BorrowMut},
5    cmp::Ordering,
6    fmt,
7    iter::{IntoIterator, Sum},
8    ops::{Add, Deref, DerefMut, Index, IndexMut, Mul, Neg, Sub},
9    slice::SliceIndex,
10};
11
12use approx::{AbsDiffEq, Relative, RelativeEq, UlpsEq};
13use num::{Complex, Float, Num, ToPrimitive};
14
15#[cfg(feature = "parallel")]
16#[allow(unused_imports)]
17use rayon::iter::{
18    IntoParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator,
19};
20
21#[cfg(feature = "parallel")]
22use rayon::slice::{ParallelSlice, ParallelSliceMut};
23
24use crate::errors::VectorError;
25
26// ================================
27//
28// Type aliases for 2D and 3D types
29//
30// ================================
31// Two-dimensional
32/// Type alias for a generic 2D vector
33pub type Vector2d<T> = Vector<T, 2>;
34// signed integers
35/// Type alias for a 2D i8 integer vector.
36pub type Vector2dI8 = Vector<i8, 2>;
37/// Type alias for a 2D i16 integer vector.
38pub type Vector2dI16 = Vector<i16, 2>;
39/// Type alias for a 2D i32 integer vector.
40pub type Vector2dI32 = Vector<i32, 2>;
41/// Type alias for a 2D i64 integer vector.
42pub type Vector2dI64 = Vector<i64, 2>;
43/// Type alias for a 2D i128 integer vector.
44pub type Vector2dI128 = Vector<i128, 2>;
45// unsigned integers
46/// Type alias for a 2D u8 integer vector.
47pub type Vector2dU8 = Vector<u8, 2>;
48/// Type alias for a 2D u16 integer vector.
49pub type Vector2dU16 = Vector<u16, 2>;
50/// Type alias for a 2D u32 integer vector.
51pub type Vector2dU32 = Vector<u32, 2>;
52/// Type alias for a 2D u64 integer vector.
53pub type Vector2dU64 = Vector<u64, 2>;
54/// Type alias for a 2D u128 integer vector.
55pub type Vector2dU128 = Vector<u128, 2>;
56// floats
57/// Type alias for a 2D f32 float vector.
58pub type Vector2dF32 = Vector<f32, 2>;
59/// Type alias for a 2D f64 float vector.
60pub type Vector2dF64 = Vector<f64, 2>;
61// architecture-specific
62/// Type alias for a 2D isize integer vector.
63pub type Vector2dIsize = Vector<isize, 2>;
64/// Type alias for a 2D usize integer vector.
65pub type Vector2dUsize = Vector<usize, 2>;
66
67// Three dimensional
68/// Type alias for a generic 3D vector.
69pub type Vector3d<T> = Vector<T, 3>;
70// signed integers
71/// Type alias for a 3D i8 integer vector.
72pub type Vector3dI8 = Vector<i8, 3>;
73/// Type alias for a 3D i16 integer vector.
74pub type Vector3dI16 = Vector<i16, 3>;
75/// Type alias for a 3D i32 integer vector.
76pub type Vector3dI32 = Vector<i32, 3>;
77/// Type alias for a 3D i64 integer vector.
78pub type Vector3dI64 = Vector<i64, 3>;
79/// Type alias for a 3D i128 integer vector.
80pub type Vector3dI128 = Vector<i128, 3>;
81// unsigned integers
82/// Type alias for a 3D u8 integer vector.
83pub type Vector3dU8 = Vector<u8, 3>;
84/// Type alias for a 3D u16 integer vector.
85pub type Vector3dU16 = Vector<u16, 3>;
86/// Type alias for a 3D u16 integer vector.
87pub type Vector3dU32 = Vector<u32, 3>;
88/// Type alias for a 3D u32 integer vector.
89pub type Vector3dU64 = Vector<u64, 3>;
90/// Type alias for a 3D u64 integer vector.
91pub type Vector3dU128 = Vector<u128, 3>;
92// floats
93/// Type alias for a 3D f32 float vector.
94pub type Vector3dF32 = Vector<f32, 3>;
95/// Type alias for a 3D f64 float vector.
96pub type Vector3dF64 = Vector<f64, 3>;
97// architecture-specific
98/// Type alias for a 3D isize integer vector.
99pub type Vector3dIsize = Vector<isize, 3>;
100/// Type alias for a 3D usize integer vector.
101pub type Vector3dUsize = Vector<usize, 3>;
102
103/// A generic, fixed length, ordered vector type that supports
104/// computation with N-dimensional real and complex scalar data.
105#[must_use]
106#[derive(Copy, Clone, Debug)]
107pub struct Vector<T, const N: usize>
108where
109    T: Num + Copy + Sync + Send,
110{
111    /// Ordered N-dimensional scalar values.
112    pub components: [T; N],
113}
114
115// ================================
116//
117// Instantiation method impl
118//
119// ================================
120impl<T, const N: usize> Vector<T, N>
121where
122    T: Num + Copy + Default + Sync + Send,
123{
124    /// Returns a new [`Vector`] initialized with default numeric
125    /// type scalar values.
126    ///
127    /// # Examples
128    ///
129    /// ## Turbofish syntax
130    ///
131    /// Use turbofish syntax to define the numeric type of the vector
132    /// component scalar values and number of vector dimensions:
133    ///
134    /// ```
135    /// # use vectora::types::vector::Vector;
136    /// let v = Vector::<i32, 2>::new();
137    ///
138    /// assert_eq!(v.len(), 2);
139    /// assert_eq!(v[0], i32::default());
140    /// assert_eq!(v[1], i32::default());
141    /// ```
142    ///
143    /// ```
144    /// # use vectora::types::vector::Vector;
145    /// let v = Vector::<f64, 3>::new();
146    ///
147    /// assert_eq!(v.len(), 3);
148    /// assert_eq!(v[0], f64::default());
149    /// assert_eq!(v[1], f64::default());
150    /// assert_eq!(v[2], f64::default());
151    /// ```
152    ///
153    /// ```
154    /// # use vectora::Vector;
155    /// use approx::assert_relative_eq;
156    /// use num::Complex;
157    ///
158    /// let v = Vector::<Complex<f64>, 2>::new();
159    ///
160    /// assert_eq!(v.len(), 2);
161    /// assert_relative_eq!(v[0].re, f64::default());
162    /// assert_relative_eq!(v[0].im, f64::default());
163    /// assert_relative_eq!(v[1].re, f64::default());
164    /// assert_relative_eq!(v[1].im, f64::default());
165    /// ```
166    ///
167    /// ## Type alias syntax
168    ///
169    /// Simplify instantiation with a 2D or 3D type alias:
170    ///
171    /// ```
172    /// # use vectora::Vector;
173    /// use vectora::types::vector::{Vector2d, Vector2dI32, Vector3d, Vector3dF64};
174    ///
175    /// let v1 = Vector2d::<i32>::new();
176    /// let v2 = Vector2dI32::new();
177    ///
178    /// let v3 = Vector3d::<f64>::new();
179    /// let v4 = Vector3dF64::new();
180    /// ```
181    ///
182    /// ## With type inference
183    ///
184    /// There is no requirement for additional data when the type can be inferrred
185    /// by the compiler:
186    ///
187    /// ```
188    /// # use vectora::Vector;
189    /// let v: Vector<u32, 3> = Vector::new();
190    /// ```
191    pub fn new() -> Self {
192        Self { components: [T::default(); N] }
193    }
194
195    /// Returns a new [`Vector`] initialized with scalar zero values
196    /// for the corresponding numeric type.
197    ///
198    /// # Examples
199    ///
200    /// Basic usage:
201    ///
202    /// ## Integer scalars
203    ///
204    /// ```
205    /// # use vectora::Vector;
206    /// let v: Vector<i32, 3> = Vector::zero();
207    ///
208    /// assert_eq!(v.len(), 3);
209    /// assert_eq!(v[0], 0_i32);
210    /// assert_eq!(v[1], 0_i32);
211    /// assert_eq!(v[2], 0_i32);
212    /// ```
213    ///
214    /// ## Floating point scalars
215    ///
216    /// ```
217    /// # use vectora::Vector;
218    /// let v: Vector<f64, 3> = Vector::zero();
219    ///
220    /// assert_eq!(v.len(), 3);
221    /// assert_eq!(v[0], 0.0_f64);
222    /// assert_eq!(v[1], 0.0_f64);
223    /// assert_eq!(v[2], 0.0_f64);
224    /// ```
225    ///
226    /// ## Complex number scalars
227    ///
228    /// ```
229    ///# use vectora::Vector;
230    /// use approx::assert_relative_eq;
231    /// use num::Complex;
232    ///
233    /// let v: Vector<Complex<f64>, 2> = Vector::zero();
234    ///
235    /// assert_eq!(v.len(), 2);
236    /// assert_relative_eq!(v[0].re, 0.0_f64);
237    /// assert_relative_eq!(v[0].im, 0.0_f64);
238    /// assert_relative_eq!(v[1].re, 0.0_f64);
239    /// assert_relative_eq!(v[1].im, 0.0_f64);
240    /// ```
241    pub fn zero() -> Self {
242        Self { components: [T::zero(); N] }
243    }
244}
245
246impl<T, const N: usize> Default for Vector<T, N>
247where
248    T: Num + Copy + Default + Sync + Send,
249{
250    /// Returns a new [`Vector`] initialized with default
251    /// numeric type scalar values.
252    ///
253    /// # Examples
254    ///
255    /// Basic usage:
256    ///
257    /// ```
258    /// # use vectora::types::vector::Vector;
259    /// let v1 = Vector::<i32, 2>::default();
260    /// let v2 = Vector::<f64, 3>::default();
261    /// ```
262    fn default() -> Self {
263        Self::new()
264    }
265}
266
267// ================================
268//
269// Display trait impl
270//
271// ================================
272
273impl<T, const N: usize> fmt::Display for Vector<T, N>
274where
275    T: Num + Copy + Default + Sync + Send + fmt::Debug,
276{
277    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
278        write!(f, "{:?}", self.components)
279    }
280}
281
282impl<T, const N: usize> Vector<T, N>
283where
284    T: Num + Copy + Sync + Send + std::fmt::Debug,
285{
286    /// Returns a pretty-print formatted [`String`] of ordered [`Vector`]
287    /// data.
288    ///
289    /// # Examples
290    ///
291    /// Basic usage:
292    ///
293    /// ```
294    /// # use vectora::types::vector::Vector;
295    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
296    ///
297    /// assert_eq!(v.pretty(), String::from("[\n    1,\n    2,\n    3,\n]"));
298    /// ```
299    pub fn pretty(&self) -> String {
300        format!("{:#?}", self.components)
301    }
302
303    /// Returns a reference to a [`Vector`] index value or range,
304    /// or `None` if the index is out of bounds.
305    ///
306    /// This method provides safe, bounds checked immutable access to scalar data
307    /// references.
308    ///
309    /// # Examples
310    ///
311    /// ## With Index Values
312    ///
313    /// ```
314    /// # use vectora::types::vector::Vector;
315    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
316    ///
317    /// assert_eq!(v.get(0), Some(&1));
318    /// assert_eq!(v.get(1), Some(&2));
319    /// assert_eq!(v.get(2), Some(&3));
320    /// assert_eq!(v.get(10), None);
321    /// ```
322    ///
323    /// ## With Index Ranges
324    ///
325    /// ```
326    /// # use vectora::types::vector::Vector;
327    /// let v = Vector::<i32, 5>::from([1, 2, 3, 4, 5]);
328    ///
329    /// assert_eq!(v.get(0..3).unwrap(), [1, 2, 3]);
330    /// assert_eq!(v.get(3..).unwrap(), [4, 5]);
331    /// assert_eq!(v.get(..2).unwrap(), [1, 2]);
332    /// assert_eq!(v.get(..).unwrap(), [1, 2, 3, 4, 5]);
333    /// assert_eq!(v.get(2..10), None);
334    /// ```
335    pub fn get<I>(&self, index: I) -> Option<&I::Output>
336    where
337        I: SliceIndex<[T]>,
338    {
339        self.components.get(index)
340    }
341
342    /// Returns a mutable reference to a [`Vector`] index value or range,
343    /// or `None` if the index is out of bounds.
344    ///
345    /// This method provides safe, bounds checked mutable access to scalar
346    /// data references.
347    ///
348    /// # Examples
349    ///
350    /// ## With Index Values
351    ///
352    /// ```
353    /// # use vectora::types::vector::Vector;
354    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
355    ///
356    /// assert_eq!(v.get_mut(0), Some(&mut 1));
357    /// assert_eq!(v.get_mut(1), Some(&mut 2));
358    /// assert_eq!(v.get_mut(2), Some(&mut 3));
359    /// assert_eq!(v.get_mut(10), None);
360    ///
361    /// let x = v.get_mut(0).unwrap();
362    ///
363    /// assert_eq!(x, &mut 1);
364    ///
365    /// *x = 10;
366    ///
367    /// assert_eq!(v[0], 10);
368    /// assert_eq!(v[1], 2);
369    /// assert_eq!(v[2], 3);
370    /// ```
371    ///
372    /// ## With Index Ranges
373    ///
374    /// ```
375    /// # use vectora::types::vector::Vector;
376    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
377    ///
378    /// assert_eq!(v.get_mut(0..3).unwrap(), [1, 2, 3]);
379    /// assert_eq!(v.get_mut(2..10), None);
380    ///
381    /// let r = v.get_mut(0..2).unwrap();
382    ///
383    /// assert_eq!(r, &mut [1, 2]);
384    ///
385    /// r[0] = 5;
386    /// r[1] = 6;
387    ///
388    /// assert_eq!(v[0], 5);
389    /// assert_eq!(v[1], 6);
390    /// assert_eq!(v[2], 3);
391    /// ```
392    pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
393    where
394        I: SliceIndex<[T]>,
395    {
396        self.components.get_mut(index)
397    }
398
399    /// Returns an iterator over immutable [`Vector`] scalar data references.
400    ///
401    /// # Examples
402    ///
403    /// Basic usage:
404    ///
405    /// ```
406    /// # use vectora::types::vector::Vector;
407    /// let v = &Vector::<i32, 3>::from([1, 2, 3]);
408    /// let mut v_iter = v.iter();
409    ///
410    /// assert_eq!(v_iter.next(), Some(&1));
411    /// assert_eq!(v_iter.next(), Some(&2));
412    /// assert_eq!(v_iter.next(), Some(&3));
413    /// assert_eq!(v_iter.next(), None);
414    /// ```
415    pub fn iter(&self) -> impl Iterator<Item = &T> {
416        self.components.iter()
417    }
418
419    /// Returns an iterator over mutable [`Vector`] scalar data references.
420    ///
421    /// # Examples
422    ///
423    /// Basic usage:
424    ///
425    /// ```
426    /// # use vectora::types::vector::Vector;
427    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
428    ///
429    /// for x in v.iter_mut() {
430    ///     *x += 3;
431    /// }
432    ///
433    /// assert_eq!(v[0], 4);
434    /// assert_eq!(v[1], 5);
435    /// assert_eq!(v[2], 6);
436    /// ```
437    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
438        self.components.iter_mut()
439    }
440
441    /// Returns a [`slice`] representation of the [`Vector`] scalar data.
442    ///
443    /// # Examples
444    ///
445    /// Basic usage:
446    ///
447    /// ```
448    /// # use vectora::types::vector::Vector;
449    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
450    /// let x: &[i32] = v.as_slice();
451    ///
452    /// assert_eq!(x, &[1, 2, 3][..]);
453    /// ```
454    pub fn as_slice(&self) -> &[T] {
455        &self.components[..]
456    }
457
458    /// Returns a mutable [`slice`] representation of the [`Vector`] scalar data.
459    ///
460    /// # Examples
461    ///
462    /// Basic usage:
463    ///
464    /// ```
465    /// # use vectora::types::vector::Vector;
466    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
467    /// let mut x: &mut [i32] = v.as_mut_slice();
468    ///
469    /// assert_eq!(x, &[1, 2, 3][..]);
470    ///
471    /// x[0] = 10;
472    ///
473    /// assert_eq!(x, &[10,2,3][..]);
474    /// ```
475    ///
476    /// Note: The assignment above **changes** the [`Vector`] data:
477    ///
478    /// ```
479    /// # use vectora::types::vector::Vector;
480    /// # let mut v = Vector::<u32, 3>::from(&[1, 2, 3]);
481    /// # let mut x: &mut [u32] = v.as_mut_slice();
482    /// # assert_eq!(x, &[1, 2, 3]);
483    /// # x[0] = 10;
484    /// # assert_eq!(x, &[10,2,3]);
485    /// assert_eq!(v[0], 10);
486    /// ```
487    pub fn as_mut_slice(&mut self) -> &mut [T] {
488        &mut self.components[..]
489    }
490
491    /// Returns an [`array`] reference representation of the [`Vector`] scalar data.
492    ///
493    /// # Examples
494    ///
495    /// Basic usage:
496    ///
497    /// ```
498    /// # use vectora::types::vector::Vector;
499    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
500    /// let x: &[i32;3] = v.as_array();
501    ///
502    /// assert_eq!(x, &[1, 2, 3]);
503    /// ```
504    pub fn as_array(&self) -> &[T; N] {
505        &self.components
506    }
507
508    /// Returns a mutable [`array`] reference representation of the [`Vector`] scalar data.
509    ///
510    /// # Examples
511    ///
512    /// Basic usage:
513    ///
514    /// ```
515    /// # use vectora::types::vector::Vector;
516    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
517    /// let mut x: &mut [i32;3] = v.as_mut_array();
518    ///
519    /// assert_eq!(x, &[1, 2, 3]);
520    ///
521    /// x[0] = 10;
522    ///
523    /// assert_eq!(x, &[10,2,3]);
524    /// ```
525    ///
526    /// Note: The assignment above **changes** the [`Vector`] data:
527    ///
528    /// ```
529    /// # use vectora::types::vector::Vector;
530    /// # let mut v = Vector::<u32, 3>::from(&[1, 2, 3]);
531    /// # let mut x: &mut [u32;3] = v.as_mut_array();
532    /// # assert_eq!(x, &[1, 2, 3]);
533    /// # x[0] = 10;
534    /// # assert_eq!(x, &[10,2,3]);
535    /// assert_eq!(v[0], 10);
536    /// ```
537    pub fn as_mut_array(&mut self) -> &mut [T; N] {
538        &mut self.components
539    }
540
541    /// Returns a new [`Vector`] with an **unchecked** numeric type cast as defined by
542    /// the return type in a closure parameter.
543    ///
544    /// # Safety
545    ///
546    /// While this method does not use `unsafe` blocks of code
547    /// and returned data *should* be sound, it can lead to information loss
548    /// and incorrect programs if return values are unexpected
549    /// (e.g., saturating overflows and underflows,
550    /// `NAN` can cast to zero integer values).
551    ///
552    /// Please understand the nuances of your type cast and use caution.
553    ///
554    /// # Examples
555    ///
556    /// Basic usage:
557    ///
558    /// ```
559    /// # use vectora::types::vector::Vector;
560    /// let v = Vector::<f32, 3>::from([1.12, 2.50, 3.99]);
561    ///
562    /// // Float to int type with default trunc
563    /// let i64_trunc_v = v.to_num_cast(|x| x as i64);
564    /// assert_eq!(i64_trunc_v, Vector::<i64, 3>::from([1, 2, 3]));
565    ///
566    /// // Float to int type with round
567    /// let i64_round_v = v.to_num_cast(|x| x.round() as i64);
568    /// assert_eq!(i64_round_v, Vector::<i64, 3>::from([1, 3, 4]));
569    ///
570    /// // Float to int type with ceil
571    /// let i64_ceil_v = v.to_num_cast(|x| x.ceil() as i64);
572    /// assert_eq!(i64_ceil_v, Vector::<i64, 3>::from([2, 3, 4]));
573    ///
574    /// // Float to int type with floor
575    /// let i64_floor_v = v.to_num_cast(|x| x.floor() as i64);
576    /// assert_eq!(i64_floor_v, Vector::<i64, 3>::from([1, 2, 3]));
577    /// ```
578    pub fn to_num_cast<U, V>(&self, closur: U) -> Vector<V, N>
579    where
580        U: Fn(T) -> V,
581        V: Num + Copy + Sync + Send,
582    {
583        let mut new_components: [V; N] = [V::zero(); N];
584        self.components.iter().enumerate().for_each(|(i, x)| new_components[i] = closur(*x));
585        Vector { components: new_components }
586    }
587
588    /// Returns a new, allocated [`array`] representation of the [`Vector`] scalar data.
589    ///
590    /// # Examples
591    ///
592    /// Basic usage:
593    ///
594    /// ```
595    /// # use vectora::types::vector::Vector;
596    /// let v = Vector::<i32, 3>::from(&[1, 2, 3]);
597    /// let mut x: [i32; 3] = v.to_array();
598    ///
599    /// assert_eq!(x, [1, 2, 3]);
600    ///
601    /// x[0] = 10;
602    ///
603    /// assert_eq!(x, [10, 2, 3]);
604    /// # assert_eq!(v[0], 1);
605    /// ```
606    ///
607    /// Note: The edit above returns a new, owned array and
608    /// **does not change** the [`Vector`] data:
609    ///
610    /// ```
611    /// # use vectora::types::vector::Vector;
612    /// # let v = Vector::<u32, 3>::from(&[1, 2, 3]);
613    /// # let mut x: [u32; 3] = v.to_array();
614    /// # assert_eq!(x, [1,2,3]);
615    /// # x[0] = 10;
616    /// # assert_eq!(x, [10, 2, 3]);
617    /// assert_eq!(v[0], 1);
618    /// ```
619    pub fn to_array(&self) -> [T; N] {
620        self.components
621    }
622
623    /// Returns a new, allocated [`Vec`] representation of the [`Vector`] scalar data.
624    ///
625    /// # Examples
626    ///
627    /// Basic usage:
628    ///
629    /// ```
630    /// # use vectora::types::vector::Vector;
631    /// let v = Vector::<i32, 3>::from(&[1, 2, 3]);
632    /// let mut x: Vec<i32> = v.to_vec();
633    ///
634    /// assert_eq!(x, Vec::from([1, 2, 3]));
635    ///
636    /// x[0] = 10;
637    ///
638    /// assert_eq!(x, Vec::from([10, 2, 3]));
639    /// # assert_eq!(v[0], 1);
640    /// ```
641    ///
642    /// Note: The assignment above returns a new, owned [`Vec`] with
643    /// copied data and **does not change** the [`Vector`] data:
644    ///
645    /// ```
646    /// # use vectora::types::vector::Vector;
647    /// # let v = Vector::<u32, 3>::from(&[1, 2, 3]);
648    /// # let mut x: Vec<u32> = v.to_vec();
649    /// # assert_eq!(x, Vec::from([1,2,3]));
650    /// # x[0] = 10;
651    /// # assert_eq!(x, Vec::from([10, 2, 3]));
652    /// assert_eq!(v[0], 1);
653    /// ```
654    pub fn to_vec(&self) -> Vec<T> {
655        Vec::from(self.components)
656    }
657
658    /// Returns the length of the [`Vector`] scalar data.
659    ///
660    /// This value represents the number of scalar data points in
661    /// the [`Vector`].
662    ///
663    /// # Examples
664    ///
665    /// Basic usage:
666    ///
667    /// ```
668    /// # use vectora::types::vector::Vector;
669    /// let v2d: Vector<i32, 2> = Vector::new();
670    ///
671    /// assert_eq!(v2d.len(), 2);
672    ///
673    /// let v3d: Vector<f64, 3> = Vector::new();
674    ///
675    /// assert_eq!(v3d.len(), 3);
676    /// ```
677    pub fn len(&self) -> usize {
678        self.components.len()
679    }
680
681    /// Returns `true` if the [`Vector`] contains no items and `false` otherwise.
682    ///
683    /// # Examples
684    ///
685    /// ```
686    /// # use vectora::types::vector::Vector;
687    /// let v: Vector<i32, 2> = Vector::new();
688    /// let v_empty: Vector<i32, 0> = Vector::new();
689    ///
690    /// assert!(v.len() > 0);
691    /// assert!(!v.is_empty());
692    ///
693    /// assert!(v_empty.len() == 0);
694    /// assert!(v_empty.is_empty());
695    /// ```
696    pub fn is_empty(&self) -> bool {
697        self.components.is_empty()
698    }
699
700    /// Vector addition with mutation of the calling [`Vector`].
701    ///
702    /// Returns a mutable reference to the [`Vector`].
703    ///
704    /// Vector addition with the [`+` operator overload](#impl-Add<Vector<T%2C%20N>>) allocates a new [`Vector`].  This method
705    /// is an alternative that supports in-place vector addition mutation of the calling [`Vector`] with data in the
706    /// parameter [`Vector`].
707    ///
708    /// # Examples
709    ///
710    /// ```
711    /// # use vectora::types::vector::Vector;
712    /// let mut v = Vector::<i32, 3>::from(&[1, 2, 3]);
713    /// let other = Vector::<i32, 3>::from(&[4, 5, 6]);
714    ///
715    /// v.mut_add(&other);
716    ///
717    /// assert_eq!(v[0], 5);
718    /// assert_eq!(v[1], 7);
719    /// assert_eq!(v[2], 9);
720    /// ```
721    pub fn mut_add(&mut self, rhs: &Vector<T, N>) -> &mut Self {
722        self.components.iter_mut().zip(rhs).for_each(|(a, b)| *a = *a + *b);
723
724        self
725    }
726
727    /// Vector subtraction with mutation of the calling [`Vector`].
728    ///
729    /// Returns a mutable reference to the [`Vector`].
730    ///
731    /// Vector subtraction with the [`-` operator overload](#impl-Sub<Vector<T%2C%20N>>) allocates a new [`Vector`].  This method
732    /// is an alternative that supports in-place vector subtraction mutation of the calling [`Vector`] with data in the
733    /// parameter [`Vector`].
734    ///
735    /// # Examples
736    ///
737    /// ```
738    /// # use vectora::types::vector::Vector;
739    /// let mut v = Vector::<i32, 3>::from(&[1, 2, 3]);
740    /// let other = Vector::<i32, 3>::from(&[4, 5, 6]);
741    ///
742    /// v.mut_sub(&other);
743    ///
744    /// assert_eq!(v[0], -3);
745    /// assert_eq!(v[1], -3);
746    /// assert_eq!(v[2], -3);
747    /// ```
748    pub fn mut_sub(&mut self, rhs: &Vector<T, N>) -> &mut Self {
749        self.components.iter_mut().zip(rhs.iter()).for_each(|(a, b)| *a = *a - *b);
750
751        self
752    }
753
754    /// Scalar multiplication with mutation of the calling [`Vector`].
755    ///
756    /// Returns a mutable reference to the [`Vector`].
757    ///
758    /// Scalar multiplication with the [`*` operator overload](#impl-Mul<T>) allocates a
759    /// new [`Vector`].  This method is an alternative that supports in-place scalar
760    /// multiplication mutation of the calling [`Vector`] with a scalar parameter value.
761    ///
762    /// # Examples
763    ///
764    /// ```
765    /// # use vectora::types::vector::Vector;
766    /// let mut v = Vector::<i32, 3>::from(&[1, 2, 3]);
767    ///
768    /// v.mut_mul(4);
769    ///
770    /// assert_eq!(v[0], 4);
771    /// assert_eq!(v[1], 8);
772    /// assert_eq!(v[2], 12);
773    /// ```
774    pub fn mut_mul(&mut self, scale: T) -> &mut Self {
775        self.components.iter_mut().for_each(|a| *a = *a * scale);
776
777        self
778    }
779
780    /// Returns the dot product of two real number [`Vector`] types.
781    ///
782    /// The return value is a scalar with the [`Vector`] numeric
783    /// type.
784    ///
785    /// **Note**: This method is not intended for use with [`Vector`]
786    /// **of** [`num::Complex`] number types.
787    ///
788    ///
789    /// # Examples
790    ///
791    /// Basic usage:
792    ///
793    /// ```
794    /// # use vectora::types::vector::Vector;
795    /// let v1: Vector<i32, 3> = Vector::from([1, 3, -5]);
796    /// let v2: Vector<i32, 3> = Vector::from([4, -2, -1]);
797    ///
798    /// let x1 = v1 * 3;
799    /// let x2 = v2 * 6;
800    ///
801    /// assert_eq!(v1.dot(&v2), 3);
802    /// assert_eq!(v2.dot(&v1), 3);
803    /// assert_eq!(-v1.dot(&-v2), 3);
804    /// assert_eq!(x1.dot(&x2), (3 * 6) * v1.dot(&v2));
805    /// ```
806    pub fn dot(&self, other: &Vector<T, N>) -> T
807    where
808        T: Num + Copy + std::iter::Sum<T> + Sync + Send,
809    {
810        self.components.iter().zip(other.components.iter()).map(|(a, b)| *a * *b).sum()
811    }
812
813    /// Returns the displacement [`Vector`] from a parameter [`Vector`] to the calling [`Vector`].
814    ///
815    /// **Note**: This is an alias for the [`Vector::sub`] vector subtraction
816    /// method and the operation can be performed with the overloaded `-` operator.
817    ///
818    /// # Examples
819    ///
820    /// ```
821    /// # use vectora::types::vector::Vector;
822    /// let to = Vector::<i32, 3>::from([1, 2, 3]);
823    /// let from = Vector::<i32, 3>::from([2, 4, 6]);
824    ///
825    /// let v = to.displacement(&from);
826    ///
827    /// assert_eq!(v[0], -1);
828    /// assert_eq!(v[1], -2);
829    /// assert_eq!(v[2], -3);
830    /// ```
831    pub fn displacement(&self, from: &Vector<T, N>) -> Self {
832        self.sub(*from)
833    }
834
835    /// Mutates a non-zero [`Vector`] in place to one with the same magnitude and opposite direction.
836    ///
837    /// This operation returns a zero vector when the calling vector is a zero vector.
838    ///
839    /// # Examples
840    ///
841    /// Basic usage:
842    ///
843    /// ```
844    /// # use vectora::types::vector::Vector;
845    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
846    ///
847    /// v.mut_opposite();
848    ///
849    /// assert_eq!(v[0], -1);
850    /// assert_eq!(v[1], -2);
851    /// assert_eq!(v[2], -3);
852    /// ```
853    ///
854    /// The zero vector case:
855    ///
856    /// ```
857    /// # use vectora::types::vector::Vector;
858    /// let mut v_zero = Vector::<i32, 3>::zero();
859    ///
860    /// v_zero.mut_opposite();
861    ///
862    /// assert_eq!(v_zero[0], 0);
863    /// assert_eq!(v_zero[1], 0);
864    /// assert_eq!(v_zero[2], 0);
865    /// ```
866    pub fn mut_opposite(&mut self) -> &mut Self {
867        self.components.iter_mut().for_each(|a| *a = T::zero() - *a);
868        self
869    }
870
871    /// Returns a [`Vector`] that is scaled by a given scalar parameter value.
872    ///
873    /// **Note**: This is an alias for the [`Vector::mul`] scalar multiplication
874    /// method and the operation can be performed with the overloaded `*` operator.
875    ///
876    /// # Examples
877    ///
878    /// ```
879    /// # use vectora::types::vector::Vector;
880    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
881    ///
882    /// let v_s = v.scale(10);
883    ///
884    /// assert_eq!(v_s[0], 10);
885    /// assert_eq!(v_s[1], 20);
886    /// assert_eq!(v_s[2], 30);
887    /// ```
888    pub fn scale(&self, scale: T) -> Self {
889        self.mul(scale)
890    }
891
892    /// Scales a [`Vector`] in place by a given scalar parameter value.
893    ///
894    /// # Examples
895    ///
896    /// ```
897    /// # use vectora::types::vector::Vector;
898    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
899    ///
900    /// v.mut_scale(10);
901    ///
902    /// assert_eq!(v[0], 10);
903    /// assert_eq!(v[1], 20);
904    /// assert_eq!(v[2], 30);
905    /// ```
906    pub fn mut_scale(&mut self, scale: T) -> &mut Self {
907        self.mut_mul(scale)
908    }
909
910    /// Returns a translated [`Vector`] with displacement defined by a
911    /// translation [`Vector`] parameter.
912    ///
913    /// **Note**: This is an alias for the [`Vector::add`] vector addition method
914    /// and the operation can be performed with the overloaded `+` operator.
915    ///
916    /// # Examples
917    ///
918    /// ```
919    /// # use vectora::types::vector::Vector;
920    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
921    /// let translation_vec = Vector::<i32, 3>::from([4, 5, 6]);
922    ///
923    /// let v_t = v.translate(&translation_vec);
924    ///
925    /// assert_eq!(v_t[0], 5);
926    /// assert_eq!(v_t[1], 7);
927    /// assert_eq!(v_t[2], 9);
928    /// ```
929    pub fn translate(&self, translation_vector: &Vector<T, N>) -> Self {
930        self.add(*translation_vector)
931    }
932
933    /// Translates a [`Vector`] in place with displacement defined by a
934    /// translation [`Vector`] parameter.
935    ///
936    /// # Examples
937    ///
938    /// ```
939    /// # use vectora::types::vector::Vector;
940    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
941    /// let translation_vec = Vector::<i32, 3>::from([4, 5, 6]);
942    ///
943    /// v.mut_translate(&translation_vec);
944    ///
945    /// assert_eq!(v[0], 5);
946    /// assert_eq!(v[1], 7);
947    /// assert_eq!(v[2], 9);
948    /// ```
949    pub fn mut_translate(&mut self, translation_vector: &Vector<T, N>) -> &mut Self {
950        self.mut_add(translation_vector)
951    }
952
953    /// Returns a new [`Vector`] with scalar data that are modified
954    /// according to the definition in a closure parameter.
955    ///
956    /// **Note**: the closure must return items of the same numeric
957    /// type as the [`Vector`] numeric type.
958    ///
959    /// # Examples
960    ///
961    /// Basic usage:
962    ///
963    /// ```
964    /// # use vectora::types::vector::Vector;
965    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
966    /// let square = |x: i32| { x.pow(2) };
967    ///
968    /// let squared_v = v.map_closure(square);
969    ///
970    /// assert_eq!(squared_v, Vector::from([1, 4, 9]));
971    /// ```
972    pub fn map_closure<U>(&self, closur: U) -> Self
973    where
974        U: Fn(T) -> T,
975    {
976        let mut new_components: [T; N] = [T::zero(); N];
977        self.components.iter().enumerate().for_each(|(i, x)| new_components[i] = closur(*x));
978        Self { components: new_components }
979    }
980
981    /// Mutates the [`Vector`] data in place according to the
982    /// definition in a closure parameter.
983    ///
984    /// **Note**: the closure must return items of the same numeric
985    /// type as the [`Vector`] numeric type.
986    ///
987    /// # Examples
988    ///
989    /// Basic usage:
990    ///
991    /// ```
992    /// # use vectora::types::vector::Vector;
993    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
994    /// let square = |x: i32| { x.pow(2) };
995    ///
996    /// v.mut_map_closure(square);
997    ///
998    /// assert_eq!(v, Vector::from([1, 4, 9]));
999    /// ```
1000    pub fn mut_map_closure<U>(&mut self, mut closur: U) -> &mut Self
1001    where
1002        U: FnMut(T) -> T,
1003    {
1004        self.components.iter_mut().for_each(|x| *x = closur(*x));
1005        self
1006    }
1007
1008    /// Returns a new [`Vector`] with data that are modified
1009    /// according to the definition in a function parameter.
1010    ///
1011    /// **Note**: the function must return items of the same numeric
1012    /// type as the [`Vector`] numeric type.
1013    ///
1014    /// # Examples
1015    ///
1016    /// Basic usage:
1017    ///
1018    /// ```
1019    /// # use vectora::types::vector::Vector;
1020    /// fn square(x: i32) -> i32 {
1021    ///     x.pow(2)
1022    /// }
1023    ///
1024    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
1025    ///
1026    /// let squared_v = v.map_fn(square);
1027    ///
1028    /// assert_eq!(squared_v, Vector::from([1, 4, 9]));
1029    /// ```
1030    pub fn map_fn(&self, func: fn(T) -> T) -> Self {
1031        let mut new_components: [T; N] = [T::zero(); N];
1032        self.components.iter().enumerate().for_each(|(i, x)| new_components[i] = func(*x));
1033        Self { components: new_components }
1034    }
1035
1036    /// Mutates the [`Vector`] data in place according to
1037    /// the definition in a function parameter.
1038    ///
1039    /// **Note**: the function must return items of the same numeric
1040    /// type as the [`Vector`] numeric type.
1041    ///
1042    /// # Examples
1043    ///
1044    /// Basic usage:
1045    ///
1046    /// ```
1047    /// # use vectora::types::vector::Vector;
1048    /// fn square(x: i32) -> i32 {
1049    ///     x.pow(2)
1050    /// }
1051    ///
1052    /// let mut v = Vector::<i32, 3>::from([1, 2, 3]);
1053    ///
1054    /// v.mut_map_fn(square);
1055    ///
1056    /// assert_eq!(v, Vector::from([1, 4, 9]));
1057    /// ```
1058    pub fn mut_map_fn(&mut self, func: fn(T) -> T) -> &mut Self {
1059        self.components.iter_mut().for_each(|x| *x = func(*x));
1060        self
1061    }
1062
1063    /// Returns an iterator that yields a tuple of the index value and [`Vector`] item
1064    /// reference at the corresponding index during iteration.
1065    ///
1066    /// # Examples
1067    ///
1068    /// Basic usage:
1069    ///
1070    /// ```
1071    /// # use vectora::types::vector::Vector;
1072    /// let v = Vector::<i32, 3>::from([10, 20, 30]);
1073    /// let mut iter = v.enumerate();
1074    ///
1075    /// assert_eq!(iter.next(), Some((0, &10)));
1076    /// assert_eq!(iter.next(), Some((1, &20)));
1077    /// assert_eq!(iter.next(), Some((2, &30)));
1078    /// assert_eq!(iter.next(), None);
1079    /// ```
1080    pub fn enumerate(&self) -> impl Iterator<Item = (usize, &T)> {
1081        self.components.iter().enumerate()
1082    }
1083
1084    /// Returns the sum of the [`Vector`] elements.
1085    ///
1086    /// **Note**: An empty [`Vector`] returns the zero value of the contained numeric type.
1087    ///
1088    /// # Examples
1089    ///
1090    /// Basic usage:
1091    ///
1092    /// ```
1093    /// # use vectora::types::vector::Vector;
1094    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
1095    ///
1096    /// assert_eq!(v.sum(), 6);
1097    /// ```
1098    pub fn sum(&self) -> T {
1099        self.components.iter().fold(T::zero(), |a, b| a + *b)
1100    }
1101
1102    /// Returns the product of the [`Vector`] elements.
1103    ///
1104    /// **Note**:
1105    ///
1106    /// - An empty [`Vector`] returns the zero value of the contained numeric type.
1107    /// - A 1-dimensional [`Vector`] returns the index 0 value contained in the [`Vector`]
1108    ///
1109    /// # Examples
1110    ///
1111    /// ```
1112    /// # use vectora::types::vector::Vector;
1113    /// let v = Vector::<i32, 3>::from([4, 5, 6]);
1114    ///
1115    /// assert_eq!(v.product(), 120);
1116    /// ```
1117    pub fn product(&self) -> T {
1118        if self.components.is_empty() {
1119            T::zero()
1120        } else if self.components.len() == 1 {
1121            self[0]
1122        } else {
1123            self.components.iter().skip(1).fold(self[0], |a, b| a * *b)
1124        }
1125    }
1126
1127    /// Returns the minimum scalar value in a [`Vector`].
1128    ///
1129    /// Returns `None` if the [`Vector`] is empty.
1130    ///
1131    /// # Examples
1132    ///
1133    /// ```
1134    /// # use vectora::types::vector::Vector;
1135    /// let v = Vector::<i32, 3>::from([4, 5, 6]);
1136    ///
1137    /// assert_eq!(v.min().unwrap(), 4);
1138    /// ```
1139    ///
1140    /// See [`Vector::min_fp`] for minimum floating point scalars.
1141    pub fn min(&self) -> Option<T>
1142    where
1143        T: Num + Copy + Sync + Send + std::cmp::Ord,
1144    {
1145        self.components.iter().copied().min()
1146    }
1147
1148    /// Returns the maximum scalar value in a [`Vector`].
1149    ///
1150    /// Returns `None` if the [`Vector`] is empty.
1151    ///
1152    /// # Examples
1153    ///
1154    /// ```
1155    /// # use vectora::types::vector::Vector;
1156    /// let v = Vector::<i32, 3>::from([4, 5, 6]);
1157    ///
1158    /// assert_eq!(v.max().unwrap(), 6);
1159    /// ```
1160    ///
1161    /// See [`Vector::max_fp`] for maximum floating point scalars.
1162    pub fn max(&self) -> Option<T>
1163    where
1164        T: Num + Copy + Sync + Send + std::cmp::Ord,
1165    {
1166        self.components.iter().copied().max()
1167    }
1168}
1169
1170impl<T, const N: usize> Vector<T, N>
1171where
1172    T: Num + Neg<Output = T> + Default + Copy + Sync + Send,
1173{
1174    /// Returns a [`Vector`] with the same magnitude and opposite direction for
1175    /// a non-zero [`Vector`].
1176    ///
1177    /// This operation does not change zero vectors.
1178    ///
1179    /// **Note**: This is an alias for the unary [`Vector::neg`] operation
1180    /// and can be performed with the overloaded unary `-` operator.
1181    ///
1182    /// # Examples
1183    ///
1184    /// Basic usage:
1185    ///
1186    /// ```
1187    /// # use vectora::types::vector::Vector;
1188    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
1189    /// let v_o = v.opposite();
1190    ///
1191    /// assert_eq!(v_o[0], -1);
1192    /// assert_eq!(v_o[1], -2);
1193    /// assert_eq!(v_o[2], -3);
1194    /// assert_eq!(v + v_o, Vector::zero());
1195    /// ```
1196    ///
1197    /// The zero vector case:
1198    ///
1199    /// ```
1200    /// # use vectora::types::vector::Vector;
1201    /// let v_zero = Vector::<i32, 3>::zero();
1202    /// let v_zero_o = v_zero.opposite();
1203    ///
1204    /// assert_eq!(v_zero_o, v_zero);
1205    /// ```
1206    pub fn opposite(&self) -> Self {
1207        -*self
1208    }
1209}
1210
1211// ================================
1212//
1213// Numeric type specific methods
1214//
1215// ================================
1216impl<T, const N: usize> Vector<T, N>
1217where
1218    T: Float + Copy + Sync + Send + Sum,
1219{
1220    /// Returns the magnitude of the displacement vector between the
1221    /// calling real, floating point number [`Vector`] and a real, floating
1222    /// point number [`Vector`] parameter.
1223    ///
1224    /// # Examples
1225    ///
1226    /// Basic usage:
1227    ///
1228    /// ```
1229    ///# use vectora::types::vector::Vector;
1230    /// use approx::assert_relative_eq;
1231    ///
1232    /// let v1: Vector<f64, 2> = Vector::from([2.0, 2.0]);
1233    /// let v2: Vector<f64, 2> = Vector::from([4.0, 4.0]);
1234    ///
1235    /// assert_relative_eq!(v1.distance(&v2), 8.0_f64.sqrt());
1236    /// assert_relative_eq!(v1.distance(&v1), 0.0_f64);
1237    /// ```
1238    ///
1239    /// This method supports floating point [`Vector`] types only. Please
1240    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1241    /// documentation for details on casting to floating point types.
1242    pub fn distance(&self, other: &Vector<T, N>) -> T {
1243        (*self - *other).magnitude()
1244    }
1245
1246    /// Returns the linear interpolant between a real, floating point number [`Vector`] and a
1247    /// parameter [`Vector`] given a parametric line equation `weight` parameter.
1248    ///
1249    /// Calculated with the parametric line equation `(1 - t)A + tB`
1250    /// where `A` is the start vector, `B` is the end vector, and `t` is the weight.
1251    ///
1252    /// The `weight` parameter must be in the closed interval [0.0, 1.0].
1253    ///
1254    /// # Errors
1255    ///
1256    /// This method does not support extrapolation.  [`VectorError::ValueError`]
1257    /// is raised if the `weight` parameter is not in the closed interval [0.0, 1.0].
1258    ///
1259    /// # Examples
1260    ///
1261    /// Basic usage:
1262    ///
1263    /// ```
1264    /// # use vectora::types::vector::Vector;
1265    /// let v1: Vector<f64, 2> = Vector::from([0.0, 0.0]);
1266    /// let v2: Vector<f64, 2> = Vector::from([10.0, 10.0]);
1267    ///
1268    /// assert_eq!(v1.lerp(&v2, 0.0).unwrap(), Vector::from([0.0, 0.0]));
1269    /// assert_eq!(v1.lerp(&v2, 0.25).unwrap(), Vector::from([2.5, 2.5]));
1270    /// assert_eq!(v1.lerp(&v2, 0.5).unwrap(), Vector::from([5.0, 5.0]));
1271    /// assert_eq!(v1.lerp(&v2, 0.75).unwrap(), Vector::from([7.5, 7.5]));
1272    /// assert_eq!(v1.lerp(&v2, 1.0).unwrap(), Vector::from([10.0, 10.0]));
1273    /// ```
1274    ///
1275    /// This method supports floating point [`Vector`] types only. Please
1276    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1277    /// documentation for details on casting to floating point types.
1278    pub fn lerp(&self, end: &Vector<T, N>, weight: T) -> Result<Self, VectorError>
1279    where
1280        T: std::fmt::Debug,
1281    {
1282        // weight bounds check
1283        if weight > T::one() || weight < T::zero() {
1284            return Err(VectorError::ValueError(format!(
1285                "invalid interpolation weight request. The weight must be in the closed interval [0,1]. Received '{:?}'",
1286                weight
1287            )));
1288        }
1289
1290        // weight bounds check for NaN
1291        if weight.is_nan() {
1292            return Err(VectorError::ValueError(
1293                "invalid interpolation weight request. The weight must be in the closed interval [0,1]. Received NaN.".to_string(),
1294            ));
1295        }
1296        // if the vectors are the same, always return the start vector (== end vector)
1297        // no calculation is required
1298        if self.components == end.components {
1299            return Ok(Self { components: self.components });
1300        }
1301
1302        Ok(self.lerp_impl(end, weight))
1303    }
1304
1305    /// Returns the midpoint between a real, floating point number [`Vector`] and a parameter [`Vector`].
1306    ///
1307    /// This vector is defined as the [linear interpolant](#method.lerp) with `weight` = 0.5.
1308    ///
1309    /// # Examples
1310    ///
1311    /// Basic usage:
1312    ///
1313    /// ```
1314    /// # use vectora::types::vector::Vector;
1315    ///
1316    /// let v1: Vector<f64, 2> = Vector::from([0.0, 0.0]);
1317    /// let v2: Vector<f64, 2> = Vector::from([10.0, 10.0]);
1318    ///
1319    /// let mid = v1.midpoint(&v2);
1320    ///
1321    /// assert_eq!(mid, Vector::from([5.0, 5.0]));
1322    /// ```
1323    ///
1324    /// This method supports floating point [`Vector`] types only. Please
1325    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1326    /// documentation for details on casting to floating point types.
1327    pub fn midpoint(&self, end: &Vector<T, N>) -> Self
1328    where
1329        T: std::fmt::Debug,
1330    {
1331        // we don't need the bounds checks on weight because it has
1332        // an explicit, valid definition here.  Ok to use `lerp_impl`
1333        // directly.
1334        self.lerp_impl(end, num::cast(0.5).unwrap())
1335    }
1336
1337    /// Returns the vector magnitude for a real, floating point number [`Vector`].
1338    ///
1339    /// # Examples
1340    ///
1341    /// Basic usage:
1342    ///
1343    /// ```
1344    /// # use vectora::types::vector::Vector;
1345    /// use approx::assert_relative_eq;
1346    ///
1347    /// let v1: Vector<f64, 2> = Vector::from([2.8, 2.6]);
1348    /// let v2: Vector<f64, 2> = Vector::from([-2.8, -2.6]);
1349    /// let v_zero: Vector<f64, 2> = Vector::zero();
1350    ///
1351    /// assert_relative_eq!(v1.magnitude(), 3.82099463490856);
1352    /// assert_relative_eq!(v2.magnitude(), 3.82099463490856);
1353    /// assert_relative_eq!(v_zero.magnitude(), 0.0);
1354    /// ```
1355    ///
1356    /// This method supports floating point [`Vector`] types only. Please
1357    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1358    /// documentation for details on casting to floating point types.
1359    pub fn magnitude(&self) -> T {
1360        let x: T = self.components.iter().map(|a| *a * *a).sum();
1361        x.sqrt()
1362    }
1363
1364    /// Returns a new, normalized unit [`Vector`] from a real,
1365    /// floating point number calling [`Vector`].
1366    ///
1367    /// # Examples
1368    ///
1369    /// ```
1370    /// # use vectora::types::vector::Vector;
1371    /// use approx::assert_relative_eq;
1372    ///
1373    /// let v: Vector<f64, 2> = Vector::from([25.123, 30.456]);
1374    ///
1375    /// assert_relative_eq!(v.normalize().magnitude(), 1.0);
1376    /// assert_relative_eq!(v[0], 25.123);
1377    /// assert_relative_eq!(v[1], 30.456);
1378    /// ```
1379    ///
1380    /// This method supports floating point [`Vector`] types only. Please
1381    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1382    /// documentation for details on casting to floating point types.
1383    pub fn normalize(&self) -> Self
1384    where
1385        T: Float + Copy + Sync + Send + Sum,
1386    {
1387        let mut new_components = [T::zero(); N];
1388        let this_magnitude = self.magnitude();
1389
1390        self.components
1391            .iter()
1392            .enumerate()
1393            .for_each(|(i, a)| new_components[i] = *a / this_magnitude);
1394
1395        Self { components: new_components }
1396    }
1397
1398    /// Normalizes a real, floating point number [`Vector`] to a unit [`Vector`] in place.
1399    ///
1400    /// # Examples
1401    ///
1402    /// ```
1403    /// # use vectora::types::vector::Vector;
1404    /// use approx::assert_relative_eq;
1405    ///
1406    /// let mut v: Vector<f64, 2> = Vector::from([25.123, 30.456]);
1407    ///
1408    /// v.mut_normalize();
1409    ///
1410    /// assert_relative_eq!(v.magnitude(), 1.0);
1411    /// assert_relative_eq!(v[0], 0.6363347262144607);
1412    /// assert_relative_eq!(v[1], 0.7714130645857428);
1413    /// ```
1414    ///
1415    /// This method supports floating point [`Vector`] types only. Please
1416    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1417    /// documentation for details on casting to floating point types.
1418    pub fn mut_normalize(&mut self) -> &mut Self
1419    where
1420        T: Float + Copy + Sync + Send + Sum,
1421    {
1422        let this_magnitude = self.magnitude();
1423        self.components.iter_mut().for_each(|a| *a = *a / this_magnitude);
1424        self
1425    }
1426
1427    /// Returns the element-wise arithmetic mean for a floating point [`Vector`].
1428    ///
1429    /// # Errors
1430    ///
1431    /// Returns [`VectorError::EmptyVectorError`] when a [`Vector`] is empty.
1432    ///
1433    /// # Examples
1434    ///
1435    /// Basic usage:
1436    ///
1437    /// ```
1438    /// # use vectora::types::vector::Vector;
1439    /// use approx::assert_relative_eq;
1440    ///
1441    /// let v: Vector<f64, 5> = Vector::from([1.0, 2.0, 3.0, 4.0, 5.0]);
1442    ///
1443    /// assert_relative_eq!(v.mean().unwrap(), 3.0);
1444    /// ```
1445    ///
1446    /// This method supports floating point [`Vector`] types only. Please
1447    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1448    /// documentation for details on casting to floating point types.
1449    pub fn mean(&self) -> Result<T, VectorError>
1450    where
1451        T: Float + Copy + Sync + Send + Sum<T>,
1452    {
1453        if self.is_empty() {
1454            Err(VectorError::EmptyVectorError(
1455                "expected a Vector with data and received an empty Vector".to_string(),
1456            ))
1457        } else {
1458            // this should be safe to unwrap because we have a fixed definition
1459            // for acceptable type casts from primitive usize to primitive f32 and f64 types
1460            let length = T::from(self.len()).unwrap();
1461            Ok((self.components.iter().copied().sum::<T>()) / length)
1462        }
1463    }
1464
1465    /// Returns the element-wise geometric mean for a floating point [`Vector`] of values
1466    /// greater than or equal to zero.
1467    ///
1468    /// **Note**: [`Vector`] that contain any number of zero values will always return a
1469    /// geometric mean of zero.  [`Vector`] that contain any number of negative values will always
1470    /// return `T::NAN`.
1471    ///
1472    /// # Errors
1473    ///
1474    /// Returns [`VectorError::EmptyVectorError`] when a [`Vector`] is empty.
1475    ///
1476    /// # Examples
1477    ///
1478    /// Basic usage:
1479    ///
1480    /// ```
1481    /// # use vectora::types::vector::Vector;
1482    /// use approx::assert_relative_eq;
1483    ///
1484    /// let v: Vector<f64, 5> = Vector::from([4.0, 36.0, 45.0, 50.0, 75.0]);
1485    ///
1486    /// assert_relative_eq!(v.mean_geo().unwrap(), 30.0);
1487    /// ```
1488    ///
1489    /// This method supports floating point [`Vector`] types only. Please
1490    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1491    /// documentation for details on casting to floating point types.
1492    pub fn mean_geo(&self) -> Result<T, VectorError>
1493    where
1494        T: Float + Copy + Sync + Send + Sum<T>,
1495    {
1496        if self.is_empty() {
1497            Err(VectorError::EmptyVectorError(
1498                "expected a Vector with data and received an empty Vector".to_string(),
1499            ))
1500        } else {
1501            // this should be safe to unwrap because we have a fixed definition
1502            // for acceptable type casts from primitive usize to primitive f32 and f64 types
1503            let length = T::from(self.len()).unwrap();
1504            // note: this uses the sum of natural logs approach to reduce the likelihood of overflows
1505            // with the product method
1506            Ok(((self.components.iter().copied().map(|x| x.ln()).sum::<T>()) / length).exp())
1507        }
1508    }
1509
1510    /// Returns the element-wise harmonic mean for a floating point [`Vector`] of values
1511    /// greater than zero.
1512    ///
1513    /// # Errors
1514    ///
1515    /// Returns [`VectorError::ValueError`] when a [`Vector`] contains the value zero
1516    /// or negative values.  Returns [`VectorError::EmptyVectorError`] when a [`Vector`]
1517    /// is empty.
1518    ///
1519    /// # Examples
1520    ///
1521    /// Basic usage:
1522    ///
1523    /// ```
1524    /// # use vectora::types::vector::Vector;
1525    /// use approx::assert_relative_eq;
1526    ///
1527    /// let v: Vector<f64, 5> = Vector::from([1.0, 2.0, 3.0, 4.0, 5.0]);
1528    ///
1529    /// assert_relative_eq!(v.mean_harmonic().unwrap(), 2.18978102189781);
1530    /// ```
1531    ///
1532    /// This method supports floating point [`Vector`] types only. Please
1533    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1534    /// documentation for details on casting to floating point types.
1535    pub fn mean_harmonic(&self) -> Result<T, VectorError>
1536    where
1537        T: Float + Copy + Sync + Send + Sum<T> + std::fmt::Debug,
1538    {
1539        if self.is_empty() {
1540            Err(VectorError::EmptyVectorError(
1541                "expected a Vector with data and received an empty Vector".to_string(),
1542            ))
1543        } else {
1544            // this should be safe to unwrap because we have a fixed definition
1545            // for acceptable type casts from primitive usize to primitive f32 and f64 types
1546            let length = T::from(self.len()).unwrap();
1547
1548            // the unchecked version of the sum of reciprocals approach is commented out below:
1549            // let sum_of_reciprocal = self.components.iter().copied().map(|x| x.powi(-1)).sum::<T>();
1550            let mut err = Ok(());
1551            let sum_of_reciprocal = self
1552                .components
1553                .iter()
1554                .copied()
1555                .map(|x| {
1556                    if x.is_sign_negative() || x.is_zero() {
1557                        Err(VectorError::ValueError(format!(
1558                            "found invalid value less than or equal to zero: {:?}",
1559                            x,
1560                        )))
1561                    } else {
1562                        Ok(x)
1563                    }
1564                })
1565                .scan(&mut err, |err, res| match res {
1566                    Ok(x) => Some(x),
1567                    Err(e) => {
1568                        **err = Err(e);
1569                        None
1570                    }
1571                })
1572                .map(|x| x.powi(-1))
1573                .sum::<T>();
1574
1575            // propagate the error if a value <= 0.0 was in the data set
1576            err?;
1577            Ok(length / sum_of_reciprocal)
1578        }
1579    }
1580
1581    /// Returns the element-wise median value for a floating point [`Vector`].
1582    ///
1583    /// This implementation identifies the median with the quickselect algorithm
1584    /// defined in the standard library [`slice::select_nth_unstable_by`] method.
1585    /// This quickselect implementation has O(n) worst-case run time.
1586    ///
1587    /// # Errors
1588    ///
1589    /// Returns a [`VectorError::EmptyVectorError`] when a [`Vector`] is empty.
1590    ///
1591    /// # Panics
1592    ///
1593    /// Panics if the data include [`f32::NAN`] or [`f64::NAN`].
1594    ///
1595    /// # Examples
1596    ///
1597    /// Basic usage:
1598    ///
1599    /// ```
1600    /// # use vectora::types::vector::Vector;
1601    /// use approx::assert_relative_eq;
1602    ///
1603    /// let v1: Vector<f64, 9> = Vector::from([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]);
1604    ///
1605    /// assert_relative_eq!(v1.median().unwrap(), 5.0);
1606    ///
1607    /// let v2: Vector<f64, 10> = Vector::from([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]);
1608    ///
1609    /// assert_relative_eq!(v2.median().unwrap(), 5.5);
1610    /// ```
1611    ///
1612    /// **Note**: Returns `T::NAN` if the median value is the arithmetic average of `T::INFINITY`
1613    /// and `T::NEG_INFINITY` (e.g., the data set `[f64::NEG_INFINITY, f64::NEG_INFINITY, f64::INFINITY, f64::INFINITY]`);
1614    ///
1615    /// This method supports floating point [`Vector`] types only. Please
1616    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1617    /// documentation for details on casting to floating point types.
1618    pub fn median(&self) -> Result<T, VectorError>
1619    where
1620        T: Float + Copy + Sync + Send + approx::RelativeEq + std::fmt::Debug,
1621    {
1622        if self.is_empty() {
1623            Err(VectorError::EmptyVectorError(
1624                "expected a Vector with data and received an empty Vector".to_string(),
1625            ))
1626        } else {
1627            let length = self.len();
1628            let even = length % 2 == 0;
1629
1630            if even {
1631                let mut data_copy_1 = self.components;
1632                let mut data_copy_2 = self.components;
1633                let median_left = data_copy_1
1634                    .select_nth_unstable_by((length / 2) - 1, |a, b| self.rel_eq_cmp(a, b))
1635                    .1;
1636                let median_right =
1637                    data_copy_2.select_nth_unstable_by(length / 2, |a, b| self.rel_eq_cmp(a, b)).1;
1638                // take the arithmetic average of the two ordered middle values
1639                Ok((*median_left + *median_right) / T::from(2.0).unwrap())
1640            } else {
1641                let mut data_copy = self.components;
1642                Ok(*data_copy.select_nth_unstable_by(length / 2, |a, b| self.rel_eq_cmp(a, b)).1)
1643            }
1644        }
1645    }
1646
1647    /// Returns the element-wise variance for a floating point [`Vector`] containing
1648    /// finite values, given a `ddof` delta degrees of freedom bias correction factor.
1649    ///
1650    /// # Errors
1651    ///
1652    /// Returns [`VectorError::ValueError`] if the `ddof` parameter is negative or has a value
1653    /// greater than the [`Vector`] length.  Returns [`VectorError::EmptyVectorError`] if the
1654    /// [`Vector`] is empty.
1655    ///
1656    /// # Examples
1657    ///
1658    /// Basic usage:
1659    ///
1660    /// ## Population variance
1661    ///
1662    /// ```
1663    /// # use vectora::types::vector::Vector;
1664    /// use approx::assert_relative_eq;
1665    ///
1666    /// let v: Vector<f64, 5> = Vector::from([5.0, 11.0, 20.0, 31.0, 100.0]);
1667    ///
1668    /// assert_relative_eq!(v.variance(0.0).unwrap(), 1185.84);
1669    /// ```
1670    ///
1671    /// ## Sample variance
1672    ///
1673    /// With [Bessel's correction](https://en.wikipedia.org/wiki/Bessel%27s_correction) for the bias
1674    /// in estimation of the population variance.
1675    ///
1676    /// ```
1677    /// # use vectora::types::vector::Vector;
1678    /// use approx::assert_relative_eq;
1679    ///
1680    /// let v: Vector<f64, 5> = Vector::from([5.0, 11.0, 20.0, 31.0, 100.0]);
1681    ///
1682    /// assert_relative_eq!(v.variance(1.0).unwrap(), 1482.3);
1683    /// ```
1684    ///
1685    /// This method supports floating point [`Vector`] types only. Please
1686    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1687    /// documentation for details on casting to floating point types.
1688    pub fn variance(&self, ddof: T) -> Result<T, VectorError>
1689    where
1690        T: Float + Copy + Sync + Send + std::fmt::Debug,
1691    {
1692        if self.is_empty() {
1693            Err(VectorError::EmptyVectorError(
1694                "expected a Vector with data and received an empty Vector".to_string(),
1695            ))
1696        } else if ddof.is_sign_negative() || ddof > T::from(self.len()).unwrap() {
1697            Err(VectorError::ValueError(format!(
1698                "ddof parameter must have a value greater than or equal to zero and must not be larger than the Vector length, received '{:?}'",
1699                ddof
1700            )))
1701        } else {
1702            Ok(self.variance_impl(ddof))
1703        }
1704    }
1705
1706    /// Returns the element-wise standard deviation for a floating point [`Vector`]
1707    /// containing finite values, given a `ddof` delta degrees of freedom bias correction
1708    /// factor.
1709    ///
1710    /// /// # Errors
1711    ///
1712    /// Returns [`VectorError::ValueError`] if the `ddof` parameter is negative or has a value
1713    /// greater than the [`Vector`] length.  Returns [`VectorError::EmptyVectorError`] if the
1714    /// [`Vector`] is empty.
1715    ///
1716    /// # Examples
1717    ///
1718    /// Basic usage:
1719    ///
1720    /// ## Population standard deviation
1721    ///
1722    /// ```
1723    /// # use vectora::types::vector::Vector;
1724    /// use approx::assert_relative_eq;
1725    ///
1726    /// let v: Vector<f64, 5> = Vector::from([5.0, 11.0, 20.0, 31.0, 100.0]);
1727    ///
1728    /// assert_relative_eq!(v.stddev(0.0).unwrap(), 34.43602764547618);
1729    /// ```
1730    ///
1731    /// ## Sample standard deviation
1732    ///
1733    /// With [Bessel's correction](https://en.wikipedia.org/wiki/Bessel%27s_correction) for the bias
1734    /// in estimation of the population variance.
1735    ///
1736    /// ```
1737    /// # use vectora::types::vector::Vector;
1738    /// use approx::assert_relative_eq;
1739    ///
1740    /// let v: Vector<f64, 5> = Vector::from([5.0, 11.0, 20.0, 31.0, 100.0]);
1741    ///
1742    /// assert_relative_eq!(v.stddev(1.0).unwrap(), 38.500649345173386);
1743    /// ```
1744    ///
1745    /// This method supports floating point [`Vector`] types only. Please
1746    /// see the [Numeric Type Casts](../../index.html#numeric-type-casts)
1747    /// documentation for details on casting to floating point types.
1748    pub fn stddev(&self, ddof: T) -> Result<T, VectorError>
1749    where
1750        T: Float + Copy + Sync + Send + std::fmt::Debug,
1751    {
1752        if self.is_empty() {
1753            Err(VectorError::EmptyVectorError(
1754                "expected a Vector with data and received an empty Vector".to_string(),
1755            ))
1756        } else if ddof.is_sign_negative() || ddof > T::from(self.len()).unwrap() {
1757            Err(VectorError::ValueError(format!(
1758                "ddof parameter must have a value greater than or equal to zero and must not be larger than the Vector length, received '{:?}'",
1759                ddof
1760            )))
1761        } else {
1762            Ok(self.variance_impl(ddof).sqrt())
1763        }
1764    }
1765
1766    /// Returns the minimum scalar value in a floating point [`Vector`].
1767    ///
1768    /// Returns `None` if the [`Vector`] is empty.
1769    ///
1770    /// # Examples
1771    ///
1772    /// ```
1773    /// # use vectora::types::vector::Vector;
1774    /// use approx::assert_relative_eq;
1775    ///
1776    /// let v = Vector::<f64, 3>::from([4.0, 5.0, 6.0]);
1777    ///
1778    /// assert_relative_eq!(v.min_fp().unwrap(), 4.0);
1779    /// ```
1780    ///
1781    /// See [`Vector::min`] for minimum integer scalars.
1782    pub fn min_fp(&self) -> Option<T> {
1783        self.components.iter().copied().reduce(T::min)
1784    }
1785
1786    /// Returns the maximum scalar value in a floating point [`Vector`].
1787    ///
1788    /// Returns `None` if the [`Vector`] is empty.
1789    ///
1790    /// # Examples
1791    ///
1792    /// ```
1793    /// # use vectora::types::vector::Vector;
1794    /// use approx::assert_relative_eq;
1795    ///
1796    /// let v = Vector::<f64, 3>::from([4.0, 5.0, 6.0]);
1797    ///
1798    /// assert_relative_eq!(v.max_fp().unwrap(), 6.0);
1799    /// ```
1800    ///
1801    /// See [`Vector::max`] for maximum integer scalars.
1802    pub fn max_fp(&self) -> Option<T> {
1803        self.components.iter().copied().reduce(T::max)
1804    }
1805
1806    // ================================
1807    //
1808    // Private methods
1809    //
1810    // ================================
1811
1812    // Vector linear interpolation implementation
1813    fn lerp_impl(&self, end: &Vector<T, N>, weight: T) -> Self {
1814        let mut new_components = [T::zero(); N];
1815        self.components
1816            .iter()
1817            .zip(end.components.iter())
1818            .map(|(a, b)| ((T::one() - weight) * *a) + (weight * *b))
1819            .enumerate()
1820            .for_each(|(i, a)| new_components[i] = a);
1821
1822        Self { components: new_components }
1823    }
1824
1825    // Floating point type : floating point type relative equivalence relation
1826    // order comparison implementation
1827    fn rel_eq_cmp<F>(&self, x: &F, y: &F) -> Ordering
1828    where
1829        F: Float + approx::RelativeEq + std::fmt::Debug,
1830    {
1831        if Relative::default().eq(x, y) {
1832            Ordering::Equal
1833        } else if x < y {
1834            Ordering::Less
1835        } else if x > y {
1836            Ordering::Greater
1837        } else {
1838            panic!("unable to determine order of {:?} and {:?}", x, y);
1839        }
1840    }
1841
1842    // Element-wise variance implementation given `ddof` population variance estimation
1843    // bias correction factor.
1844    //
1845    // Based on the ndarray crate `var` method implementation:
1846    // https://docs.rs/ndarray/0.15.4/ndarray/struct.ArrayBase.html#method.var
1847    // under [Apache License v2.0](https://github.com/rust-ndarray/ndarray/blob/master/LICENSE-APACHE)
1848    //
1849    // This implementation uses the [Welford one-pass algorithm](https://www.jstor.org/stable/1266577).
1850    fn variance_impl(&self, ddof: T) -> T {
1851        let bias_correction = T::from(self.len()).unwrap() - ddof;
1852        let mut mean = T::zero();
1853        let mut sum_of_squares = T::zero();
1854        self.iter().enumerate().for_each(|(i, &x)| {
1855            let delta = x - mean;
1856            mean = mean + delta / T::from(i + 1).unwrap();
1857            sum_of_squares = (x - mean).mul_add(delta, sum_of_squares);
1858        });
1859
1860        sum_of_squares / bias_correction
1861    }
1862}
1863
1864// ================================
1865//
1866// Index / IndexMut trait impl
1867//
1868// ================================
1869impl<I, T, const N: usize> Index<I> for Vector<T, N>
1870where
1871    I: SliceIndex<[T]>,
1872    T: Num + Copy + Sync + Send,
1873{
1874    type Output = I::Output;
1875    /// Returns [`Vector`] scalar data values by zero-based index.
1876    ///
1877    /// # Examples
1878    ///
1879    /// Indexing:
1880    ///
1881    /// ```
1882    /// # use vectora::types::vector::Vector;
1883    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
1884    ///
1885    /// assert_eq!(v[0], 1);
1886    /// assert_eq!(v[1], 2);
1887    /// assert_eq!(v[2], 3);
1888    /// ```
1889    ///
1890    /// Slicing:
1891    ///
1892    /// ```
1893    /// # use vectora::types::vector::Vector;
1894    /// let v = Vector::<i32, 3>::from([1, 2, 3]);
1895    ///
1896    /// let v_slice = &v[..];
1897    ///
1898    /// assert_eq!(v_slice, [1, 2, 3]);
1899    /// ```
1900    ///
1901    fn index(&self, i: I) -> &Self::Output {
1902        &self.components[i]
1903    }
1904}
1905
1906impl<T, const N: usize> IndexMut<usize> for Vector<T, N>
1907where
1908    T: Num + Copy + Sync + Send,
1909{
1910    /// Returns mutable [`Vector`] scalar data values by zero-based index.
1911    ///
1912    /// Supports scalar value assignment by index.
1913    ///
1914    /// # Examples
1915    ///
1916    /// Basic usage:
1917    ///
1918    /// ```
1919    /// # use vectora::types::vector::Vector;
1920    /// let mut v = Vector::<i32, 3>::from(&[1, 2, 3]);
1921    ///
1922    /// assert_eq!(v[0], 1);
1923    /// assert_eq!(v[1], 2);
1924    /// assert_eq!(v[2], 3);
1925    ///
1926    /// v[0] = 5;
1927    /// v[1] = 6;
1928    ///
1929    /// assert_eq!(v[0], 5);
1930    /// assert_eq!(v[1], 6);
1931    /// assert_eq!(v[2], 3);
1932    /// ```
1933    fn index_mut(&mut self, i: usize) -> &mut T {
1934        &mut self.components[i]
1935    }
1936}
1937
1938// ================================
1939//
1940// Iter / IntoIterator trait impl
1941//
1942// ================================
1943
1944impl<T, const N: usize> IntoIterator for Vector<T, N>
1945where
1946    T: Num + Copy + Sync + Send,
1947{
1948    type Item = T;
1949    type IntoIter = std::array::IntoIter<Self::Item, N>;
1950
1951    /// Creates a consuming iterator that iterates over scalar data by value.
1952    fn into_iter(self) -> Self::IntoIter {
1953        self.components.into_iter()
1954    }
1955}
1956
1957impl<'a, T, const N: usize> IntoIterator for &'a Vector<T, N>
1958where
1959    T: Num + Copy + Sync + Send,
1960{
1961    type Item = &'a T;
1962    type IntoIter = std::slice::Iter<'a, T>;
1963
1964    /// Creates an iterator over immutable scalar data references.
1965    fn into_iter(self) -> Self::IntoIter {
1966        self.components.iter()
1967    }
1968}
1969
1970impl<'a, T, const N: usize> IntoIterator for &'a mut Vector<T, N>
1971where
1972    T: Num + Copy + Sync + Send,
1973{
1974    type Item = &'a mut T;
1975    type IntoIter = std::slice::IterMut<'a, T>;
1976
1977    /// Creates an iterator over mutable scalar data references.
1978    fn into_iter(self) -> Self::IntoIter {
1979        self.components.iter_mut()
1980    }
1981}
1982
1983// ================================
1984//
1985// FromIterator trait impl
1986//
1987// ================================
1988
1989impl<T, const N: usize> FromIterator<T> for Vector<T, N>
1990where
1991    T: Num + Copy + Default + Sync + Send,
1992{
1993    /// FromIterator trait implementation with support for `collect`.
1994    ///
1995    /// # Important
1996    ///
1997    /// This implementation is designed to be permissive across iterables
1998    /// with lengths that differ from the requested [`Vector`] length. The
1999    /// approaches to underflow and overflow are:
2000    ///
2001    /// - On underflow: take all items in the iterator and fill subsequent
2002    /// undefined data components with the default value for the numeric type
2003    /// (`T::default`)
2004    /// - On overflow: truncate data after the first N items in the iterator
2005    ///
2006    /// # Examples
2007    ///
2008    /// Basic usage:
2009    ///
2010    /// ```
2011    /// # use vectora::types::vector::Vector;
2012    /// let v: Vector<i32, 3> = [1, 2, 3].into_iter().collect();
2013    ///
2014    /// assert_eq!(v.len(), 3);
2015    /// assert_eq!(v[0], 1 as i32);
2016    /// assert_eq!(v[1], 2 as i32);
2017    /// assert_eq!(v[2], 3 as i32);
2018    /// ```
2019    ///
2020    /// ## Overflow Example
2021    ///
2022    /// Three dimensional data used to instantiate a two dimensional
2023    /// [`Vector`] results in truncation.
2024    ///
2025    /// ```
2026    /// # use vectora::types::vector::Vector;
2027    /// let v: Vector<i32, 2> = [1, 2, 3].into_iter().collect();
2028    ///
2029    /// assert_eq!(v.len(), 2);
2030    /// assert_eq!(v[0], 1 as i32);
2031    /// assert_eq!(v[1], 2 as i32);
2032    /// ```
2033    ///
2034    /// ## Underflow Example
2035    ///
2036    /// Two dimensional data used to instantiate a three dimensional
2037    /// [`Vector`] results in a default numeric type value fill for
2038    /// the undefined final component.
2039    ///
2040    /// ```
2041    /// # use vectora::types::vector::Vector;
2042    /// let v: Vector<i32, 3> = [1, 2].into_iter().collect();
2043    ///
2044    /// assert_eq!(v.len(), 3);
2045    /// assert_eq!(v[0], 1 as i32);
2046    /// assert_eq!(v[1], 2 as i32);
2047    /// assert_eq!(v[2], 0 as i32);
2048    /// ```
2049    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Vector<T, N> {
2050        let mut newvec = Vector::<T, N>::new();
2051        let mut it = iter.into_iter();
2052        // n.b. *Truncation on overflows*
2053        // We take a maximum of N items from the iterator.
2054        // This results in truncation on overflow.
2055        for i in 0..N {
2056            // n.b. *Zero value fills on underflows*
2057            // no need to edit values here because
2058            // the type was instantiated with default
2059            // type-secific zero values
2060            if let Some(c) = it.next() {
2061                newvec[i] = c
2062            }
2063        }
2064
2065        newvec
2066    }
2067}
2068
2069// ================================
2070//
2071// to_* numeric type cast impl
2072//
2073// ================================
2074
2075macro_rules! impl_vector_cast_num_type_to {
2076    ($NumTyp: ty, $MethodName: ident, $doc: expr) => {
2077        impl<T, const N: usize> Vector<T, N>
2078        where
2079            T: Num + Copy + Default + Sync + Send + ToPrimitive,
2080        {
2081            #[doc = $doc]
2082            pub fn $MethodName(&self) -> Option<Vector<$NumTyp, N>> {
2083                let mut new_components: [$NumTyp; N] = [0 as $NumTyp; N];
2084                for (i, val) in self.components.iter().enumerate() {
2085                    match val.$MethodName() {
2086                        Some(x) => new_components[i] = x,
2087                        None => return None,
2088                    }
2089                }
2090                Some(Vector { components: new_components })
2091            }
2092        }
2093    };
2094    ($NumTyp: ty, $MethodName: ident) => {
2095        impl_vector_cast_num_type_to!(
2096            $NumTyp,
2097            $MethodName,
2098            concat!(
2099                "Cast [`Vector`] numeric type to [`",
2100                stringify!($NumTyp),
2101                "`] and return a new [`Vector`]."
2102            )
2103        );
2104    };
2105}
2106
2107impl_vector_cast_num_type_to!(isize, to_isize);
2108impl_vector_cast_num_type_to!(i8, to_i8);
2109impl_vector_cast_num_type_to!(i16, to_i16);
2110impl_vector_cast_num_type_to!(i32, to_i32);
2111impl_vector_cast_num_type_to!(i64, to_i64);
2112impl_vector_cast_num_type_to!(i128, to_i128);
2113
2114impl_vector_cast_num_type_to!(usize, to_usize);
2115impl_vector_cast_num_type_to!(u8, to_u8);
2116impl_vector_cast_num_type_to!(u16, to_u16);
2117impl_vector_cast_num_type_to!(u32, to_u32);
2118impl_vector_cast_num_type_to!(u64, to_u64);
2119impl_vector_cast_num_type_to!(u128, to_u128);
2120
2121impl_vector_cast_num_type_to!(f32, to_f32);
2122impl_vector_cast_num_type_to!(f64, to_f64);
2123
2124// ================================
2125//
2126// PartialEq trait impl
2127//
2128// ================================
2129
2130/// PartialEq trait implementation for [`Vector`] with integer scalar data.
2131///
2132/// These comparisons establish the symmetry and transitivity relationships
2133/// required for the partial equivalence relation definition with integer types.
2134///
2135/// Note:
2136///
2137/// - Negative zero to positive zero comparisons are considered equal.
2138macro_rules! impl_vector_int_partialeq_from {
2139    ($IntTyp: ty, $doc: expr) => {
2140        impl<const N: usize> PartialEq<Vector<$IntTyp, N>> for Vector<$IntTyp, N> {
2141            #[doc = $doc]
2142            fn eq(&self, other: &Self) -> bool {
2143                self.components == other.components
2144            }
2145        }
2146    };
2147    ($IntTyp: ty) => {
2148        impl_vector_int_partialeq_from!(
2149            $IntTyp,
2150            concat!("PartialEq trait implementation for `Vector<", stringify!($IntTyp), ", N>`")
2151        );
2152    };
2153}
2154
2155impl_vector_int_partialeq_from!(usize);
2156impl_vector_int_partialeq_from!(u8);
2157impl_vector_int_partialeq_from!(u16);
2158impl_vector_int_partialeq_from!(u32);
2159impl_vector_int_partialeq_from!(u64);
2160impl_vector_int_partialeq_from!(u128);
2161impl_vector_int_partialeq_from!(isize);
2162impl_vector_int_partialeq_from!(i8);
2163impl_vector_int_partialeq_from!(i16);
2164impl_vector_int_partialeq_from!(i32);
2165impl_vector_int_partialeq_from!(i64);
2166impl_vector_int_partialeq_from!(i128);
2167
2168/// PartialEq trait implementation for [`Vector`] with floating point scalar data.
2169///
2170/// These comparisons establish the symmetry and transitivity relationships
2171/// required for the partial equivalence relation definition with floating point
2172/// types.  
2173///
2174/// Note:
2175///
2176/// - Negative zero to positive zero comparisons are considered equal.
2177/// - Positive infinity to positive infinity comparisons are considered equal.
2178/// - Negative infinity to negative infinity comparisons are considered equal.
2179/// - NaN comparisons are considered not equal.
2180///
2181/// This approach uses the default approx crate relative epsilon float equality testing implementation.
2182/// This equivalence relation implementation is based on the approach described in
2183/// [Comparing Floating Point Numbers, 2012 Edition](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/)
2184macro_rules! impl_vector_float_partialeq_from {
2185    ($FloatTyp: ty, $doc: expr) => {
2186        impl<const N: usize> PartialEq<Vector<$FloatTyp, N>> for Vector<$FloatTyp, N> {
2187            #[doc = $doc]
2188            fn eq(&self, other: &Self) -> bool {
2189                for (i, item) in self.components.iter().enumerate() {
2190                    // uses default approx crate epsilon and max relative
2191                    // diff = epsilon value parameter definitions
2192                    if !Relative::default().eq(item, &other[i]) {
2193                        return false;
2194                    }
2195                }
2196
2197                true
2198            }
2199        }
2200    };
2201    ($FloatTyp: ty) => {
2202        impl_vector_float_partialeq_from!(
2203            $FloatTyp,
2204            concat!("PartialEq trait implementation for `Vector<", stringify!($FloatTyp), ", N>`")
2205        );
2206    };
2207}
2208
2209impl_vector_float_partialeq_from!(f32);
2210impl_vector_float_partialeq_from!(f64);
2211
2212/// PartialEq trait implementation for [`Vector`] of [`num:Complex`] filled with
2213/// integer real and imaginary part data.
2214///
2215/// These comparisons establish the symmetry and transitivity relationships
2216/// required for the partial equivalence relation definition with complex numbers
2217/// with integer real and imaginary part types.
2218///
2219/// Note:
2220///
2221/// - Negative zero to positive zero comparisons are considered equal.
2222macro_rules! impl_vector_complex_int_partialeq_from {
2223    ($IntTyp: ty, $doc: expr) => {
2224        impl<const N: usize> PartialEq<Vector<Complex<$IntTyp>, N>>
2225            for Vector<Complex<$IntTyp>, N>
2226        {
2227            #[doc = $doc]
2228            fn eq(&self, other: &Self) -> bool {
2229                self.components == other.components
2230            }
2231        }
2232    };
2233    ($IntTyp: ty) => {
2234        impl_vector_complex_int_partialeq_from!(
2235            $IntTyp,
2236            concat!(
2237                "PartialEq trait implementation for `Vector<Complex<",
2238                stringify!($IntTyp),
2239                ">, N>`"
2240            )
2241        );
2242    };
2243}
2244
2245impl_vector_complex_int_partialeq_from!(usize);
2246impl_vector_complex_int_partialeq_from!(u8);
2247impl_vector_complex_int_partialeq_from!(u16);
2248impl_vector_complex_int_partialeq_from!(u32);
2249impl_vector_complex_int_partialeq_from!(u64);
2250impl_vector_complex_int_partialeq_from!(u128);
2251impl_vector_complex_int_partialeq_from!(isize);
2252impl_vector_complex_int_partialeq_from!(i8);
2253impl_vector_complex_int_partialeq_from!(i16);
2254impl_vector_complex_int_partialeq_from!(i32);
2255impl_vector_complex_int_partialeq_from!(i64);
2256impl_vector_complex_int_partialeq_from!(i128);
2257
2258/// PartialEq trait implementation for [`Vector`] of [`Complex`] numbers with
2259/// floating point real and imaginary parts.
2260///
2261/// These comparisons establish the symmetry and transitivity relationships
2262/// required for the partial equivalence relation definition with floating point
2263/// types.  
2264///
2265/// Note:
2266///
2267/// - Negative zero to positive zero comparisons are considered equal.
2268/// - Positive infinity to positive infinity comparisons are considered equal.
2269/// - Negative infinity to negative infinity comparisons are considered equal.
2270/// - NaN comparisons are considered not equal.
2271///
2272/// This approach uses the default approx crate relative epsilon float equality testing implementation.
2273/// This equivalence relation implementation is based on the approach described in
2274/// [Comparing Floating Point Numbers, 2012 Edition](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/)
2275macro_rules! impl_vector_complex_float_partialeq_from {
2276    ($FloatTyp: ty, $doc: expr) => {
2277        impl<const N: usize> PartialEq<Vector<Complex<$FloatTyp>, N>>
2278            for Vector<Complex<$FloatTyp>, N>
2279        {
2280            #[doc = $doc]
2281            fn eq(&self, other: &Self) -> bool {
2282                for (i, item) in self.components.iter().enumerate() {
2283                    // uses default approx crate epsilon and max relative
2284                    // diff = epsilon value parameter definitions
2285                    if !Relative::default().eq(&item.re, &other[i].re)
2286                        || !Relative::default().eq(&item.im, &other[i].im)
2287                    {
2288                        return false;
2289                    }
2290                }
2291
2292                true
2293            }
2294        }
2295    };
2296    ($FloatTyp: ty) => {
2297        impl_vector_complex_float_partialeq_from!(
2298            $FloatTyp,
2299            concat!(
2300                "PartialEq trait implementation for `Vector<Complex<",
2301                stringify!($FloatTyp),
2302                ">, N>`"
2303            )
2304        );
2305    };
2306}
2307
2308impl_vector_complex_float_partialeq_from!(f32);
2309impl_vector_complex_float_partialeq_from!(f64);
2310
2311// ======================================================
2312//
2313// approx crate float approximate equivalence trait impl
2314// AbsDiffEq, RelativeEq, UlpsEq traits
2315//
2316// ======================================================
2317
2318// approx::AbsDiffEq trait impl for floating point data types
2319macro_rules! impl_vector_float_absdiffeq_from {
2320    ($FloatTyp: ty, $doc: expr) => {
2321        impl<const N: usize> AbsDiffEq for Vector<$FloatTyp, N> {
2322            type Epsilon = $FloatTyp;
2323
2324            fn default_epsilon() -> $FloatTyp {
2325                <$FloatTyp>::default_epsilon()
2326            }
2327
2328            fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
2329                for (i, item) in self.components.iter().enumerate() {
2330                    if !<$FloatTyp>::abs_diff_eq(item, &other[i], epsilon) {
2331                        return false;
2332                    }
2333                }
2334                true
2335            }
2336        }
2337    };
2338    ($FloatTyp: ty) => {
2339        impl_vector_float_absdiffeq_from!(
2340            $FloatTyp,
2341            concat!(
2342                "approx::AbsDiffEq trait implementation for `Vector<",
2343                stringify!($FloatTyp),
2344                ", N>`"
2345            )
2346        );
2347    };
2348}
2349
2350impl_vector_float_absdiffeq_from!(f32);
2351impl_vector_float_absdiffeq_from!(f64);
2352
2353// approx::AbsDiffEq trait impl for complex numbers with floating point
2354// real and imaginary part data types
2355macro_rules! impl_vector_complex_float_absdiffeq_from {
2356    ($FloatTyp: ty, $doc: expr) => {
2357        impl<const N: usize> AbsDiffEq for Vector<Complex<$FloatTyp>, N> {
2358            type Epsilon = $FloatTyp;
2359
2360            fn default_epsilon() -> $FloatTyp {
2361                <$FloatTyp>::default_epsilon()
2362            }
2363
2364            fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
2365                for (i, item) in self.components.iter().enumerate() {
2366                    // compare the real and imaginary parts for eq
2367                    if !<$FloatTyp>::abs_diff_eq(&item.re, &other[i].re, epsilon)
2368                        || !<$FloatTyp>::abs_diff_eq(&item.im, &other[i].im, epsilon)
2369                    {
2370                        return false;
2371                    }
2372                }
2373                true
2374            }
2375        }
2376    };
2377    ($FloatTyp: ty) => {
2378        impl_vector_complex_float_absdiffeq_from!(
2379            $FloatTyp,
2380            concat!(
2381                "approx::AbsDiffEq trait implementation for `Vector<Complex<",
2382                stringify!($FloatTyp),
2383                ">, N>`"
2384            )
2385        );
2386    };
2387}
2388
2389impl_vector_complex_float_absdiffeq_from!(f32);
2390impl_vector_complex_float_absdiffeq_from!(f64);
2391
2392// approx::RelativeEq trait impl for floating point data types
2393macro_rules! impl_vector_float_relativeeq_from {
2394    ($FloatTyp: ty, $doc: expr) => {
2395        impl<const N: usize> RelativeEq for Vector<$FloatTyp, N> {
2396            fn default_max_relative() -> $FloatTyp {
2397                <$FloatTyp>::default_max_relative()
2398            }
2399
2400            fn relative_eq(
2401                &self,
2402                other: &Self,
2403                epsilon: Self::Epsilon,
2404                max_relative: Self::Epsilon,
2405            ) -> bool {
2406                for (i, item) in self.components.iter().enumerate() {
2407                    if !<$FloatTyp>::relative_eq(item, &other[i], epsilon, max_relative) {
2408                        return false;
2409                    }
2410                }
2411                true
2412            }
2413        }
2414    };
2415    ($FloatTyp: ty) => {
2416        impl_vector_float_relativeeq_from!(
2417            $FloatTyp,
2418            concat!(
2419                "approx::RelativeEq trait implementation for `Vector<",
2420                stringify!($FloatTyp),
2421                ", N>`"
2422            )
2423        );
2424    };
2425}
2426
2427impl_vector_float_relativeeq_from!(f32);
2428impl_vector_float_relativeeq_from!(f64);
2429
2430// approx::RelativeEq trait impl for floating point data types
2431macro_rules! impl_vector_complex_float_relativeeq_from {
2432    ($FloatTyp: ty, $doc: expr) => {
2433        impl<const N: usize> RelativeEq for Vector<Complex<$FloatTyp>, N> {
2434            fn default_max_relative() -> $FloatTyp {
2435                <$FloatTyp>::default_max_relative()
2436            }
2437
2438            fn relative_eq(
2439                &self,
2440                other: &Self,
2441                epsilon: Self::Epsilon,
2442                max_relative: Self::Epsilon,
2443            ) -> bool {
2444                for (i, item) in self.components.iter().enumerate() {
2445                    // compare the real and imaginary parts for eq
2446                    if !<$FloatTyp>::relative_eq(&item.re, &other[i].re, epsilon, max_relative)
2447                        || !<$FloatTyp>::relative_eq(&item.im, &other[i].im, epsilon, max_relative)
2448                    {
2449                        return false;
2450                    }
2451                }
2452                true
2453            }
2454        }
2455    };
2456    ($FloatTyp: ty) => {
2457        impl_vector_complex_float_relativeeq_from!(
2458            $FloatTyp,
2459            concat!(
2460                "approx::RelativeEq trait implementation for `Vector<Complex<",
2461                stringify!($FloatTyp),
2462                ">, N>`"
2463            )
2464        );
2465    };
2466}
2467
2468impl_vector_complex_float_relativeeq_from!(f32);
2469impl_vector_complex_float_relativeeq_from!(f64);
2470
2471// approx::UlpsEq trait impl for floating point types
2472macro_rules! impl_vector_float_ulpseq_from {
2473    ($FloatTyp: ty, $doc: expr) => {
2474        impl<const N: usize> UlpsEq for Vector<$FloatTyp, N> {
2475            fn default_max_ulps() -> u32 {
2476                <$FloatTyp>::default_max_ulps()
2477            }
2478
2479            fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
2480                for (i, item) in self.components.iter().enumerate() {
2481                    if !<$FloatTyp>::ulps_eq(item, &other[i], epsilon, max_ulps) {
2482                        return false;
2483                    }
2484                }
2485                true
2486            }
2487        }
2488    };
2489    ($FloatTyp: ty) => {
2490        impl_vector_float_ulpseq_from!(
2491            $FloatTyp,
2492            concat!(
2493                "approx::UlpsEq trait implementation for `Vector<",
2494                stringify!($FloatTyp),
2495                ", N>`"
2496            )
2497        );
2498    };
2499}
2500
2501impl_vector_float_ulpseq_from!(f32);
2502impl_vector_float_ulpseq_from!(f64);
2503
2504// approx::UlpsEq trait impl for complex numbers with floating point
2505// real and imaginary parts
2506macro_rules! impl_vector_complex_float_ulpseq_from {
2507    ($FloatTyp: ty, $doc: expr) => {
2508        impl<const N: usize> UlpsEq for Vector<Complex<$FloatTyp>, N> {
2509            fn default_max_ulps() -> u32 {
2510                <$FloatTyp>::default_max_ulps()
2511            }
2512
2513            fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
2514                for (i, item) in self.components.iter().enumerate() {
2515                    // compare the real and imaginary parts for eq
2516                    if !<$FloatTyp>::ulps_eq(&item.re, &other[i].re, epsilon, max_ulps)
2517                        || !<$FloatTyp>::ulps_eq(&item.im, &other[i].im, epsilon, max_ulps)
2518                    {
2519                        return false;
2520                    }
2521                }
2522                true
2523            }
2524        }
2525    };
2526    ($FloatTyp: ty) => {
2527        impl_vector_complex_float_ulpseq_from!(
2528            $FloatTyp,
2529            concat!(
2530                "approx::UlpsEq trait implementation for `Vector<Complex<",
2531                stringify!($FloatTyp),
2532                ">, N>`"
2533            )
2534        );
2535    };
2536}
2537
2538impl_vector_complex_float_ulpseq_from!(f32);
2539impl_vector_complex_float_ulpseq_from!(f64);
2540
2541// ================================
2542//
2543// AsRef / AsMut trait impl
2544//
2545// ================================
2546impl<T, const N: usize> AsRef<Vector<T, N>> for Vector<T, N>
2547where
2548    T: Num + Copy + Sync + Send,
2549{
2550    fn as_ref(&self) -> &Vector<T, N> {
2551        self
2552    }
2553}
2554
2555impl<T, const N: usize> AsRef<[T]> for Vector<T, N>
2556where
2557    T: Num + Copy + Sync + Send,
2558{
2559    fn as_ref(&self) -> &[T] {
2560        &self.components
2561    }
2562}
2563
2564impl<T, const N: usize> AsMut<Vector<T, N>> for Vector<T, N>
2565where
2566    T: Num + Copy + Sync + Send,
2567{
2568    fn as_mut(&mut self) -> &mut Vector<T, N> {
2569        self
2570    }
2571}
2572
2573impl<T, const N: usize> AsMut<[T]> for Vector<T, N>
2574where
2575    T: Num + Copy + Sync + Send,
2576{
2577    fn as_mut(&mut self) -> &mut [T] {
2578        &mut self.components
2579    }
2580}
2581
2582// ================================
2583//
2584// Borrow trait impl
2585//
2586// ================================
2587impl<T, const N: usize> Borrow<[T]> for Vector<T, N>
2588where
2589    T: Num + Copy + Sync + Send,
2590{
2591    fn borrow(&self) -> &[T] {
2592        &self.components
2593    }
2594}
2595
2596impl<T, const N: usize> BorrowMut<[T]> for Vector<T, N>
2597where
2598    T: Num + Copy + Sync + Send,
2599{
2600    fn borrow_mut(&mut self) -> &mut [T] {
2601        &mut self.components
2602    }
2603}
2604
2605// ================================
2606//
2607// Deref / DerefMut trait impl
2608//
2609// ================================
2610impl<T, const N: usize> Deref for Vector<T, N>
2611where
2612    T: Num + Copy + Sync + Send,
2613{
2614    type Target = [T];
2615
2616    fn deref(&self) -> &[T] {
2617        &self.components
2618    }
2619}
2620
2621impl<T, const N: usize> DerefMut for Vector<T, N>
2622where
2623    T: Num + Copy + Sync + Send,
2624{
2625    fn deref_mut(&mut self) -> &mut [T] {
2626        &mut self.components
2627    }
2628}
2629
2630// ================================
2631//
2632// From trait impl
2633//
2634// ================================
2635impl<T, const N: usize> From<[T; N]> for Vector<T, N>
2636where
2637    T: Num + Copy + Sync + Send,
2638{
2639    /// Returns a new [`Vector`] as defined by an [`array`] parameter.
2640    ///
2641    /// Note: The [`Vector`] dimension size is defined by the fixed [`array`]
2642    /// size.
2643    fn from(t_n_array: [T; N]) -> Vector<T, N> {
2644        Vector { components: t_n_array }
2645    }
2646}
2647
2648impl<T, const N: usize> From<&[T; N]> for Vector<T, N>
2649where
2650    T: Num + Copy + Sync + Send,
2651{
2652    /// Returns a new [`Vector`] as defined by an [`array`] reference parameter.
2653    ///
2654    /// Note: The [`Vector`] dimension size is defined by the fixed [`array`]
2655    /// size.
2656    fn from(t_n_array: &[T; N]) -> Vector<T, N> {
2657        Vector { components: *t_n_array }
2658    }
2659}
2660
2661impl<T, const N: usize> TryFrom<Vec<T>> for Vector<T, N>
2662where
2663    T: Num + Copy + Default + Sync + Send + std::fmt::Debug,
2664{
2665    type Error = VectorError;
2666    /// Returns a new [`Vector`] as defined by the [`Vec`] parameter.
2667    ///
2668    /// [`Vec`] lengths are not fixed and may not be known at compile time. Bounds
2669    /// checks are used in this approach.  This is slower than instantiation from
2670    /// arrays and will fail with overflows and underflows.
2671    ///
2672    /// # Errors
2673    ///
2674    /// Raises [`VectorError::TryFromVecError`] when the [`Vec`] parameter length
2675    /// does not equal the expected [`Vector`] data component length.
2676    ///
2677    /// # Examples
2678    ///
2679    /// Basic usage:
2680    ///
2681    /// ```
2682    /// # use vectora::types::vector::Vector;
2683    /// let _: Vector<i32, 3> = Vector::try_from(Vec::from([1, 2, 3])).unwrap();
2684    /// let _: Vector<f64, 2> = Vector::try_from(Vec::from([1.0, 2.0])).unwrap();
2685    /// ```
2686    ///
2687    /// Callers should confirm that the length of the [`Vec`] is
2688    /// the same as the number of requested [`Vector`] scalar data elements.  The following
2689    /// code raises [`VectorError::TryFromVecError`] on an attempt to make a
2690    /// three dimensional [`Vector`] with two dimensional data:
2691    ///
2692    /// ```
2693    ///# use vectora::types::vector::Vector;
2694    /// let v = vec![1 as i32, 2 as i32];
2695    /// let e = Vector::<i32, 3>::try_from(v);
2696    ///
2697    /// assert!(e.is_err());
2698    /// ```
2699    fn try_from(t_vec: Vec<T>) -> Result<Vector<T, N>, VectorError> {
2700        if t_vec.len() != N {
2701            return Err(VectorError::TryFromVecError(format!(
2702                "expected Vec with {} items, but received Vec with {} items",
2703                N,
2704                t_vec.len()
2705            )));
2706        }
2707        match t_vec.try_into() {
2708            Ok(s) => Ok(Self { components: s }),
2709            Err(err) => Err(VectorError::TryFromVecError(format!(
2710                "failed to cast Vec to Vector type: {:?}",
2711                err
2712            ))),
2713        }
2714    }
2715}
2716
2717impl<T, const N: usize> TryFrom<&Vec<T>> for Vector<T, N>
2718where
2719    T: Num + Copy + Default + Sync + Send + std::fmt::Debug,
2720{
2721    type Error = VectorError;
2722    /// Returns a new [`Vector`] as defined by the [`Vec`] reference parameter.
2723    ///
2724    /// [`Vec`] lengths are not fixed and may not be known at compile time. Bounds
2725    /// checks are used in this approach.  This is slower than instantiation from
2726    /// arrays and will fail with overflows and underflows.
2727    ///
2728    /// # Errors
2729    ///
2730    /// Raises [`VectorError::TryFromVecError`] when the [`Vec`] parameter length
2731    /// does not equal the expected [`Vector`] component length.
2732    ///
2733    /// # Examples
2734    ///
2735    /// Basic usage:
2736    ///
2737    /// ```
2738    /// # use vectora::types::vector::Vector;
2739    /// let _: Vector<i32, 3> = Vector::try_from(&Vec::from([1, 2, 3])).unwrap();
2740    /// let _: Vector<f64, 2> = Vector::try_from(&Vec::from([1.0, 2.0])).unwrap();
2741    /// ```
2742    ///
2743    /// Callers should confirm that the length of the [`Vec`] is
2744    /// the same as the number of requested [`Vector`] data dimensions.  The following
2745    /// code raises [`VectorError::TryFromVecError`] on an attempt to make a
2746    /// three dimensional [`Vector`] with two dimensional data:
2747    ///
2748    /// ```
2749    ///# use vectora::types::vector::Vector;
2750    /// let v = vec![1 as i32, 2 as i32];
2751    /// let e = Vector::<i32, 3>::try_from(&v);
2752    ///
2753    /// assert!(e.is_err());
2754    /// ```
2755    fn try_from(t_vec: &Vec<T>) -> Result<Vector<T, N>, VectorError> {
2756        if t_vec.len() != N {
2757            return Err(VectorError::TryFromVecError(format!(
2758                "expected Vec with {} items, but received Vec with {} items",
2759                N,
2760                t_vec.len()
2761            )));
2762        }
2763
2764        Self::try_from(&t_vec[..])
2765    }
2766}
2767
2768impl<T, const N: usize> TryFrom<&[T]> for Vector<T, N>
2769where
2770    T: Num + Copy + Default + Sync + Send,
2771{
2772    type Error = VectorError;
2773    /// Returns a new [`Vector`] as defined by a [`slice`] parameter.
2774    ///
2775    /// # Errors
2776    ///
2777    /// Raises [`VectorError::TryFromSliceError`] when the [`slice`] parameter length
2778    /// is not equal to the requested [`Vector`] data component length.
2779    ///
2780    /// # Examples
2781    ///
2782    /// ## From [`array`] slice
2783    ///
2784    /// ```
2785    ///# use vectora::types::vector::Vector;
2786    /// let _: Vector<i32, 3> = Vector::try_from(&[1, 2, 3][..]).unwrap();
2787    /// let _: Vector<f64, 2> = Vector::try_from(&[1.0, 2.0][..]).unwrap();
2788    /// ```
2789    ///
2790    /// ## From [`Vec`] slice
2791    ///
2792    /// ```
2793    ///# use vectora::types::vector::Vector;
2794    /// let _: Vector<i32, 3> = Vector::try_from(Vec::from([1, 2, 3]).as_slice()).unwrap();
2795    /// let _: Vector<f64, 2> = Vector::try_from(Vec::from([1.0, 2.0]).as_slice()).unwrap();
2796    /// ```
2797    ///
2798    /// Callers should confirm that the length of the [`slice`] is
2799    /// the same as the number of requested [`Vector`] data dimensions.  The following
2800    /// code raises [`VectorError::TryFromSliceError`] on an attempt to make a
2801    /// three dimensional [`Vector`] with two dimensional data:
2802    ///
2803    /// ```
2804    ///# use vectora::types::vector::Vector;
2805    /// let v = vec![1 as i32, 2 as i32];
2806    /// let s = &v[..];
2807    /// let e = Vector::<i32, 3>::try_from(s);
2808    ///
2809    /// assert!(e.is_err());
2810    /// ```
2811    fn try_from(t_slice: &[T]) -> Result<Vector<T, N>, VectorError> {
2812        if t_slice.len() != N {
2813            return Err(VectorError::TryFromSliceError(format!(
2814                "expected slice with {} items, but received slice with {} items",
2815                N,
2816                t_slice.len()
2817            )));
2818        }
2819
2820        match t_slice.try_into() {
2821            Ok(s) => Ok(Self { components: s }),
2822            Err(err) => Err(VectorError::TryFromSliceError(format!(
2823                "failed to cast slice to Vector type: {}",
2824                err
2825            ))),
2826        }
2827    }
2828}
2829
2830/// Returns a new [`Vector`] with lossless [`Vector`] real scalar numeric type data
2831/// cast support.
2832macro_rules! impl_vector_from_vector {
2833    ($Small: ty, $Large: ty, $doc: expr) => {
2834        impl<const N: usize> From<Vector<$Small, N>> for Vector<$Large, N> {
2835            #[doc = $doc]
2836            fn from(small: Vector<$Small, N>) -> Vector<$Large, N> {
2837                let mut new_components: [$Large; N] = [0 as $Large; N];
2838                let mut i = 0;
2839                for c in &small.components {
2840                    new_components[i] = *c as $Large;
2841                    i += 1;
2842                }
2843                Vector { components: new_components }
2844            }
2845        }
2846    };
2847    ($Small: ty, $Large: ty) => {
2848        impl_vector_from_vector!(
2849            $Small,
2850            $Large,
2851            concat!(
2852                "Converts [`",
2853                stringify!($Small),
2854                "`] scalar components to [`",
2855                stringify!($Large),
2856                "`] losslessly."
2857            )
2858        );
2859    };
2860}
2861
2862// Unsigned to Unsigned
2863impl_vector_from_vector!(u8, u16);
2864impl_vector_from_vector!(u8, u32);
2865impl_vector_from_vector!(u8, u64);
2866impl_vector_from_vector!(u8, u128);
2867impl_vector_from_vector!(u8, usize);
2868impl_vector_from_vector!(u16, u32);
2869impl_vector_from_vector!(u16, u64);
2870impl_vector_from_vector!(u16, u128);
2871impl_vector_from_vector!(u32, u64);
2872impl_vector_from_vector!(u32, u128);
2873impl_vector_from_vector!(u64, u128);
2874
2875// Signed to Signed
2876impl_vector_from_vector!(i8, i16);
2877impl_vector_from_vector!(i8, i32);
2878impl_vector_from_vector!(i8, i64);
2879impl_vector_from_vector!(i8, i128);
2880impl_vector_from_vector!(i8, isize);
2881impl_vector_from_vector!(i16, i32);
2882impl_vector_from_vector!(i16, i64);
2883impl_vector_from_vector!(i16, i128);
2884impl_vector_from_vector!(i32, i64);
2885impl_vector_from_vector!(i32, i128);
2886impl_vector_from_vector!(i64, i128);
2887
2888// Unsigned to Signed
2889impl_vector_from_vector!(u8, i16);
2890impl_vector_from_vector!(u8, i32);
2891impl_vector_from_vector!(u8, i64);
2892impl_vector_from_vector!(u8, i128);
2893impl_vector_from_vector!(u16, i32);
2894impl_vector_from_vector!(u16, i64);
2895impl_vector_from_vector!(u16, i128);
2896impl_vector_from_vector!(u32, i64);
2897impl_vector_from_vector!(u32, i128);
2898impl_vector_from_vector!(u64, i128);
2899
2900// Signed to Float
2901impl_vector_from_vector!(i8, f32);
2902impl_vector_from_vector!(i8, f64);
2903impl_vector_from_vector!(i16, f32);
2904impl_vector_from_vector!(i16, f64);
2905impl_vector_from_vector!(i32, f64);
2906
2907// Unsigned to Float
2908impl_vector_from_vector!(u8, f32);
2909impl_vector_from_vector!(u8, f64);
2910impl_vector_from_vector!(u16, f32);
2911impl_vector_from_vector!(u16, f64);
2912impl_vector_from_vector!(u32, f64);
2913
2914// Float to Float
2915impl_vector_from_vector!(f32, f64);
2916
2917/// Returns a new [`Vector`] with lossless [`Vector`] complex scalar numeric type data
2918/// cast support.
2919macro_rules! impl_complex_vector_from_complex_vector {
2920    ($Small: ty, $Large: ty, $doc: expr) => {
2921        impl<const N: usize> From<Vector<Complex<$Small>, N>> for Vector<Complex<$Large>, N> {
2922            #[doc = $doc]
2923            fn from(small: Vector<Complex<$Small>, N>) -> Vector<Complex<$Large>, N> {
2924                let mut new_components =
2925                    [Complex { re: <$Large>::default(), im: <$Large>::default() }; N];
2926                let mut i = 0;
2927                for small_complex_num in &small.components {
2928                    new_components[i].re = small_complex_num.re as $Large;
2929                    new_components[i].im = small_complex_num.im as $Large;
2930                    i += 1;
2931                }
2932                Vector { components: new_components }
2933            }
2934        }
2935    };
2936    ($Small: ty, $Large: ty) => {
2937        impl_complex_vector_from_complex_vector!(
2938            $Small,
2939            $Large,
2940            concat!(
2941                "Converts [`Complex<",
2942                stringify!($Small),
2943                ">`] scalar components to [`Complex<",
2944                stringify!($Large),
2945                ">`] losslessly."
2946            )
2947        );
2948    };
2949}
2950
2951// Unsigned to Unsigned
2952impl_complex_vector_from_complex_vector!(u8, u16);
2953impl_complex_vector_from_complex_vector!(u8, u32);
2954impl_complex_vector_from_complex_vector!(u8, u64);
2955impl_complex_vector_from_complex_vector!(u8, u128);
2956impl_complex_vector_from_complex_vector!(u8, usize);
2957impl_complex_vector_from_complex_vector!(u16, u32);
2958impl_complex_vector_from_complex_vector!(u16, u64);
2959impl_complex_vector_from_complex_vector!(u16, u128);
2960impl_complex_vector_from_complex_vector!(u32, u64);
2961impl_complex_vector_from_complex_vector!(u32, u128);
2962impl_complex_vector_from_complex_vector!(u64, u128);
2963
2964// Signed to Signed
2965impl_complex_vector_from_complex_vector!(i8, i16);
2966impl_complex_vector_from_complex_vector!(i8, i32);
2967impl_complex_vector_from_complex_vector!(i8, i64);
2968impl_complex_vector_from_complex_vector!(i8, i128);
2969impl_complex_vector_from_complex_vector!(i8, isize);
2970impl_complex_vector_from_complex_vector!(i16, i32);
2971impl_complex_vector_from_complex_vector!(i16, i64);
2972impl_complex_vector_from_complex_vector!(i16, i128);
2973impl_complex_vector_from_complex_vector!(i32, i64);
2974impl_complex_vector_from_complex_vector!(i32, i128);
2975impl_complex_vector_from_complex_vector!(i64, i128);
2976
2977// Unsigned to Signed
2978impl_complex_vector_from_complex_vector!(u8, i16);
2979impl_complex_vector_from_complex_vector!(u8, i32);
2980impl_complex_vector_from_complex_vector!(u8, i64);
2981impl_complex_vector_from_complex_vector!(u8, i128);
2982impl_complex_vector_from_complex_vector!(u16, i32);
2983impl_complex_vector_from_complex_vector!(u16, i64);
2984impl_complex_vector_from_complex_vector!(u16, i128);
2985impl_complex_vector_from_complex_vector!(u32, i64);
2986impl_complex_vector_from_complex_vector!(u32, i128);
2987impl_complex_vector_from_complex_vector!(u64, i128);
2988
2989// Signed to Float
2990impl_complex_vector_from_complex_vector!(i8, f32);
2991impl_complex_vector_from_complex_vector!(i8, f64);
2992impl_complex_vector_from_complex_vector!(i16, f32);
2993impl_complex_vector_from_complex_vector!(i16, f64);
2994impl_complex_vector_from_complex_vector!(i32, f64);
2995
2996// Unsigned to Float
2997impl_complex_vector_from_complex_vector!(u8, f32);
2998impl_complex_vector_from_complex_vector!(u8, f64);
2999impl_complex_vector_from_complex_vector!(u16, f32);
3000impl_complex_vector_from_complex_vector!(u16, f64);
3001impl_complex_vector_from_complex_vector!(u32, f64);
3002
3003// Float to Float
3004impl_complex_vector_from_complex_vector!(f32, f64);
3005
3006// ================================
3007//
3008// Operator overloads
3009//
3010// ================================
3011
3012// Unary
3013
3014impl<T, const N: usize> Neg for Vector<T, N>
3015where
3016    T: Num + Neg<Output = T> + Copy + Default + Sync + Send,
3017{
3018    type Output = Self;
3019
3020    /// Unary negation operator overload implementation.
3021    fn neg(self) -> Self::Output {
3022        let new_components = &mut [T::default(); N];
3023        for (i, x) in new_components.iter_mut().enumerate() {
3024            *x = -self.components[i];
3025        }
3026        Self { components: *new_components }
3027    }
3028}
3029
3030// Binary
3031
3032impl<T, const N: usize> Add for Vector<T, N>
3033where
3034    T: Num + Copy + Sync + Send,
3035{
3036    type Output = Self;
3037
3038    /// Binary add operator overload implemenatation for vector addition.
3039    fn add(self, rhs: Self) -> Self::Output {
3040        let new_components = &mut [T::zero(); N];
3041        for (i, x) in new_components.iter_mut().enumerate() {
3042            *x = self[i] + rhs[i];
3043        }
3044        Self { components: *new_components }
3045    }
3046}
3047
3048impl<T, const N: usize> Sub for Vector<T, N>
3049where
3050    T: Num + Copy + Sync + Send,
3051{
3052    type Output = Self;
3053
3054    /// Binary subtraction operator overload implementation for vector substration.
3055    fn sub(self, rhs: Self) -> Self::Output {
3056        let new_components = &mut [T::zero(); N];
3057        for (i, x) in new_components.iter_mut().enumerate() {
3058            *x = self[i] - rhs[i];
3059        }
3060        Self { components: *new_components }
3061    }
3062}
3063
3064impl<T, const N: usize> Mul<T> for Vector<T, N>
3065where
3066    T: Num + Copy + Sync + Send,
3067{
3068    type Output = Self;
3069
3070    /// Binary multiplication operator overload implementation for vector
3071    /// scalar multiplication.
3072    fn mul(self, rhs: T) -> Self::Output {
3073        let new_components = &mut [T::zero(); N];
3074        for (i, x) in new_components.iter_mut().enumerate() {
3075            *x = self[i] * rhs;
3076        }
3077        Self { components: *new_components }
3078    }
3079}
3080
3081impl<T, const N: usize> Mul<T> for Vector<Complex<T>, N>
3082where
3083    T: Num + Copy + Sync + Send,
3084{
3085    type Output = Self;
3086
3087    /// Binary multiplication operator overload implementation for complex
3088    /// number [`Vector`] scalar multiplication with a real number
3089    /// scalar multiple.
3090    fn mul(self, rhs: T) -> Self::Output {
3091        let new_components = &mut [Complex { re: T::zero(), im: T::zero() }; N];
3092        for (i, x) in new_components.iter_mut().enumerate() {
3093            *x = self[i] * rhs;
3094        }
3095        Self { components: *new_components }
3096    }
3097}
3098
3099// =====================================================
3100//
3101// Optional rayon::iter::IntoParallelIterator trait impl
3102//
3103// =====================================================
3104
3105#[cfg(feature = "parallel")]
3106impl<T, const N: usize> IntoParallelIterator for Vector<T, N>
3107where
3108    T: Num + Copy + Sync + Send,
3109{
3110    type Item = T;
3111    type Iter = rayon::array::IntoIter<T, N>;
3112
3113    /// Creates a parallel iterator over owned scalar data.
3114    fn into_par_iter(self) -> Self::Iter {
3115        self.components.into_par_iter()
3116    }
3117}
3118
3119#[cfg(feature = "parallel")]
3120impl<'a, T, const N: usize> IntoParallelIterator for &'a Vector<T, N>
3121where
3122    T: Num + Copy + Sync + Send + 'a,
3123{
3124    type Item = &'a T;
3125    type Iter = rayon::slice::Iter<'a, T>;
3126
3127    /// Creates a parallel iterator over immutable references to scalar data.
3128    fn into_par_iter(self) -> Self::Iter {
3129        <&[T]>::into_par_iter(self)
3130    }
3131}
3132
3133#[cfg(feature = "parallel")]
3134impl<'a, T, const N: usize> IntoParallelIterator for &'a mut Vector<T, N>
3135where
3136    T: Num + Copy + Sync + Send + 'a,
3137{
3138    type Item = &'a mut T;
3139    type Iter = rayon::slice::IterMut<'a, T>;
3140
3141    /// Creates a parallel iterator over mutable references to scalar data.
3142    fn into_par_iter(self) -> Self::Iter {
3143        <&mut [T]>::into_par_iter(self)
3144    }
3145}
3146
3147// =====================================================
3148//
3149// Optional rayon::slice::ParallelSlice trait impl
3150// Optional rayon::slice::ParallelSliceMut trait impl
3151//
3152// =====================================================
3153
3154#[cfg(feature = "parallel")]
3155impl<T, const N: usize> ParallelSlice<T> for Vector<T, N>
3156where
3157    T: Num + Copy + Sync + Send,
3158{
3159    /// Returns an immutable slice of scalar data for use with Rayon
3160    /// parallel slice methods.
3161    fn as_parallel_slice(&self) -> &[T] {
3162        &self.components[..]
3163    }
3164}
3165
3166#[cfg(feature = "parallel")]
3167impl<T, const N: usize> ParallelSlice<T> for &Vector<T, N>
3168where
3169    T: Num + Copy + Sync + Send,
3170{
3171    /// Returns an immutable slice of scalar data for use with Rayon
3172    /// parallel slice methods.
3173    fn as_parallel_slice(&self) -> &[T] {
3174        &self.components[..]
3175    }
3176}
3177
3178#[cfg(feature = "parallel")]
3179impl<T, const N: usize> ParallelSliceMut<T> for Vector<T, N>
3180where
3181    T: Num + Copy + Sync + Send,
3182{
3183    /// Returns a mutable slice of scalar data for use with Rayon
3184    /// parallel slice methods.
3185    fn as_parallel_slice_mut(&mut self) -> &mut [T] {
3186        &mut self.components[..]
3187    }
3188}
3189
3190#[cfg(feature = "parallel")]
3191impl<T, const N: usize> ParallelSliceMut<T> for &mut Vector<T, N>
3192where
3193    T: Num + Copy + Sync + Send,
3194{
3195    /// Returns a mutable slice of scalar data for use with Rayon
3196    /// parallel slice methods.
3197    fn as_parallel_slice_mut(&mut self) -> &mut [T] {
3198        &mut self.components[..]
3199    }
3200}
3201
3202#[cfg(test)]
3203mod tests {
3204    use super::*;
3205    #[allow(unused_imports)]
3206    use approx::{assert_relative_eq, assert_relative_ne};
3207    use num::complex::Complex;
3208    #[allow(unused_imports)]
3209    use pretty_assertions::{assert_eq, assert_ne};
3210    use std::any::{Any, TypeId};
3211
3212    #[cfg(feature = "parallel")]
3213    use rayon::iter::IndexedParallelIterator;
3214
3215    // =======================================
3216    //
3217    // Instantiation associated function tests
3218    //
3219    // =======================================
3220
3221    #[test]
3222    fn vector_instantiation_new_i8() {
3223        // Two dimension
3224        let mut tests = vec![];
3225        let v1 = Vector::<i8, 2>::new();
3226        let v2 = Vector2d::<i8>::new();
3227        let v3 = Vector2dI8::new();
3228        tests.push(v1);
3229        tests.push(v2);
3230        tests.push(v3);
3231        for v in tests {
3232            assert_eq!(v[0], 0 as i8);
3233            assert_eq!(v[1], 0 as i8);
3234            assert_eq!(v.components.len(), 2);
3235        }
3236
3237        // Three dimension
3238        let mut tests = vec![];
3239        let v1 = Vector::<i8, 3>::new();
3240        let v2 = Vector3d::<i8>::new();
3241        let v3 = Vector3dI8::new();
3242        tests.push(v1);
3243        tests.push(v2);
3244        tests.push(v3);
3245        for v in tests {
3246            assert_eq!(v[0], 0 as i8);
3247            assert_eq!(v[1], 0 as i8);
3248            assert_eq!(v[2], 0 as i8);
3249            assert_eq!(v.components.len(), 3);
3250        }
3251    }
3252
3253    #[test]
3254    fn vector_instantiation_new_i16() {
3255        // Two dimension
3256        let mut tests = vec![];
3257        let v1 = Vector::<i16, 2>::new();
3258        let v2 = Vector2d::<i16>::new();
3259        let v3 = Vector2dI16::new();
3260        tests.push(v1);
3261        tests.push(v2);
3262        tests.push(v3);
3263        for v in tests {
3264            assert_eq!(v[0], 0 as i16);
3265            assert_eq!(v[1], 0 as i16);
3266            assert_eq!(v.components.len(), 2);
3267        }
3268
3269        // Three dimension
3270        let mut tests = vec![];
3271        let v1 = Vector::<i16, 3>::new();
3272        let v2 = Vector3d::<i16>::new();
3273        let v3 = Vector3dI16::new();
3274        tests.push(v1);
3275        tests.push(v2);
3276        tests.push(v3);
3277        for v in tests {
3278            assert_eq!(v[0], 0 as i16);
3279            assert_eq!(v[1], 0 as i16);
3280            assert_eq!(v[2], 0 as i16);
3281            assert_eq!(v.components.len(), 3);
3282        }
3283    }
3284
3285    #[test]
3286    fn vector_instantiation_new_i32() {
3287        // Two dimension
3288        let mut tests = vec![];
3289        let v1 = Vector::<i32, 2>::new();
3290        let v2 = Vector2d::<i32>::new();
3291        let v3 = Vector2dI32::new();
3292        tests.push(v1);
3293        tests.push(v2);
3294        tests.push(v3);
3295        for v in tests {
3296            assert_eq!(v[0], 0 as i32);
3297            assert_eq!(v[1], 0 as i32);
3298            assert_eq!(v.components.len(), 2);
3299        }
3300
3301        // Three dimension
3302        let mut tests = vec![];
3303        let v1 = Vector::<i32, 3>::new();
3304        let v2 = Vector3d::<i32>::new();
3305        let v3 = Vector3dI32::new();
3306        tests.push(v1);
3307        tests.push(v2);
3308        tests.push(v3);
3309        for v in tests {
3310            assert_eq!(v[0], 0 as i32);
3311            assert_eq!(v[1], 0 as i32);
3312            assert_eq!(v[2], 0 as i32);
3313            assert_eq!(v.components.len(), 3);
3314        }
3315    }
3316
3317    #[test]
3318    fn vector_instantiation_new_i64() {
3319        // Two dimension
3320        let mut tests = vec![];
3321        let v1 = Vector::<i64, 2>::new();
3322        let v2 = Vector2d::<i64>::new();
3323        let v3 = Vector2dI64::new();
3324        tests.push(v1);
3325        tests.push(v2);
3326        tests.push(v3);
3327        for v in tests {
3328            assert_eq!(v[0], 0 as i64);
3329            assert_eq!(v[1], 0 as i64);
3330            assert_eq!(v.components.len(), 2);
3331        }
3332
3333        // Three dimension
3334        let mut tests = vec![];
3335        let v1 = Vector::<i64, 3>::new();
3336        let v2 = Vector3d::<i64>::new();
3337        let v3 = Vector3dI64::new();
3338        tests.push(v1);
3339        tests.push(v2);
3340        tests.push(v3);
3341        for v in tests {
3342            assert_eq!(v[0], 0 as i64);
3343            assert_eq!(v[1], 0 as i64);
3344            assert_eq!(v[2], 0 as i64);
3345            assert_eq!(v.components.len(), 3);
3346        }
3347    }
3348
3349    #[test]
3350    fn vector_instantiation_new_i128() {
3351        // Two dimension
3352        let mut tests = vec![];
3353        let v1 = Vector::<i128, 2>::new();
3354        let v2 = Vector2d::<i128>::new();
3355        let v3 = Vector2dI128::new();
3356        tests.push(v1);
3357        tests.push(v2);
3358        tests.push(v3);
3359        for v in tests {
3360            assert_eq!(v[0], 0 as i128);
3361            assert_eq!(v[1], 0 as i128);
3362            assert_eq!(v.components.len(), 2);
3363        }
3364
3365        // Three dimension
3366        let mut tests = vec![];
3367        let v1 = Vector::<i128, 3>::new();
3368        let v2 = Vector3d::<i128>::new();
3369        let v3 = Vector3dI128::new();
3370        tests.push(v1);
3371        tests.push(v2);
3372        tests.push(v3);
3373        for v in tests {
3374            assert_eq!(v[0], 0 as i128);
3375            assert_eq!(v[1], 0 as i128);
3376            assert_eq!(v[2], 0 as i128);
3377            assert_eq!(v.components.len(), 3);
3378        }
3379    }
3380
3381    #[test]
3382    fn vector_instantiation_new_u8() {
3383        // Two dimension
3384        let mut tests = vec![];
3385        let v1 = Vector::<u8, 2>::new();
3386        let v2 = Vector2d::<u8>::new();
3387        let v3 = Vector2dU8::new();
3388        tests.push(v1);
3389        tests.push(v2);
3390        tests.push(v3);
3391        for v in tests {
3392            assert_eq!(v[0], 0 as u8);
3393            assert_eq!(v[1], 0 as u8);
3394            assert_eq!(v.components.len(), 2);
3395        }
3396
3397        // Three dimension
3398        let mut tests = vec![];
3399        let v1 = Vector::<u8, 3>::new();
3400        let v2 = Vector3d::<u8>::new();
3401        let v3 = Vector3dU8::new();
3402        tests.push(v1);
3403        tests.push(v2);
3404        tests.push(v3);
3405        for v in tests {
3406            assert_eq!(v[0], 0 as u8);
3407            assert_eq!(v[1], 0 as u8);
3408            assert_eq!(v[2], 0 as u8);
3409            assert_eq!(v.components.len(), 3);
3410        }
3411    }
3412
3413    #[test]
3414    fn vector_instantiation_new_u16() {
3415        // Two dimension
3416        let mut tests = vec![];
3417        let v1 = Vector::<u16, 2>::new();
3418        let v2 = Vector2d::<u16>::new();
3419        let v3 = Vector2dU16::new();
3420        tests.push(v1);
3421        tests.push(v2);
3422        tests.push(v3);
3423        for v in tests {
3424            assert_eq!(v[0], 0 as u16);
3425            assert_eq!(v[1], 0 as u16);
3426            assert_eq!(v.components.len(), 2);
3427        }
3428
3429        // Three dimension
3430        let mut tests = vec![];
3431        let v1 = Vector::<u16, 3>::new();
3432        let v2 = Vector3d::<u16>::new();
3433        let v3 = Vector3dU16::new();
3434        tests.push(v1);
3435        tests.push(v2);
3436        tests.push(v3);
3437        for v in tests {
3438            assert_eq!(v[0], 0 as u16);
3439            assert_eq!(v[1], 0 as u16);
3440            assert_eq!(v[2], 0 as u16);
3441            assert_eq!(v.components.len(), 3);
3442        }
3443    }
3444
3445    #[test]
3446    fn vector_instantiation_new_u32() {
3447        // Two dimension
3448        let mut tests = vec![];
3449        let v1 = Vector::<u32, 2>::new();
3450        let v2 = Vector2d::<u32>::new();
3451        let v3 = Vector2dU32::new();
3452        tests.push(v1);
3453        tests.push(v2);
3454        tests.push(v3);
3455        for v in tests {
3456            assert_eq!(v[0], 0 as u32);
3457            assert_eq!(v[1], 0 as u32);
3458            assert_eq!(v.components.len(), 2);
3459        }
3460
3461        // Three dimension
3462        let mut tests = vec![];
3463        let v1 = Vector::<u32, 3>::new();
3464        let v2 = Vector3d::<u32>::new();
3465        let v3 = Vector3dU32::new();
3466        tests.push(v1);
3467        tests.push(v2);
3468        tests.push(v3);
3469        for v in tests {
3470            assert_eq!(v[0], 0 as u32);
3471            assert_eq!(v[1], 0 as u32);
3472            assert_eq!(v[2], 0 as u32);
3473            assert_eq!(v.components.len(), 3);
3474        }
3475    }
3476
3477    #[test]
3478    fn vector_instantiation_new_u64() {
3479        // Two dimension
3480        let mut tests = vec![];
3481        let v1 = Vector::<u64, 2>::new();
3482        let v2 = Vector2d::<u64>::new();
3483        let v3 = Vector2dU64::new();
3484        tests.push(v1);
3485        tests.push(v2);
3486        tests.push(v3);
3487        for v in tests {
3488            assert_eq!(v[0], 0 as u64);
3489            assert_eq!(v[1], 0 as u64);
3490            assert_eq!(v.components.len(), 2);
3491        }
3492
3493        // Three dimension
3494        let mut tests = vec![];
3495        let v1 = Vector::<u64, 3>::new();
3496        let v2 = Vector3d::<u64>::new();
3497        let v3 = Vector3dU64::new();
3498        tests.push(v1);
3499        tests.push(v2);
3500        tests.push(v3);
3501        for v in tests {
3502            assert_eq!(v[0], 0 as u64);
3503            assert_eq!(v[1], 0 as u64);
3504            assert_eq!(v[2], 0 as u64);
3505            assert_eq!(v.components.len(), 3);
3506        }
3507    }
3508
3509    #[test]
3510    fn vector_instantiation_new_u128() {
3511        // Two dimension
3512        let mut tests = vec![];
3513        let v1 = Vector::<u128, 2>::new();
3514        let v2 = Vector2d::<u128>::new();
3515        let v3 = Vector2dU128::new();
3516        tests.push(v1);
3517        tests.push(v2);
3518        tests.push(v3);
3519        for v in tests {
3520            assert_eq!(v[0], 0 as u128);
3521            assert_eq!(v[1], 0 as u128);
3522            assert_eq!(v.components.len(), 2);
3523        }
3524
3525        // Three dimension
3526        let mut tests = vec![];
3527        let v1 = Vector::<u128, 3>::new();
3528        let v2 = Vector3d::<u128>::new();
3529        let v3 = Vector3dU128::new();
3530        tests.push(v1);
3531        tests.push(v2);
3532        tests.push(v3);
3533        for v in tests {
3534            assert_eq!(v[0], 0 as u128);
3535            assert_eq!(v[1], 0 as u128);
3536            assert_eq!(v[2], 0 as u128);
3537            assert_eq!(v.components.len(), 3);
3538        }
3539    }
3540
3541    #[test]
3542    fn vector_instantiation_new_f32() {
3543        // Two dimension
3544        let mut tests = vec![];
3545        let v1 = Vector::<f32, 2>::new();
3546        let v2 = Vector2d::<f32>::new();
3547        let v3 = Vector2dF32::new();
3548        tests.push(v1);
3549        tests.push(v2);
3550        tests.push(v3);
3551        for v in tests {
3552            assert_relative_eq!(v[0], 0.0 as f32);
3553            assert_relative_eq!(v[1], 0.0 as f32);
3554            assert_eq!(v.components.len(), 2);
3555        }
3556
3557        // Three dimension
3558        let mut tests = vec![];
3559        let v1 = Vector::<f32, 3>::new();
3560        let v2 = Vector3d::<f32>::new();
3561        let v3 = Vector3dF32::new();
3562        tests.push(v1);
3563        tests.push(v2);
3564        tests.push(v3);
3565        for v in tests {
3566            assert_relative_eq!(v[0], 0.0 as f32);
3567            assert_relative_eq!(v[1], 0.0 as f32);
3568            assert_relative_eq!(v[2], 0.0 as f32);
3569            assert_eq!(v.components.len(), 3);
3570        }
3571    }
3572
3573    #[test]
3574    fn vector_instantiation_new_f64() {
3575        // Two dimension
3576        let mut tests = vec![];
3577        let v1 = Vector::<f64, 2>::new();
3578        let v2 = Vector2d::<f64>::new();
3579        let v3 = Vector2dF64::new();
3580        tests.push(v1);
3581        tests.push(v2);
3582        tests.push(v3);
3583        for v in tests {
3584            assert_relative_eq!(v[0], 0.0 as f64);
3585            assert_relative_eq!(v[1], 0.0 as f64);
3586            assert_eq!(v.components.len(), 2);
3587        }
3588
3589        // Three dimension
3590        let mut tests = vec![];
3591        let v1 = Vector::<f64, 3>::new();
3592        let v2 = Vector3d::<f64>::new();
3593        let v3 = Vector3dF64::new();
3594        tests.push(v1);
3595        tests.push(v2);
3596        tests.push(v3);
3597        for v in tests {
3598            assert_relative_eq!(v[0], 0.0 as f64);
3599            assert_relative_eq!(v[1], 0.0 as f64);
3600            assert_relative_eq!(v[2], 0.0 as f64);
3601            assert_eq!(v.components.len(), 3);
3602        }
3603    }
3604
3605    #[test]
3606    fn vector_instantiation_new_usize() {
3607        // Two dimension
3608        let mut tests = vec![];
3609        let v1 = Vector::<usize, 2>::new();
3610        let v2 = Vector2d::<usize>::new();
3611        let v3 = Vector2dUsize::new();
3612        tests.push(v1);
3613        tests.push(v2);
3614        tests.push(v3);
3615        for v in tests {
3616            assert_eq!(v[0], 0 as usize);
3617            assert_eq!(v[1], 0 as usize);
3618            assert_eq!(v.components.len(), 2);
3619        }
3620
3621        // Three dimension
3622        let mut tests = vec![];
3623        let v1 = Vector::<usize, 3>::new();
3624        let v2 = Vector3d::<usize>::new();
3625        let v3 = Vector3dUsize::new();
3626        tests.push(v1);
3627        tests.push(v2);
3628        tests.push(v3);
3629        for v in tests {
3630            assert_eq!(v[0], 0 as usize);
3631            assert_eq!(v[1], 0 as usize);
3632            assert_eq!(v[2], 0 as usize);
3633            assert_eq!(v.components.len(), 3);
3634        }
3635    }
3636
3637    #[test]
3638    fn vector_instantiation_new_isize() {
3639        // Two dimension
3640        let mut tests = vec![];
3641        let v1 = Vector::<isize, 2>::new();
3642        let v2 = Vector2d::<isize>::new();
3643        let v3 = Vector2dIsize::new();
3644        tests.push(v1);
3645        tests.push(v2);
3646        tests.push(v3);
3647        for v in tests {
3648            assert_eq!(v[0], 0 as isize);
3649            assert_eq!(v[1], 0 as isize);
3650            assert_eq!(v.components.len(), 2);
3651        }
3652
3653        // Three dimension
3654        let mut tests = vec![];
3655        let v1 = Vector::<isize, 3>::new();
3656        let v2 = Vector3d::<isize>::new();
3657        let v3 = Vector3dIsize::new();
3658        tests.push(v1);
3659        tests.push(v2);
3660        tests.push(v3);
3661        for v in tests {
3662            assert_eq!(v[0], 0 as isize);
3663            assert_eq!(v[1], 0 as isize);
3664            assert_eq!(v[2], 0 as isize);
3665            assert_eq!(v.components.len(), 3);
3666        }
3667    }
3668
3669    #[test]
3670    fn vector_instantiation_complex_i32() {
3671        let c1 = Complex::new(10_i32, 20_i32);
3672        let c2 = Complex::new(3_i32, -4_i32);
3673        let v: Vector<Complex<i32>, 2> = Vector::from([c1, c2]);
3674        assert_eq!(v[0].re, 10_i32);
3675        assert_eq!(v[0].im, 20_i32);
3676        assert_eq!(v[1].re, 3_i32);
3677        assert_eq!(v[1].im, -4_i32);
3678    }
3679
3680    #[test]
3681    fn vector_instantiation_complex_f64() {
3682        let c1 = Complex::new(10.0_f64, 20.0_f64);
3683        let c2 = Complex::new(3.1_f64, -4.2_f64);
3684        let v: Vector<Complex<f64>, 2> = Vector::from([c1, c2]);
3685        assert_relative_eq!(v[0].re, 10.0_f64);
3686        assert_relative_eq!(v[0].im, 20.0_f64);
3687        assert_relative_eq!(v[1].re, 3.1_f64);
3688        assert_relative_eq!(v[1].im, -4.2_f64);
3689    }
3690
3691    #[test]
3692    fn vector_instantiation_default_u32() {
3693        // Two dimension
3694        let v = Vector::<u32, 2>::default();
3695        assert_eq!(v[0], 0 as u32);
3696        assert_eq!(v[1], 0 as u32);
3697        assert_eq!(v.components.len(), 2);
3698
3699        // Three dimension
3700        let v = Vector::<u32, 3>::default();
3701        assert_eq!(v[0], 0 as u32);
3702        assert_eq!(v[1], 0 as u32);
3703        assert_eq!(v[2], 0 as u32);
3704        assert_eq!(v.components.len(), 3);
3705    }
3706
3707    #[test]
3708    fn vector_instantiation_default_f64() {
3709        // Two dimension
3710        let v = Vector::<f64, 2>::default();
3711        assert_relative_eq!(v[0], 0.0 as f64);
3712        assert_relative_eq!(v[1], 0.0 as f64);
3713        assert_eq!(v.components.len(), 2);
3714
3715        // Three dimension
3716        let v = Vector::<f64, 3>::default();
3717        assert_relative_eq!(v[0], 0.0 as f64);
3718        assert_relative_eq!(v[1], 0.0 as f64);
3719        assert_relative_eq!(v[2], 0.0 as f64);
3720        assert_eq!(v.components.len(), 3);
3721    }
3722
3723    #[test]
3724    fn vector_instantiation_complex_i32_default() {
3725        let v = Vector::<Complex<i32>, 2>::default();
3726        assert_eq!(v[0].re, 0_i32);
3727        assert_eq!(v[0].im, 0_i32);
3728    }
3729
3730    #[test]
3731    fn vector_instantiation_complex_f64_default() {
3732        let v = Vector::<Complex<f64>, 2>::default();
3733        assert_relative_eq!(v[0].re, 0.0_f64);
3734        assert_relative_eq!(v[0].im, 0.0_f64);
3735    }
3736
3737    #[test]
3738    fn vector_instantiation_from_array() {
3739        // Two dimension
3740        let v1 = Vector::<u32, 2>::from(&[1, 2]);
3741        let v2 = Vector::<f64, 2>::from(&[1.0, 2.0]);
3742        assert_eq!(v1[0], 1);
3743        assert_eq!(v1[1], 2);
3744        assert_eq!(v1.components.len(), 2);
3745
3746        assert_relative_eq!(v2[0], 1.0 as f64);
3747        assert_relative_eq!(v2[1], 2.0 as f64);
3748        assert_eq!(v2.components.len(), 2);
3749
3750        // Three dimension
3751        let v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
3752        let v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
3753        assert_eq!(v1[0], 1);
3754        assert_eq!(v1[1], 2);
3755        assert_eq!(v1[2], 3);
3756        assert_eq!(v1.components.len(), 3);
3757
3758        assert_relative_eq!(v2[0], 1.0 as f64);
3759        assert_relative_eq!(v2[1], 2.0 as f64);
3760        assert_relative_eq!(v2[2], 3.0 as f64);
3761        assert_eq!(v2.components.len(), 3);
3762    }
3763
3764    // ================================
3765    //
3766    // concurrency support
3767    //
3768    // ================================
3769
3770    #[test]
3771    fn vector_send_sync_concurrency_int() {
3772        let v = Vector::<i32, 2>::from([1, 2]);
3773
3774        let handle = std::thread::spawn(move || {
3775            println!("{:?}", v);
3776        });
3777
3778        handle.join().unwrap();
3779    }
3780
3781    #[test]
3782    fn vector_send_sync_concurrency_float() {
3783        let v = Vector::<f64, 2>::from([1.0, 2.0]);
3784
3785        let handle = std::thread::spawn(move || {
3786            println!("{:?}", v);
3787        });
3788
3789        handle.join().unwrap();
3790    }
3791
3792    #[test]
3793    fn vector_send_sync_concurrency_complex_float() {
3794        let v = Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
3795
3796        let handle = std::thread::spawn(move || {
3797            println!("{:?}", v);
3798        });
3799
3800        handle.join().unwrap();
3801    }
3802
3803    // ================================
3804    //
3805    // rel_eq_cmp method tests
3806    //
3807    // ================================
3808    #[test]
3809    fn vector_private_rel_eq_cmp() {
3810        let v: Vector<f64, 0> = Vector::new();
3811
3812        assert_eq!(v.rel_eq_cmp(&4.0, &4.0), Ordering::Equal);
3813        assert_eq!(v.rel_eq_cmp(&(0.1 + 0.2), &(0.15 + 0.15)), Ordering::Equal);
3814        assert_eq!(v.rel_eq_cmp(&4.1, &4.0), Ordering::Greater);
3815        assert_eq!(v.rel_eq_cmp(&4.0, &4.1), Ordering::Less);
3816        assert_eq!(v.rel_eq_cmp(&f64::INFINITY, &4.0), Ordering::Greater);
3817        assert_eq!(v.rel_eq_cmp(&f64::NEG_INFINITY, &4.0), Ordering::Less);
3818        assert_eq!(v.rel_eq_cmp(&f64::INFINITY, &-4.0), Ordering::Greater);
3819        assert_eq!(v.rel_eq_cmp(&f64::NEG_INFINITY, &-4.0), Ordering::Less);
3820        assert_eq!(v.rel_eq_cmp(&f64::INFINITY, &0.0), Ordering::Greater);
3821        assert_eq!(v.rel_eq_cmp(&f64::NEG_INFINITY, &0.0), Ordering::Less);
3822        assert_eq!(v.rel_eq_cmp(&f64::INFINITY, &-0.0), Ordering::Greater);
3823        assert_eq!(v.rel_eq_cmp(&f64::NEG_INFINITY, &-0.0), Ordering::Less);
3824        assert_eq!(v.rel_eq_cmp(&f64::INFINITY, &f64::INFINITY), Ordering::Equal);
3825        assert_eq!(v.rel_eq_cmp(&f64::NEG_INFINITY, &f64::NEG_INFINITY), Ordering::Equal);
3826        assert_eq!(v.rel_eq_cmp(&f64::INFINITY, &f64::NEG_INFINITY), Ordering::Greater);
3827        assert_eq!(v.rel_eq_cmp(&f64::NEG_INFINITY, &f64::INFINITY), Ordering::Less);
3828    }
3829
3830    #[test]
3831    #[should_panic(expected = "unable to determine order of NaN and 4.0")]
3832    fn vector_private_rel_eq_cmp_panic_nan_lhs() {
3833        let v: Vector<f64, 0> = Vector::new();
3834
3835        v.rel_eq_cmp(&f64::NAN, &4.0);
3836    }
3837
3838    #[test]
3839    #[should_panic(expected = "unable to determine order of 4.0 and NaN")]
3840    fn vector_private_rel_eq_cmp_panic_nan_rhs() {
3841        let v: Vector<f64, 0> = Vector::new();
3842
3843        v.rel_eq_cmp(&4.0, &f64::NAN);
3844    }
3845
3846    // ================================
3847    //
3848    // pretty method tests
3849    //
3850    // ================================
3851    #[test]
3852    fn vector_method_pretty() {
3853        let v1 = Vector::<i32, 2>::from([-1, 2]);
3854        let v2 = Vector::<f64, 2>::from([-1.0, 2.0]);
3855        let v3 =
3856            Vector::<Complex<f64>, 2>::from([Complex::new(-1.0, 2.0), Complex::new(3.0, -4.0)]);
3857
3858        assert_eq!(v1.pretty(), String::from("[\n    -1,\n    2,\n]"));
3859        assert_eq!(v2.pretty(), String::from("[\n    -1.0,\n    2.0,\n]"));
3860        assert_eq!(v3.pretty(), String::from("[\n    Complex {\n        re: -1.0,\n        im: 2.0,\n    },\n    Complex {\n        re: 3.0,\n        im: -4.0,\n    },\n]"));
3861    }
3862
3863    // ================================
3864    //
3865    // get method tests
3866    //
3867    // ================================
3868    #[test]
3869    fn vector_method_get_with_value() {
3870        let v1 = Vector::<u32, 2>::from([1, 2]);
3871        let v2 = Vector::<f64, 2>::from([1.0, 2.0]);
3872        assert_eq!(v1.get(0).unwrap(), &1);
3873        assert_eq!(v1.get(1).unwrap(), &2);
3874        assert_eq!(v1.get(2), None);
3875        assert_relative_eq!(v2.get(0).unwrap(), &1.0);
3876        assert_relative_eq!(v2.get(1).unwrap(), &2.0);
3877        assert_eq!(v2.get(2), None);
3878    }
3879
3880    #[test]
3881    fn vector_method_get_with_value_complex() {
3882        let v1 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
3883        let v2 = Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
3884        assert_eq!(v1.get(0).unwrap().re, 1);
3885        assert_eq!(v1.get(0).unwrap().im, 2);
3886        assert_eq!(v1.get(1).unwrap().re, 3);
3887        assert_eq!(v1.get(1).unwrap().im, 4);
3888        assert_eq!(v1.get(2), None);
3889
3890        assert_relative_eq!(v2.get(0).unwrap().re, 1.0);
3891        assert_relative_eq!(v2.get(0).unwrap().im, 2.0);
3892        assert_relative_eq!(v2.get(1).unwrap().re, 3.0);
3893        assert_relative_eq!(v2.get(1).unwrap().im, 4.0);
3894        assert_eq!(v2.get(2), None);
3895    }
3896
3897    #[test]
3898    fn vector_method_get_with_range() {
3899        let v1 = Vector::<u32, 5>::from(&[1, 2, 3, 4, 5]);
3900        let v2 = Vector::<f64, 5>::from(&[1.0, 2.0, 3.0, 4.0, 5.0]);
3901
3902        assert_eq!(v1.get(0..2).unwrap(), &[1, 2]);
3903        assert_eq!(v1.get(..2).unwrap(), &[1, 2]);
3904        assert_eq!(v1.get(2..).unwrap(), &[3, 4, 5]);
3905        assert_eq!(v1.get(..).unwrap(), &[1, 2, 3, 4, 5]);
3906        assert_eq!(v1.get(4..8), None);
3907
3908        assert_eq!(v2.get(0..2).unwrap(), &[1.0, 2.0]);
3909        assert_eq!(v2.get(..2).unwrap(), &[1.0, 2.0]);
3910        assert_eq!(v2.get(2..).unwrap(), &[3.0, 4.0, 5.0]);
3911        assert_eq!(v2.get(..).unwrap(), &[1.0, 2.0, 3.0, 4.0, 5.0]);
3912        assert_eq!(v2.get(4..8), None);
3913    }
3914
3915    #[test]
3916    fn vector_method_get_with_range_complex() {
3917        let v1 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
3918        let v2 = Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
3919        assert_eq!(v1.get(0..2).unwrap(), [Complex::new(1_i32, 2_i32), Complex::new(3_i32, 4_i32)]);
3920        assert_eq!(v1.get(..2).unwrap(), [Complex::new(1_i32, 2_i32), Complex::new(3_i32, 4_i32)]);
3921        assert_eq!(v1.get(1..).unwrap(), [Complex::new(3_i32, 4_i32)]);
3922        assert_eq!(v1.get(..).unwrap(), [Complex::new(1_i32, 2_i32), Complex::new(3_i32, 4_i32)]);
3923        assert_eq!(v1.get(4..8), None);
3924
3925        assert_eq!(
3926            v2.get(0..2).unwrap(),
3927            [Complex::new(1.0_f64, 2.0_f64), Complex::new(3.0_f64, 4.0_f64)]
3928        );
3929        assert_eq!(
3930            v2.get(..2).unwrap(),
3931            [Complex::new(1.0_f64, 2.0_f64), Complex::new(3.0_f64, 4.0_f64)]
3932        );
3933        assert_eq!(v2.get(1..).unwrap(), [Complex::new(3.0_f64, 4.0_f64)]);
3934        assert_eq!(
3935            v2.get(..).unwrap(),
3936            [Complex::new(1.0_f64, 2.0_f64), Complex::new(3.0_f64, 4.0_f64)]
3937        );
3938        assert_eq!(v2.get(4..8), None);
3939    }
3940
3941    #[test]
3942    fn vector_method_get_mut_with_value() {
3943        let mut v1 = Vector::<u32, 2>::from(&[1, 2]);
3944        let mut v2 = Vector::<f64, 2>::from(&[1.0, 2.0]);
3945
3946        let x1 = v1.get_mut(0).unwrap();
3947        assert_eq!(*x1, 1);
3948        *x1 = 10;
3949        assert_eq!(v1.components[0], 10);
3950        assert_eq!(v1.components[1], 2);
3951
3952        let x2 = v2.get_mut(0).unwrap();
3953        assert_relative_eq!(*x2, 1.0);
3954        *x2 = 10.0;
3955        assert_relative_eq!(v2.components[0], 10.0);
3956        assert_relative_eq!(v2.components[1], 2.0);
3957
3958        let mut v3 = Vector::<u32, 1>::default();
3959        let mut v4 = Vector::<f64, 1>::default();
3960        assert_eq!(v3.get_mut(10), None);
3961        assert_eq!(v4.get_mut(10), None);
3962    }
3963
3964    #[test]
3965    fn vector_method_get_mut_with_value_complex() {
3966        let mut v1 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
3967        let mut v2 =
3968            Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
3969
3970        let c1 = v1.get_mut(0).unwrap();
3971        assert_eq!(c1.re, 1);
3972        assert_eq!(c1.im, 2);
3973        c1.re = 5;
3974        c1.im = 6;
3975        assert_eq!(v1[0], Complex::new(5, 6));
3976        assert_eq!(v1[1], Complex::new(3, 4));
3977
3978        let c2 = v2.get_mut(0).unwrap();
3979        assert_relative_eq!(c2.re, 1.0);
3980        assert_relative_eq!(c2.im, 2.0);
3981        c2.re = 5.0;
3982        c2.im = 6.0;
3983        assert_relative_eq!(v2[0].re, 5.0);
3984        assert_relative_eq!(v2[0].im, 6.0);
3985        assert_relative_eq!(v2[1].re, 3.0);
3986        assert_relative_eq!(v2[1].im, 4.0);
3987    }
3988
3989    #[test]
3990    fn vector_method_get_mut_with_range() {
3991        let mut v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
3992        let mut v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
3993
3994        let r1 = v1.get_mut(0..2).unwrap();
3995        assert_eq!(*r1, [1, 2]);
3996        r1[0] = 5;
3997        r1[1] = 6;
3998        assert_eq!(v1.components, [5, 6, 3]);
3999
4000        let r2 = v2.get_mut(0..2).unwrap();
4001        assert_eq!(r2.len(), 2);
4002        assert_relative_eq!(r2[0], 1.0);
4003        assert_relative_eq!(r2[1], 2.0);
4004        r2[0] = 5.0;
4005        r2[1] = 6.0;
4006        assert_eq!(v2.components.len(), 3);
4007        assert_relative_eq!(v2.components[0], 5.0);
4008        assert_relative_eq!(v2.components[1], 6.0);
4009        assert_relative_eq!(v2.components[2], 3.0);
4010    }
4011
4012    #[test]
4013    fn vector_method_get_mut_with_range_complex() {
4014        let mut v1 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
4015        let mut v2 =
4016            Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
4017
4018        let r1 = v1.get_mut(0..2).unwrap();
4019        assert_eq!(r1, [Complex::new(1, 2), Complex::new(3, 4)]);
4020        r1[0].re = 5;
4021        r1[0].im = 6;
4022        assert_eq!(v1.components, [Complex::new(5, 6), Complex::new(3, 4)]);
4023
4024        let r2 = v2.get_mut(0..2).unwrap();
4025        assert_relative_eq!(r2[0].re, 1.0);
4026        assert_relative_eq!(r2[0].im, 2.0);
4027        assert_relative_eq!(r2[1].re, 3.0);
4028        assert_relative_eq!(r2[1].im, 4.0);
4029        r2[0].re = 5.0;
4030        r2[0].im = 6.0;
4031        assert_relative_eq!(v2[0].re, 5.0);
4032        assert_relative_eq!(v2[0].im, 6.0);
4033        assert_relative_eq!(v2[1].re, 3.0);
4034        assert_relative_eq!(v2[1].im, 4.0);
4035    }
4036
4037    // ================================
4038    //
4039    // as_* method tests
4040    //
4041    // ================================
4042    #[test]
4043    fn vector_method_as_slice() {
4044        let v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
4045        let v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
4046        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
4047        let v4 = Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
4048        let _: &[u32] = v1.as_slice();
4049        let _: &[f64] = v2.as_slice();
4050        let _: &[Complex<i32>] = v3.as_slice();
4051        let _: &[Complex<f64>] = v4.as_slice();
4052    }
4053
4054    #[test]
4055    fn vector_method_as_mut_slice() {
4056        let mut v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
4057        let mut v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
4058        let mut v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
4059        let mut v4 =
4060            Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
4061        let _: &mut [u32] = v1.as_mut_slice();
4062        let _: &mut [f64] = v2.as_mut_slice();
4063        let _: &mut [Complex<i32>] = v3.as_mut_slice();
4064        let _: &mut [Complex<f64>] = v4.as_mut_slice();
4065    }
4066
4067    #[test]
4068    fn vector_method_as_array() {
4069        let v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
4070        let v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
4071        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
4072        let v4 = Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
4073        let _: &[u32; 3] = v1.as_array();
4074        let _: &[f64; 3] = v2.as_array();
4075        let _: &[Complex<i32>; 2] = v3.as_array();
4076        let _: &[Complex<f64>; 2] = v4.as_array();
4077    }
4078
4079    #[test]
4080    fn vector_method_as_mut_array() {
4081        let mut v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
4082        let mut v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
4083        let mut v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
4084        let mut v4 =
4085            Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
4086        let _: &mut [u32; 3] = v1.as_mut_array();
4087        let _: &mut [f64; 3] = v2.as_mut_array();
4088        let _: &mut [Complex<i32>; 2] = v3.as_mut_array();
4089        let _: &mut [Complex<f64>; 2] = v4.as_mut_array();
4090    }
4091
4092    // ================================
4093    //
4094    // to_array / to_vec method tests
4095    //
4096    // ================================
4097    #[test]
4098    fn vector_method_to_array() {
4099        let v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
4100        let v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
4101        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
4102        let v4 = Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
4103        let _: [u32; 3] = v1.to_array();
4104        let _: [f64; 3] = v2.to_array();
4105        let _: [Complex<i32>; 2] = v3.to_array();
4106        let _: [Complex<f64>; 2] = v4.to_array();
4107    }
4108
4109    #[test]
4110    fn vector_method_to_vec() {
4111        let v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
4112        let v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
4113        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
4114        let v4 = Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
4115        let _: Vec<u32> = v1.to_vec();
4116        let _: Vec<f64> = v2.to_vec();
4117        let _: Vec<Complex<i32>> = v3.to_vec();
4118        let _: Vec<Complex<f64>> = v4.to_vec();
4119    }
4120
4121    // ================================
4122    //
4123    // enumerate method tests
4124    //
4125    // ================================
4126    #[test]
4127    fn vector_method_enumerate() {
4128        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
4129        let mut iter1 = v1.enumerate();
4130
4131        assert_eq!(iter1.next(), Some((0, &1)));
4132        assert_eq!(iter1.next(), Some((1, &2)));
4133        assert_eq!(iter1.next(), Some((2, &3)));
4134        assert_eq!(iter1.next(), None);
4135
4136        // empty vector
4137        let v2: Vector<i32, 0> = Vector::new();
4138        let mut iter2 = v2.enumerate();
4139
4140        assert_eq!(iter2.next(), None);
4141    }
4142
4143    // ================================
4144    //
4145    // to_num_cast method tests
4146    //
4147    // ================================
4148
4149    #[test]
4150    fn vector_to_num_cast() {
4151        // ~~~~~~~~~~~~~~~~~~
4152        // Float to int tests
4153        // ~~~~~~~~~~~~~~~~~~
4154        let v = Vector::<f32, 3>::from([1.12, 2.50, 3.99]);
4155
4156        // Float to int type with default trunc
4157        let i64_trunc_v = v.to_num_cast(|x| x as i64);
4158        assert_eq!(i64_trunc_v, Vector::<i64, 3>::from([1, 2, 3]));
4159
4160        // Float to int type with round
4161        let i64_round_v = v.to_num_cast(|x| x.round() as i64);
4162        assert_eq!(i64_round_v, Vector::<i64, 3>::from([1, 3, 4]));
4163
4164        // Float to int type with ceil
4165        let i64_ceil_v = v.to_num_cast(|x| x.ceil() as i64);
4166        assert_eq!(i64_ceil_v, Vector::<i64, 3>::from([2, 3, 4]));
4167
4168        // Float to int type with floor
4169        let i64_floor_v = v.to_num_cast(|x| x.floor() as i64);
4170        assert_eq!(i64_floor_v, Vector::<i64, 3>::from([1, 2, 3]));
4171
4172        // ~~~~~~~~~~~~~~~~~~
4173        // Int to float tests
4174        // ~~~~~~~~~~~~~~~~~~
4175        let v = Vector::<i32, 3>::from([1, 2, 3]);
4176
4177        let f64_v = v.to_num_cast(|x| x as f64);
4178        assert_eq!(f64_v, Vector::<f64, 3>::from([1.0, 2.0, 3.0]));
4179
4180        let v = Vector::<i16, 3>::from([1, 2, 3]);
4181
4182        let f32_v = v.to_num_cast(|x| x as f32);
4183        assert_eq!(f32_v, Vector::<f32, 3>::from([1.0, 2.0, 3.0]));
4184    }
4185
4186    #[test]
4187    fn vector_to_num_cast_complex() {
4188        let v = Vector::<Complex<i32>, 2>::from([Complex::new(1, 0), Complex::new(3, 4)]);
4189
4190        let v_i64: Vector<Complex<i64>, 2> =
4191            v.to_num_cast(|x| Complex { re: x.re as i64, im: x.im as i64 });
4192
4193        assert!(v_i64.len() == 2);
4194        assert_eq!(v_i64[0].re, 1_i64);
4195        assert_eq!(v_i64[0].im, 0_i64);
4196        assert_eq!(v_i64[1].re, 3_i64);
4197        assert_eq!(v_i64[1].im, 4_i64);
4198    }
4199
4200    #[test]
4201    fn vector_to_num_cast_safety() {
4202        let v = Vector::<f64, 2>::from([f64::MAX, 1.00]);
4203        let i8_v = v.to_num_cast(|x| x as i8);
4204
4205        // Rust 1.45+ overflows are handled with a saturating cast.
4206        assert_eq!(i8_v[0], f64::MAX as i8);
4207        assert_eq!(i8_v[0], i8::MAX);
4208        assert_eq!(i8_v[0], 127);
4209
4210        let v = Vector::<i64, 2>::from([i64::MIN, 1]);
4211        let u8_v_2 = v.to_num_cast(|x| x as u8);
4212
4213        // signed to unsigned can change the value and eliminate the unary neg num sign
4214        // underflows saturate too
4215        assert_eq!(u8_v_2[0], i64::MIN as u8);
4216        assert_eq!(u8_v_2[0], u8::MIN);
4217        assert_eq!(u8_v_2[0], 0);
4218
4219        let v = Vector::<f64, 2>::from([f64::NAN, 1.00]);
4220        let u8_v_3 = v.to_num_cast(|x| x as u8);
4221
4222        // NAN casts to zero value
4223        assert_eq!(u8_v_3[0], f64::NAN as u8);
4224        assert_eq!(u8_v_3[0], 0);
4225    }
4226
4227    // ================================
4228    //
4229    // to_[TYPE] numeric type cast method tests
4230    //
4231    // ================================
4232
4233    #[test]
4234    fn vector_method_to_type_numeric_casts() {
4235        let v_u8: Vector<u8, 2> = Vector::from([1, 2]);
4236        let v_i8: Vector<i8, 2> = Vector::from([-1, 2]);
4237        let v_f32: Vector<f32, 2> = Vector::from([1.0, 2.0]);
4238        let v_f64: Vector<f32, 2> = Vector::from([-1.0, 2.0]);
4239        let v_complex_without_im: Vector<Complex<f32>, 2> =
4240            Vector::from([Complex::new(1.0, 0.0), Complex::new(2.0, 0.0)]);
4241        let v_complex_with_im: Vector<Complex<f32>, 2> =
4242            Vector::from([Complex::new(1.0, 1.0), Complex::new(2.0, 1.0)]);
4243
4244        assert_eq!(v_u8.to_u16().unwrap().components, [1 as u16, 2 as u16]);
4245        assert_eq!(v_u8.to_u32().unwrap().components, [1 as u32, 2 as u32]);
4246        assert_eq!(v_u8.to_u64().unwrap().components, [1 as u64, 2 as u64]);
4247        assert_eq!(v_u8.to_u128().unwrap().components, [1 as u128, 2 as u128]);
4248        assert_eq!(v_u8.to_i16().unwrap().components, [1 as i16, 2 as i16]);
4249        assert_eq!(v_u8.to_i32().unwrap().components, [1 as i32, 2 as i32]);
4250        assert_eq!(v_u8.to_i64().unwrap().components, [1 as i64, 2 as i64]);
4251        assert_eq!(v_u8.to_i128().unwrap().components, [1 as i128, 2 as i128]);
4252        assert_eq!(v_u8.to_f32().unwrap(), Vector::<f32, 2>::from([1.0, 2.0]));
4253        assert_eq!(v_u8.to_f64().unwrap(), Vector::<f64, 2>::from([1.0, 2.0]));
4254
4255        // contains neg values so cast to unsigned type returns None
4256        assert_eq!(v_i8.to_u16(), None);
4257        assert_eq!(v_i8.to_u32(), None);
4258        assert_eq!(v_i8.to_u64(), None);
4259        assert_eq!(v_i8.to_u128(), None);
4260        assert_eq!(v_i8.to_i16().unwrap().components, [-1 as i16, 2 as i16]);
4261        assert_eq!(v_i8.to_i32().unwrap().components, [-1 as i32, 2 as i32]);
4262        assert_eq!(v_i8.to_i64().unwrap().components, [-1 as i64, 2 as i64]);
4263        assert_eq!(v_i8.to_i128().unwrap().components, [-1 as i128, 2 as i128]);
4264        assert_eq!(v_i8.to_f32().unwrap(), Vector::<f32, 2>::from([-1.0, 2.0]));
4265        assert_eq!(v_i8.to_f64().unwrap(), Vector::<f64, 2>::from([-1.0, 2.0]));
4266
4267        // float to unsigned int type returns a value when contents are all positive
4268        // data of appropriate number range
4269        assert_eq!(v_f32.to_u16().unwrap().components, [1 as u16, 2 as u16]);
4270        assert_eq!(v_f32.to_u32().unwrap().components, [1 as u32, 2 as u32]);
4271        assert_eq!(v_f32.to_u64().unwrap().components, [1 as u64, 2 as u64]);
4272        assert_eq!(v_f32.to_u128().unwrap().components, [1 as u128, 2 as u128]);
4273        assert_eq!(v_f32.to_i16().unwrap().components, [1 as i16, 2 as i16]);
4274        assert_eq!(v_f32.to_i32().unwrap().components, [1 as i32, 2 as i32]);
4275        assert_eq!(v_f32.to_i64().unwrap().components, [1 as i64, 2 as i64]);
4276        assert_eq!(v_f32.to_i128().unwrap().components, [1 as i128, 2 as i128]);
4277        assert_eq!(v_f32.to_f32().unwrap(), Vector::<f32, 2>::from([1.0, 2.0]));
4278        assert_eq!(v_f32.to_f64().unwrap(), Vector::<f64, 2>::from([1.0, 2.0]));
4279
4280        // contains neg values so cast to unsigned type returns None
4281        assert_eq!(v_f64.to_u16(), None);
4282        assert_eq!(v_f64.to_u32(), None);
4283        assert_eq!(v_f64.to_u64(), None);
4284        assert_eq!(v_f64.to_u128(), None);
4285        assert_eq!(v_f64.to_i16().unwrap().components, [-1 as i16, 2 as i16]);
4286        assert_eq!(v_f64.to_i32().unwrap().components, [-1 as i32, 2 as i32]);
4287        assert_eq!(v_f64.to_i64().unwrap().components, [-1 as i64, 2 as i64]);
4288        assert_eq!(v_f64.to_i128().unwrap().components, [-1 as i128, 2 as i128]);
4289        assert_eq!(v_f64.to_f32().unwrap(), Vector::<f32, 2>::from([-1.0, 2.0]));
4290        assert_eq!(v_f64.to_f64().unwrap(), Vector::<f64, 2>::from([-1.0, 2.0]));
4291
4292        // complex numbers cast when imaginary part is zero
4293        assert_eq!(v_complex_without_im.to_u16().unwrap().components, [1 as u16, 2 as u16]);
4294        assert_eq!(v_complex_without_im.to_u32().unwrap().components, [1 as u32, 2 as u32]);
4295        assert_eq!(v_complex_without_im.to_u64().unwrap().components, [1 as u64, 2 as u64]);
4296        assert_eq!(v_complex_without_im.to_u128().unwrap().components, [1 as u128, 2 as u128]);
4297        assert_eq!(v_complex_without_im.to_i16().unwrap().components, [1 as i16, 2 as i16]);
4298        assert_eq!(v_complex_without_im.to_i32().unwrap().components, [1 as i32, 2 as i32]);
4299        assert_eq!(v_complex_without_im.to_i64().unwrap().components, [1 as i64, 2 as i64]);
4300        assert_eq!(v_complex_without_im.to_i128().unwrap().components, [1 as i128, 2 as i128]);
4301        assert_eq!(v_complex_without_im.to_f32().unwrap(), Vector::<f32, 2>::from([1.0, 2.0]));
4302        assert_eq!(v_complex_without_im.to_f64().unwrap(), Vector::<f64, 2>::from([1.0, 2.0]));
4303
4304        // complex numbers return None when imaginary part is non-zero
4305        assert_eq!(v_complex_with_im.to_u16(), None);
4306        assert_eq!(v_complex_with_im.to_u32(), None);
4307        assert_eq!(v_complex_with_im.to_u64(), None);
4308        assert_eq!(v_complex_with_im.to_u128(), None);
4309        assert_eq!(v_complex_with_im.to_i16(), None);
4310        assert_eq!(v_complex_with_im.to_i32(), None);
4311        assert_eq!(v_complex_with_im.to_i64(), None);
4312        assert_eq!(v_complex_with_im.to_i128(), None);
4313        assert_eq!(v_complex_with_im.to_f32(), None);
4314        assert_eq!(v_complex_with_im.to_f64(), None);
4315    }
4316
4317    // ================================
4318    //
4319    // len and is_empty method tests
4320    //
4321    // ================================
4322    #[test]
4323    fn vector_method_len_is_empty() {
4324        let v = Vector::<u32, 3>::from(&[1, 2, 3]);
4325        let v_empty = Vector::<u32, 0>::from(&[]);
4326        assert_eq!(v.len(), 3);
4327        assert_eq!(v_empty.len(), 0);
4328        assert!(v_empty.is_empty());
4329    }
4330
4331    // ================================
4332    //
4333    // dot method tests
4334    //
4335    // ================================
4336    #[test]
4337    fn vector_method_dot() {
4338        // Note: this method *should* support valid dot products
4339        // with 2-length Vector *as* complex numbers, where item
4340        // 0 is the real part and item 1 is the imaginary part;
4341        // however it is not appropriate for use with Vector
4342        // of complex number types (i.e. each item in the Vector
4343        // is a complex number).
4344        let v1: Vector<i32, 3> = Vector::from([1, 3, -5]);
4345        let v2: Vector<i32, 3> = Vector::from([4, -2, -1]);
4346        let x1 = v1 * 3;
4347        let x2 = v2 * 6;
4348        assert_eq!(v1.dot(&v2), 3);
4349        assert_eq!(v2.dot(&v1), 3);
4350        assert_eq!(-v1.dot(&-v2), 3);
4351        assert_eq!(x1.dot(&x2), (3 * 6) * v1.dot(&v2));
4352
4353        let v1: Vector<f64, 3> = Vector::from([1.0, 3.0, -5.0]);
4354        let v2: Vector<f64, 3> = Vector::from([4.0, -2.0, -1.0]);
4355        let x1 = v1 * 3.0;
4356        let x2 = v2 * 6.0;
4357        assert_relative_eq!(v1.dot(&v2), 3.0);
4358        assert_relative_eq!(v2.dot(&v1), 3.0);
4359        assert_relative_eq!(-v1.dot(&-v2), 3.0);
4360        assert_relative_eq!(x1.dot(&x2), (3.0 * 6.0) * v1.dot(&v2));
4361    }
4362
4363    // ================================
4364    //
4365    // magnitude method tests
4366    //
4367    // ================================
4368
4369    #[test]
4370    fn vector_method_magnitude_int() {
4371        let v1: Vector<i32, 2> = Vector::from([2, 2]);
4372        let v2: Vector<i32, 2> = Vector::from([-2, -2]);
4373        let v1_f: Vector<f64, 2> = v1.into();
4374        let v2_f: Vector<f64, 2> = v2.into();
4375        assert_relative_eq!(v1_f.magnitude(), 2.8284271247461903);
4376        assert_relative_eq!(v2_f.magnitude(), 2.8284271247461903);
4377    }
4378
4379    #[test]
4380    fn vector_method_magnitude_float() {
4381        let v1: Vector<f64, 2> = Vector::from([2.8, 2.6]);
4382        let v2: Vector<f64, 2> = Vector::from([-2.8, -2.6]);
4383
4384        assert_relative_eq!(v1.magnitude(), 3.82099463490856);
4385        assert_relative_eq!(v2.magnitude(), 3.82099463490856);
4386    }
4387
4388    // ================================
4389    //
4390    // normalize method tests
4391    //
4392    // ================================
4393
4394    #[test]
4395    fn vector_method_normalize() {
4396        let v1: Vector<f64, 2> = Vector::from([25.123, 30.456]);
4397        let v2: Vector<f64, 2> = Vector::from([-25.123, -30.456]);
4398        let mut v3: Vector<f64, 2> = Vector::from([25.123, 30.456]);
4399        let mut v4: Vector<f64, 2> = Vector::from([-25.123, -30.456]);
4400        assert_relative_eq!(v1.normalize().magnitude(), 1.0);
4401        assert_relative_eq!(v2.normalize().magnitude(), 1.0);
4402        // normalize does not mutate the calling Vector
4403        assert_relative_eq!(v1[0], 25.123);
4404        assert_relative_eq!(v1[1], 30.456);
4405
4406        assert_relative_eq!(v3.mut_normalize().magnitude(), 1.0);
4407        assert_relative_eq!(v4.mut_normalize().magnitude(), 1.0);
4408        // mut_normalize does mutate the calling Vector
4409        assert_relative_eq!(v3[0], 0.6363347262144607);
4410        assert_relative_eq!(v3[1], 0.7714130645857428);
4411
4412        assert_eq!((v1.normalize() * v1.magnitude()).magnitude(), v1.magnitude());
4413    }
4414
4415    // ================================
4416    //
4417    // lerp method tests
4418    //
4419    // ================================
4420    #[test]
4421    fn vector_method_lerp() {
4422        let v1: Vector<f64, 2> = Vector::from([0.0, 0.0]);
4423        let v2: Vector<f64, 2> = Vector::from([10.0, 10.0]);
4424
4425        // the value at weight 0 is the start vector
4426        assert_eq!(v1.lerp(&v2, 0.0).unwrap(), v1);
4427        // values move from start to end
4428        assert_eq!(v1.lerp(&v2, 0.25).unwrap(), Vector::from([2.5, 2.5]));
4429        assert_eq!(v1.lerp(&v2, 0.5).unwrap(), Vector::from([5.0, 5.0]));
4430        assert_eq!(v1.lerp(&v2, 0.75).unwrap(), Vector::from([7.5, 7.5]));
4431        // the value at weight 1 is the end vector
4432        assert_eq!(v1.lerp(&v2, 1.0).unwrap(), v2);
4433
4434        // if start == end, the value at any weight will always be start (equivalent to end)
4435        assert_eq!(v2.lerp(&v2, 0.0).unwrap(), Vector::from([10.0, 10.0]));
4436        assert_eq!(v2.lerp(&v2, 0.1).unwrap(), Vector::from([10.0, 10.0]));
4437        assert_eq!(v2.lerp(&v2, 0.2).unwrap(), Vector::from([10.0, 10.0]));
4438        assert_eq!(v2.lerp(&v2, 0.3).unwrap(), Vector::from([10.0, 10.0]));
4439        assert_eq!(v2.lerp(&v2, 0.4).unwrap(), Vector::from([10.0, 10.0]));
4440        assert_eq!(v2.lerp(&v2, 0.5).unwrap(), Vector::from([10.0, 10.0]));
4441        assert_eq!(v2.lerp(&v2, 0.6).unwrap(), Vector::from([10.0, 10.0]));
4442        assert_eq!(v2.lerp(&v2, 0.7).unwrap(), Vector::from([10.0, 10.0]));
4443        assert_eq!(v2.lerp(&v2, 0.8).unwrap(), Vector::from([10.0, 10.0]));
4444        assert_eq!(v2.lerp(&v2, 1.0).unwrap(), Vector::from([10.0, 10.0]));
4445
4446        let v1: Vector<f64, 2> = Vector::from([0.0, 0.0]);
4447        let v2: Vector<f64, 2> = Vector::from([-10.0, -10.0]);
4448
4449        // the value at weight 0 is the start vector
4450        assert_eq!(v1.lerp(&v2, 0.0).unwrap(), v1);
4451        // values move from start to end
4452        assert_eq!(v1.lerp(&v2, 0.25).unwrap(), Vector::from([-2.5, -2.5]));
4453        assert_eq!(v1.lerp(&v2, 0.5).unwrap(), Vector::from([-5.0, -5.0]));
4454        assert_eq!(v1.lerp(&v2, 0.75).unwrap(), Vector::from([-7.5, -7.5]));
4455        // value at weight 1 is the end vector
4456        assert_eq!(v1.lerp(&v2, 1.0).unwrap(), v2);
4457
4458        // if start == end, the value at any weight will always be start (equivalent to end)
4459        assert_eq!(v2.lerp(&v2, 0.0).unwrap(), Vector::from([-10.0, -10.0]));
4460        assert_eq!(v2.lerp(&v2, 0.1).unwrap(), Vector::from([-10.0, -10.0]));
4461        assert_eq!(v2.lerp(&v2, 0.2).unwrap(), Vector::from([-10.0, -10.0]));
4462        assert_eq!(v2.lerp(&v2, 0.3).unwrap(), Vector::from([-10.0, -10.0]));
4463        assert_eq!(v2.lerp(&v2, 0.4).unwrap(), Vector::from([-10.0, -10.0]));
4464        assert_eq!(v2.lerp(&v2, 0.5).unwrap(), Vector::from([-10.0, -10.0]));
4465        assert_eq!(v2.lerp(&v2, 0.6).unwrap(), Vector::from([-10.0, -10.0]));
4466        assert_eq!(v2.lerp(&v2, 0.7).unwrap(), Vector::from([-10.0, -10.0]));
4467        assert_eq!(v2.lerp(&v2, 0.8).unwrap(), Vector::from([-10.0, -10.0]));
4468        assert_eq!(v2.lerp(&v2, 1.0).unwrap(), Vector::from([-10.0, -10.0]));
4469
4470        // higher dimension tests
4471        let v1: Vector<f64, 3> = Vector::from([-10.0, -10.0, -10.0]);
4472        let v2: Vector<f64, 3> = Vector::from([10.0, 10.0, 10.0]);
4473
4474        assert_eq!(v1.lerp(&v2, 0.0).unwrap(), v1);
4475        assert_eq!(v1.lerp(&v2, 0.25).unwrap(), Vector::from([-5.0, -5.0, -5.0]));
4476        assert_eq!(v1.lerp(&v2, 0.5).unwrap(), Vector::from([0.0, 0.0, 0.0]));
4477        assert_eq!(v1.lerp(&v2, 0.75).unwrap(), Vector::from([5.0, 5.0, 5.0]));
4478        assert_eq!(v1.lerp(&v2, 1.0).unwrap(), v2);
4479
4480        // NaN tests
4481        let v1: Vector<f64, 2> = Vector::from([0.0, 0.0]);
4482        let v2: Vector<f64, 2> = Vector::from([f64::NAN, 10.0]);
4483        let v3: Vector<f64, 2> = Vector::from([f64::NAN, f64::NAN]);
4484
4485        // interpolation with NaN does not fail and interpolated value
4486        // is always NaN
4487        let v_res_1 = v1.lerp(&v2, 0.5).unwrap();
4488        assert!(v_res_1[0].is_nan());
4489        assert_relative_eq!(v_res_1[1], 5.0);
4490
4491        let v_res_2 = v2.lerp(&v3, 0.5).unwrap();
4492        assert!(v_res_2[0].is_nan());
4493        assert!(v_res_2[1].is_nan());
4494    }
4495
4496    #[test]
4497    fn vector_method_lerp_bounds_checks() {
4498        let v1: Vector<f64, 2> = Vector::from([0.0, 0.0]);
4499        let v2: Vector<f64, 2> = Vector::from([10.0, 10.0]);
4500
4501        let err1 = v1.lerp(&v2, -0.01);
4502        let err2 = v1.lerp(&v2, 1.01);
4503
4504        assert!(err1.is_err());
4505        assert!(matches!(err1, Err(VectorError::ValueError(_))));
4506        assert!(err2.is_err());
4507        assert!(matches!(err2, Err(VectorError::ValueError(_))));
4508    }
4509
4510    #[test]
4511    fn vector_method_lerp_bounds_check_nan() {
4512        let v1: Vector<f64, 2> = Vector::from([0.0, 0.0]);
4513        let v2: Vector<f64, 2> = Vector::from([10.0, 10.0]);
4514
4515        let v_res = v1.lerp(&v2, f64::NAN);
4516        assert!(v_res.is_err());
4517        assert!(matches!(v_res, Err(VectorError::ValueError(_))));
4518    }
4519
4520    // ================================
4521    //
4522    // midpoint method tests
4523    //
4524    // ================================
4525
4526    #[test]
4527    fn vector_method_midpoint() {
4528        let v1: Vector<f64, 2> = Vector::from([0.0, 0.0]);
4529        let v2: Vector<f64, 2> = Vector::from([10.0, 10.0]);
4530
4531        assert_eq!(v1.midpoint(&v2), Vector::from([5.0, 5.0]));
4532
4533        let v1: Vector<f64, 2> = Vector::from([0.0, 0.0]);
4534        let v2: Vector<f64, 2> = Vector::from([-10.0, -10.0]);
4535
4536        assert_eq!(v1.midpoint(&v2), Vector::from([-5.0, -5.0]));
4537
4538        let v1: Vector<f64, 3> = Vector::from([-10.0, -10.0, -10.0]);
4539        let v2: Vector<f64, 3> = Vector::from([10.0, 10.0, 10.0]);
4540
4541        assert_eq!(v1.midpoint(&v2), Vector::zero());
4542
4543        // NaN tests
4544        let v1: Vector<f64, 2> = Vector::from([0.0, 0.0]);
4545        let v2: Vector<f64, 2> = Vector::from([f64::NAN, 10.0]);
4546        let v3: Vector<f64, 2> = Vector::from([f64::NAN, f64::NAN]);
4547
4548        // interpolation with NaN does not fail and midpoint value
4549        // is always NaN
4550        let v_res_1 = v1.midpoint(&v2);
4551        assert!(v_res_1[0].is_nan());
4552        assert_relative_eq!(v_res_1[1], 5.0);
4553
4554        let v_res_2 = v2.midpoint(&v3);
4555        assert!(v_res_2[0].is_nan());
4556        assert!(v_res_2[1].is_nan());
4557    }
4558
4559    // ================================
4560    //
4561    // sum method tests
4562    //
4563    // ================================
4564    #[test]
4565    fn vector_method_sum() {
4566        let v1 = Vector::<i32, 3>::from([-1, 2, 3]);
4567
4568        assert_eq!(v1.sum(), 4);
4569
4570        let v2 = Vector::<f64, 3>::from([-1.0, 2.0, 3.0]);
4571
4572        assert_relative_eq!(v2.sum(), 4.0);
4573
4574        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, -2), Complex::new(5, -6)]);
4575
4576        assert_eq!(v3.sum(), Complex::new(6, -8));
4577
4578        // zero floating point values
4579        let v4 = Vector::<f64, 3>::from([0.0, -1.0, 5.0]);
4580
4581        assert_relative_eq!(v4.sum(), 4.0);
4582
4583        // postiive infinity floating point values
4584        let v5 = Vector::<f64, 3>::from([f64::INFINITY, 1.0, 2.0]);
4585
4586        assert_eq!(v5.sum(), f64::INFINITY);
4587        assert!(v5.sum().is_infinite());
4588
4589        // negative infinity floating point values
4590        let v6 = Vector::<f64, 3>::from([f64::NEG_INFINITY, 1.0, 2.0]);
4591
4592        assert_eq!(v6.sum(), f64::NEG_INFINITY);
4593        assert!(v6.sum().is_infinite());
4594
4595        // NaN floating point values
4596        let v7 = Vector::<f64, 3>::from([f64::NAN, 1.0, 2.0]);
4597
4598        assert!(v7.sum().is_nan());
4599    }
4600
4601    // ================================
4602    //
4603    // product method tests
4604    //
4605    // ================================
4606    #[test]
4607    fn vector_method_product() {
4608        let v1 = Vector::<i32, 3>::from([-1, 2, 3]);
4609
4610        assert_eq!(v1.product(), -6);
4611
4612        let v2 = Vector::<f64, 3>::from([-1.0, 2.0, 3.0]);
4613
4614        assert_relative_eq!(v2.product(), -6.0);
4615
4616        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, -2), Complex::new(5, -6)]);
4617
4618        assert_eq!(v3.product(), Complex::new(-7, -16));
4619
4620        // -------------
4621        // zero
4622        // -------------
4623        let v_int_zero = Vector::<i32, 3>::from([0, -2, 3]);
4624
4625        assert_eq!(v_int_zero.product(), 0);
4626
4627        let v_float_zero = Vector::<f64, 3>::from([0.0, -2.0, 3.0]);
4628
4629        assert_relative_eq!(v_float_zero.product(), 0.0);
4630
4631        let v_complex_zero =
4632            Vector::<Complex<i32>, 2>::from([Complex::new(0, 0), Complex::new(5, -6)]);
4633
4634        assert_eq!(v_complex_zero.product(), Complex::new(0, 0));
4635
4636        // -------------------------
4637        // floating point infinities
4638        // -------------------------
4639        let v_pos_inf = Vector::<f64, 3>::from([f64::INFINITY, 1.0, 2.0]);
4640
4641        assert_eq!(v_pos_inf.product(), f64::INFINITY);
4642        assert!(v_pos_inf.product().is_infinite());
4643
4644        let v_neg_inf = Vector::<f64, 3>::from([f64::NEG_INFINITY, 1.0, 2.0]);
4645
4646        assert_eq!(v_neg_inf.product(), f64::NEG_INFINITY);
4647        assert!(v_neg_inf.product().is_infinite());
4648
4649        // -------------------
4650        // floating point NaN
4651        // -------------------
4652
4653        let v_nan = Vector::<f64, 3>::from([f64::NAN, 1.0, 2.0]);
4654
4655        assert!(v_nan.product().is_nan());
4656
4657        // -------------
4658        // special cases
4659        // -------------
4660
4661        // zero-dimension Vector should return zero value for numeric type
4662        let v_int_zero_ele = Vector::<i32, 0>::new();
4663        let v_float_zero_ele = Vector::<f64, 0>::new();
4664        let v_complex_zero_ele = Vector::<Complex<i32>, 0>::new();
4665
4666        assert_eq!(v_int_zero_ele.product(), 0);
4667        assert_relative_eq!(v_float_zero_ele.product(), 0.0);
4668        assert_eq!(v_complex_zero_ele.product(), Complex::new(0, 0));
4669
4670        // one-dimension Vector should return value at index 0
4671        let v_int_one_ele = Vector::<i32, 1>::from([10]);
4672        let v_float_one_ele = Vector::<f64, 1>::from([10.0]);
4673        let v_complex_one_ele = Vector::<Complex<i32>, 1>::from([Complex::new(10, 1)]);
4674
4675        assert_eq!(v_int_one_ele.product(), 10);
4676        assert_relative_eq!(v_float_one_ele.product(), 10.0);
4677        assert_eq!(v_complex_one_ele.product(), Complex::new(10, 1));
4678    }
4679
4680    // ================================
4681    //
4682    // mean method tests
4683    //
4684    // ================================
4685    #[test]
4686    fn vector_method_mean() {
4687        let v1_f32: Vector<f32, 5> = Vector::from([1.0, 2.0, 3.0, 4.0, 5.0]);
4688        let v1_f64: Vector<f64, 5> = Vector::from([1.0, 2.0, 3.0, 4.0, 5.0]);
4689
4690        assert_relative_eq!(v1_f32.mean().unwrap(), 3.0);
4691        assert_relative_eq!(v1_f64.mean().unwrap(), 3.0);
4692
4693        let v1_f64_mean = v1_f64.mean().unwrap();
4694
4695        // sum of residuals = zero
4696        assert_relative_eq!(
4697            (v1_f64[0] - v1_f64_mean)
4698                + (v1_f64[1] - v1_f64_mean)
4699                + (v1_f64[2] - v1_f64_mean)
4700                + (v1_f64[3] - v1_f64_mean)
4701                + (v1_f64[4] - v1_f64_mean),
4702            0.0
4703        );
4704
4705        // 1-Vector mean = contained value
4706        let v2: Vector<f64, 1> = Vector::from([5.0]);
4707        assert_relative_eq!(v2.mean().unwrap(), 5.0);
4708
4709        // negative values
4710        let v3: Vector<f64, 5> = Vector::from([-4.0, 2.0, 3.0, 4.0, 5.0]);
4711        assert_relative_eq!(v3.mean().unwrap(), 2.0);
4712
4713        // identical values
4714        let v4: Vector<f64, 5> = Vector::from([10.0, 10.0, 10.0, 10.0, 10.0]);
4715        assert_relative_eq!(v4.mean().unwrap(), 10.0);
4716
4717        // zero vector
4718        let v_zero: Vector<f64, 5> = Vector::zero();
4719        assert_relative_eq!(v_zero.mean().unwrap(), 0.0);
4720
4721        // NaN data
4722        let v_nan: Vector<f64, 5> = Vector::from([f64::NAN, 2.0, 3.0, 4.0, 5.0]);
4723        assert!(v_nan.mean().unwrap().is_nan());
4724
4725        // infinities
4726        let v_pos_inf: Vector<f64, 5> = Vector::from([f64::INFINITY, 2.0, 3.0, 4.0, 5.0]);
4727        let v_neg_inf: Vector<f64, 5> = Vector::from([f64::NEG_INFINITY, 2.0, 3.0, 4.0, 5.0]);
4728        assert_eq!(v_pos_inf.mean().unwrap(), f64::INFINITY);
4729        assert_eq!(v_neg_inf.mean().unwrap(), f64::NEG_INFINITY);
4730    }
4731
4732    #[test]
4733    fn vector_method_mean_err() {
4734        // the mean method should raise an error when called from an empty vector
4735        let v: Vector<f64, 0> = Vector::new();
4736        assert!(v.mean().is_err());
4737        assert!(matches!(v.mean(), Err(VectorError::EmptyVectorError(_))));
4738    }
4739
4740    // ================================
4741    //
4742    // mean_geo method tests
4743    //
4744    // ================================
4745
4746    #[test]
4747    fn vector_method_mean_geo() {
4748        let v1: Vector<f32, 5> = Vector::from([4.0, 36.0, 45.0, 50.0, 75.0]);
4749        let v2: Vector<f64, 5> = Vector::from([4.0, 36.0, 45.0, 50.0, 75.0]);
4750
4751        assert_relative_eq!(v1.mean_geo().unwrap(), 30.0);
4752        assert_relative_eq!(v2.mean_geo().unwrap(), 30.0);
4753
4754        let v1_mean_geo = v1.mean_geo().unwrap();
4755
4756        // sum of log residuals = zero
4757        assert_relative_eq!(
4758            (v1[0].ln() - v1_mean_geo.ln())
4759                + (v1[1].ln() - v1_mean_geo.ln())
4760                + (v1[2].ln() - v1_mean_geo.ln())
4761                + (v1[3].ln() - v1_mean_geo.ln())
4762                + (v1[4].ln() - v1_mean_geo.ln()),
4763            0.0
4764        );
4765
4766        // 1-Vector geometric mean = contained value
4767        let v3: Vector<f64, 1> = Vector::from([5.0]);
4768        assert_relative_eq!(v3.mean_geo().unwrap(), 5.0);
4769
4770        // mixed positive and negative values
4771        let v3: Vector<f64, 5> = Vector::from([-4.0, 2.0, 3.0, 4.0, 5.0]);
4772        assert!(v3.mean_geo().unwrap().is_nan());
4773
4774        let v3_alt: Vector<f64, 5> = Vector::from([-4.0, -2.0, 3.0, 4.0, 5.0]);
4775        assert!(v3_alt.mean_geo().unwrap().is_nan());
4776
4777        // negative values only
4778        let v4: Vector<f64, 5> = Vector::from([-4.0, -36.0, -45.0, -50.0, -75.0]);
4779        assert!(v4.mean_geo().unwrap().is_nan());
4780
4781        // identical values
4782        let v5: Vector<f64, 5> = Vector::from([10.0, 10.0, 10.0, 10.0, 10.0]);
4783        assert_relative_eq!(v5.mean_geo().unwrap(), 10.0);
4784
4785        // NaN data
4786        let v_nan: Vector<f64, 5> = Vector::from([f64::NAN, 2.0, 3.0, 4.0, 5.0]);
4787        assert!(v_nan.mean_geo().unwrap().is_nan());
4788
4789        // positive infinity
4790        let v_pos_inf: Vector<f64, 5> = Vector::from([f64::INFINITY, 2.0, 3.0, 4.0, 5.0]);
4791        assert_eq!(v_pos_inf.mean_geo().unwrap(), f64::INFINITY);
4792
4793        // negative infinity
4794        let v_neg_inf: Vector<f64, 5> = Vector::from([f64::NEG_INFINITY, 2.0, 3.0, 4.0, 5.0]);
4795        assert!(v_neg_inf.mean_geo().unwrap().is_nan());
4796
4797        // zero values
4798        let v_zero: Vector<f64, 5> = Vector::from([0.0, 1.0, 2.0, 3.0, 4.0]);
4799        assert_relative_eq!(v_zero.mean_geo().unwrap(), 0.0);
4800
4801        let v_zero_alt: Vector<f64, 5> = Vector::from([0.0, 0.0, 0.0, 0.0, 0.0]);
4802        assert_relative_eq!(v_zero_alt.mean_geo().unwrap(), 0.0);
4803    }
4804
4805    #[test]
4806    fn vector_method_mean_geo_err() {
4807        // the mean method should raise an error when called from an empty vector
4808        let v: Vector<f64, 0> = Vector::new();
4809        assert!(v.mean_geo().is_err());
4810        assert!(matches!(v.mean(), Err(VectorError::EmptyVectorError(_))));
4811    }
4812
4813    // ================================
4814    //
4815    // mean_harmonic method tests
4816    //
4817    // ================================
4818    #[test]
4819    fn vector_method_mean_harmonic() {
4820        let v1: Vector<f32, 5> = Vector::from([4.0, 36.0, 45.0, 50.0, 75.0]);
4821        let v2: Vector<f64, 5> = Vector::from([4.0, 36.0, 45.0, 50.0, 75.0]);
4822
4823        assert_relative_eq!(v1.mean_harmonic().unwrap(), 15.0);
4824        assert_relative_eq!(v2.mean_harmonic().unwrap(), 15.0);
4825
4826        // 1-Vector geometric mean = contained value
4827        let v3: Vector<f64, 1> = Vector::from([5.0]);
4828        assert_relative_eq!(v3.mean_harmonic().unwrap(), 5.0);
4829
4830        // mixed positive and negative values
4831        let v4: Vector<f64, 5> = Vector::from([-4.0, 2.0, 3.0, 4.0, 5.0]);
4832        assert!(v4.mean_harmonic().is_err());
4833        assert!(matches!(v4.mean_harmonic(), Err(VectorError::ValueError(_))));
4834
4835        let v4_alt: Vector<f64, 5> = Vector::from([-4.0, -2.0, 3.0, 4.0, 5.0]);
4836        assert!(v4_alt.mean_harmonic().is_err());
4837        assert!(matches!(v4.mean_harmonic(), Err(VectorError::ValueError(_))));
4838
4839        // negative values only
4840        let v5: Vector<f64, 5> = Vector::from([-4.0, -36.0, -45.0, -50.0, -75.0]);
4841        assert!(v5.mean_harmonic().is_err());
4842        assert!(matches!(v4.mean_harmonic(), Err(VectorError::ValueError(_))));
4843
4844        // identical values
4845        let v6: Vector<f64, 5> = Vector::from([10.0, 10.0, 10.0, 10.0, 10.0]);
4846        assert_relative_eq!(v6.mean_harmonic().unwrap(), 10.0);
4847
4848        // NaN data
4849        let v_nan: Vector<f64, 5> = Vector::from([f64::NAN, 2.0, 3.0, 4.0, 5.0]);
4850        assert!(v_nan.mean_harmonic().unwrap().is_nan());
4851
4852        // positive infinity
4853        let v_pos_inf: Vector<f64, 5> = Vector::from([f64::INFINITY, 2.0, 3.0, 4.0, 5.0]);
4854        assert_eq!(v_pos_inf.mean_harmonic().unwrap(), 3.8961038961038965);
4855    }
4856
4857    #[test]
4858    fn vector_method_mean_harmonic_err() {
4859        // negative infinity
4860        let v_neg_inf: Vector<f64, 5> = Vector::from([f64::NEG_INFINITY, 2.0, 3.0, 4.0, 5.0]);
4861        assert!(v_neg_inf.mean_harmonic().is_err());
4862        assert!(matches!(v_neg_inf.mean_harmonic(), Err(VectorError::ValueError(_))));
4863
4864        // zero values
4865        let v_zero: Vector<f64, 5> = Vector::from([0.0, 1.0, 2.0, 3.0, 4.0]);
4866        assert!(v_zero.mean_harmonic().is_err());
4867        assert!(matches!(v_zero.mean_harmonic(), Err(VectorError::ValueError(_))));
4868
4869        let v_zero_alt: Vector<f64, 5> = Vector::from([0.0, 0.0, 0.0, 0.0, 0.0]);
4870        assert!(v_zero_alt.mean_harmonic().is_err());
4871        assert!(matches!(v_zero_alt.mean_harmonic(), Err(VectorError::ValueError(_))));
4872    }
4873
4874    // ================================
4875    //
4876    // median method tests
4877    //
4878    // ================================
4879    #[test]
4880    fn vector_method_median() {
4881        let v_even: Vector<f64, 10> =
4882            Vector::from([5.0, 1.0, 2.0, 3.0, 4.0, 6.0, 7.0, 8.0, 9.0, 10.0]);
4883        let v_odd: Vector<f64, 9> = Vector::from([5.0, 1.0, 2.0, 3.0, 4.0, 6.0, 7.0, 8.0, 9.0]);
4884
4885        // should take arithmetic average of middle two values in data set with even number of items
4886        assert_relative_eq!(v_even.median().unwrap(), 5.5);
4887        // should be the middle value in a data set with an odd number of items
4888        assert_relative_eq!(v_odd.median().unwrap(), 5.0);
4889
4890        let v_neg_even: Vector<f64, 10> =
4891            Vector::from([-5.0, -1.0, -2.0, -3.0, -4.0, -6.0, -7.0, -8.0, -9.0, -10.0]);
4892        let v_neg_odd: Vector<f64, 9> =
4893            Vector::from([-5.0, -1.0, -2.0, -3.0, -4.0, -6.0, -7.0, -8.0, -9.0]);
4894
4895        assert_relative_eq!(v_neg_even.median().unwrap(), -5.5);
4896        assert_relative_eq!(v_neg_odd.median().unwrap(), -5.0);
4897
4898        // two value data set
4899        let v_two_val: Vector<f64, 2> = Vector::from([2.0, 3.0]);
4900
4901        assert_relative_eq!(v_two_val.median().unwrap(), 2.5);
4902
4903        // single value data set
4904        let v_one_val: Vector<f64, 1> = Vector::from([2.0]);
4905
4906        assert_relative_eq!(v_one_val.median().unwrap(), 2.0);
4907
4908        // positive / negative infinity in the data set - order
4909        let v_infinites: Vector<f64, 5> =
4910            Vector::from([f64::INFINITY, 3.0, 2.0, 1.0, f64::NEG_INFINITY]);
4911
4912        assert_relative_eq!(v_infinites.median().unwrap(), 2.0);
4913
4914        // positive infinity as the median value (odd)
4915        let v_infinites: Vector<f64, 3> =
4916            Vector::from([f64::INFINITY, f64::INFINITY, f64::NEG_INFINITY]);
4917
4918        assert!(v_infinites.median().unwrap().is_infinite());
4919        assert_eq!(v_infinites.median().unwrap(), f64::INFINITY);
4920
4921        // positive infinity as the median value (even)
4922        let v_infinites: Vector<f64, 2> = Vector::from([f64::INFINITY, f64::INFINITY]);
4923
4924        assert!(v_infinites.median().unwrap().is_infinite());
4925        assert_eq!(v_infinites.median().unwrap(), f64::INFINITY);
4926
4927        // negative infinity as the median value (odd)
4928        let v_infinites: Vector<f64, 3> =
4929            Vector::from([f64::INFINITY, f64::NEG_INFINITY, f64::NEG_INFINITY]);
4930
4931        assert!(v_infinites.median().unwrap().is_infinite());
4932        assert_eq!(v_infinites.median().unwrap(), f64::NEG_INFINITY);
4933
4934        // negative infinity as the median value (even)
4935        let v_infinites: Vector<f64, 2> = Vector::from([f64::NEG_INFINITY, f64::NEG_INFINITY]);
4936
4937        assert!(v_infinites.median().unwrap().is_infinite());
4938        assert_eq!(v_infinites.median().unwrap(), f64::NEG_INFINITY);
4939
4940        // median of positive infinity and negative infinity in a data set with even # items is NaN
4941        let v_infinites: Vector<f64, 2> = Vector::from([f64::INFINITY, f64::NEG_INFINITY]);
4942
4943        assert!(v_infinites.median().unwrap().is_nan());
4944
4945        // the median of an even data set with neg zero and pos zero can be
4946        // asserted as either 0.0 or -0.0
4947        let v_zeroes: Vector<f64, 4> = Vector::from([-1.0, -0.0, 0.0, 1.0]);
4948
4949        assert_relative_eq!(v_zeroes.median().unwrap(), 0.0);
4950        assert_relative_eq!(v_zeroes.median().unwrap(), -0.0);
4951    }
4952
4953    // ================================
4954    //
4955    // variance method tests
4956    //
4957    // ================================
4958
4959    #[test]
4960    fn vector_method_variance_impl() {
4961        // all positive numbers
4962        let v: Vector<f64, 5> = Vector::from([1.0, 5.0, 10.0, 20.0, 40.0]);
4963
4964        // population
4965        assert_relative_eq!(v.variance_impl(0.0), 194.16);
4966        assert_relative_eq!(v.variance(0.0).unwrap(), 194.16);
4967        // sample
4968        assert_relative_eq!(v.variance_impl(1.0), 242.7);
4969        assert_relative_eq!(v.variance(1.0).unwrap(), 242.7);
4970
4971        // include negative numbers
4972        let v: Vector<f64, 5> = Vector::from([-40.0, -10.0, -1.0, 5.0, 20.0]);
4973
4974        // population
4975        assert_relative_eq!(v.variance_impl(0.0), 398.16);
4976        assert_relative_eq!(v.variance(0.0).unwrap(), 398.16);
4977        // sample
4978        assert_relative_eq!(v.variance_impl(1.0), 497.7);
4979        assert_relative_eq!(v.variance(1.0).unwrap(), 497.7);
4980
4981        // no variance in data set
4982        let v: Vector<f64, 5> = Vector::from([1.0, 1.0, 1.0, 1.0, 1.0]);
4983
4984        assert_relative_eq!(v.variance_impl(0.0), 0.0);
4985        assert_relative_eq!(v.variance(0.0).unwrap(), 0.0);
4986        assert_relative_eq!(v.variance_impl(1.0), 0.0);
4987        assert_relative_eq!(v.variance(1.0).unwrap(), 0.0);
4988
4989        let v: Vector<f64, 5> = Vector::from([-1.0, -1.0, -1.0, -1.0, -1.0]);
4990
4991        assert_relative_eq!(v.variance_impl(0.0), 0.0);
4992        assert_relative_eq!(v.variance(0.0).unwrap(), 0.0);
4993        assert_relative_eq!(v.variance_impl(1.0), 0.0);
4994        assert_relative_eq!(v.variance(1.0).unwrap(), 0.0);
4995
4996        let v: Vector<f64, 5> = Vector::from([0.0, 0.0, 0.0, 0.0, 0.0]);
4997
4998        assert_relative_eq!(v.variance_impl(0.0), 0.0);
4999        assert_relative_eq!(v.variance(0.0).unwrap(), 0.0);
5000        assert_relative_eq!(v.variance_impl(1.0), 0.0);
5001        assert_relative_eq!(v.variance(1.0).unwrap(), 0.0);
5002
5003        let v: Vector<f64, 5> = Vector::from([-0.0, -0.0, -0.0, -0.0, -0.0]);
5004
5005        assert_relative_eq!(v.variance_impl(0.0), 0.0);
5006        assert_relative_eq!(v.variance(0.0).unwrap(), 0.0);
5007        assert_relative_eq!(v.variance_impl(1.0), 0.0);
5008        assert_relative_eq!(v.variance(1.0).unwrap(), 0.0);
5009
5010        // infinities
5011        let v_pos_inf: Vector<f64, 5> = Vector::from([f64::INFINITY, -10.0, -1.0, 5.0, 20.0]);
5012        let v_neg_inf: Vector<f64, 5> = Vector::from([f64::NEG_INFINITY, -10.0, -1.0, 5.0, 20.0]);
5013
5014        assert!(v_pos_inf.variance_impl(0.0).is_nan());
5015        assert!(v_pos_inf.variance(0.0).unwrap().is_nan());
5016        assert!(v_neg_inf.variance_impl(0.0).is_nan());
5017        assert!(v_neg_inf.variance(0.0).unwrap().is_nan());
5018
5019        assert!(v_pos_inf.variance_impl(1.0).is_nan());
5020        assert!(v_pos_inf.variance(1.0).unwrap().is_nan());
5021        assert!(v_neg_inf.variance_impl(1.0).is_nan());
5022        assert!(v_neg_inf.variance(1.0).unwrap().is_nan());
5023    }
5024
5025    #[test]
5026    fn vector_method_variance_err_empty() {
5027        let v: Vector<f64, 0> = Vector::new();
5028
5029        assert!(v.variance(1.0).is_err());
5030        assert!(matches!(v.variance(0.0), Err(VectorError::EmptyVectorError(_))));
5031    }
5032
5033    #[test]
5034    fn vector_method_variance_err_ddof_out_of_range_neg() {
5035        let v: Vector<f64, 3> = Vector::new();
5036
5037        assert!(v.variance(-1.0).is_err());
5038        assert!(matches!(v.variance(-1.0), Err(VectorError::ValueError(_))));
5039    }
5040
5041    #[test]
5042    fn vector_method_variance_err_ddof_out_of_range_greater_vector_size() {
5043        let v: Vector<f64, 3> = Vector::new();
5044
5045        assert!(v.variance(4.0).is_err());
5046        assert!(matches!(v.variance(4.0), Err(VectorError::ValueError(_))));
5047    }
5048
5049    // ================================
5050    //
5051    // stddev method tests
5052    //
5053    // ================================
5054
5055    // note: this method is the square root of the variance method and additional
5056    // test case coverage is on the variance method above.
5057    #[test]
5058    fn vector_method_stddev() {
5059        let v: Vector<f64, 5> = Vector::from([-40.0, -10.0, -1.0, 5.0, 20.0]);
5060
5061        // population
5062        assert_relative_eq!(v.stddev(0.0).unwrap(), 19.95394697797907);
5063        // sample
5064        assert_relative_eq!(v.stddev(1.0).unwrap(), 22.30919093109385);
5065
5066        // no variance in data set
5067        let v: Vector<f64, 5> = Vector::from([1.0, 1.0, 1.0, 1.0, 1.0]);
5068
5069        // population
5070        assert_relative_eq!(v.stddev(0.0).unwrap(), 0.0);
5071        // sample
5072        assert_relative_eq!(v.stddev(1.0).unwrap(), 0.0);
5073
5074        // infinities
5075        let v_pos_inf: Vector<f64, 5> = Vector::from([f64::INFINITY, -10.0, -1.0, 5.0, 20.0]);
5076        let v_neg_inf: Vector<f64, 5> = Vector::from([f64::NEG_INFINITY, -10.0, -1.0, 5.0, 20.0]);
5077
5078        // population
5079        assert!(v_pos_inf.stddev(0.0).unwrap().is_nan());
5080        assert!(v_neg_inf.stddev(0.0).unwrap().is_nan());
5081        // sample
5082        assert!(v_pos_inf.stddev(1.0).unwrap().is_nan());
5083        assert!(v_neg_inf.stddev(1.0).unwrap().is_nan());
5084    }
5085
5086    #[test]
5087    fn vector_method_stddev_err_empty() {
5088        let v: Vector<f64, 0> = Vector::new();
5089
5090        assert!(v.stddev(1.0).is_err());
5091        assert!(matches!(v.stddev(0.0), Err(VectorError::EmptyVectorError(_))));
5092    }
5093
5094    #[test]
5095    fn vector_method_stddev_err_ddof_out_of_range_neg() {
5096        let v: Vector<f64, 3> = Vector::new();
5097
5098        assert!(v.stddev(-1.0).is_err());
5099        assert!(matches!(v.stddev(-1.0), Err(VectorError::ValueError(_))));
5100    }
5101
5102    #[test]
5103    fn vector_method_stddev_err_ddof_out_of_range_greater_vector_size() {
5104        let v: Vector<f64, 3> = Vector::new();
5105
5106        assert!(v.stddev(4.0).is_err());
5107        assert!(matches!(v.stddev(4.0), Err(VectorError::ValueError(_))));
5108    }
5109
5110    // =====================================
5111    //
5112    // min, max, min_fp, max_fp method tests
5113    //
5114    // =====================================
5115    #[test]
5116    fn vector_method_min() {
5117        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
5118        assert_eq!(v1.min().unwrap(), 1);
5119
5120        let v2: Vector<i32, 3> = Vector::from([-1, -2, -3]);
5121        assert_eq!(v2.min().unwrap(), -3);
5122
5123        let v3: Vector<i32, 3> = Vector::from([-1, 2, 3]);
5124        assert_eq!(v3.min().unwrap(), -1);
5125
5126        let v4: Vector<i32, 3> = Vector::from([1, 1, 1]);
5127        assert_eq!(v4.min().unwrap(), 1);
5128
5129        let v5: Vector<i32, 3> = Vector::from([0, 0, 0]);
5130        assert_eq!(v5.min().unwrap(), 0);
5131
5132        let v6: Vector<i32, 3> = Vector::from([i32::MIN, 0, 0]);
5133        assert_eq!(v6.min().unwrap(), i32::MIN);
5134
5135        let v6: Vector<i32, 3> = Vector::from([i32::MIN, i32::MIN, i32::MIN]);
5136        assert_eq!(v6.min().unwrap(), i32::MIN);
5137
5138        let v_empty: Vector<i32, 0> = Vector::zero();
5139        assert!(v_empty.min().is_none());
5140    }
5141
5142    #[test]
5143    fn vector_method_min_fp() {
5144        let v1: Vector<f64, 3> = Vector::from([1.0, 2.0, 3.0]);
5145        assert_relative_eq!(v1.min_fp().unwrap(), 1.0);
5146
5147        let v2: Vector<f64, 3> = Vector::from([-1.0, -2.0, -3.0]);
5148        assert_relative_eq!(v2.min_fp().unwrap(), -3.0);
5149
5150        let v3: Vector<f64, 3> = Vector::from([-1.0, 2.0, 3.0]);
5151        assert_relative_eq!(v3.min_fp().unwrap(), -1.0);
5152
5153        let v4: Vector<f64, 3> = Vector::from([1.0, 1.0, 1.0]);
5154        assert_relative_eq!(v4.min_fp().unwrap(), 1.0);
5155
5156        let v5: Vector<f64, 3> = Vector::from([0.0, 0.0, 0.0]);
5157        assert_relative_eq!(v5.min_fp().unwrap(), 0.0);
5158
5159        let v6: Vector<f64, 3> = Vector::from([f64::MIN, 0.0, 0.0]);
5160        assert_relative_eq!(v6.min_fp().unwrap(), f64::MIN);
5161
5162        let v6: Vector<f64, 3> = Vector::from([f64::MIN, f64::MIN, f64::MIN]);
5163        assert_relative_eq!(v6.min_fp().unwrap(), f64::MIN);
5164
5165        let v7: Vector<f64, 3> = Vector::from([0.0, 0.0, 1.0]);
5166        assert_relative_eq!(v7.min_fp().unwrap(), 0.0);
5167
5168        let v_empty: Vector<f64, 0> = Vector::zero();
5169        assert!(v_empty.min_fp().is_none());
5170    }
5171
5172    #[test]
5173    fn vector_method_max() {
5174        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
5175        assert_eq!(v1.max().unwrap(), 3);
5176
5177        let v2: Vector<i32, 3> = Vector::from([-1, -2, -3]);
5178        assert_eq!(v2.max().unwrap(), -1);
5179
5180        let v3: Vector<i32, 3> = Vector::from([-1, 2, 3]);
5181        assert_eq!(v3.max().unwrap(), 3);
5182
5183        let v4: Vector<i32, 3> = Vector::from([1, 1, 1]);
5184        assert_eq!(v4.max().unwrap(), 1);
5185
5186        let v5: Vector<i32, 3> = Vector::from([0, 0, 0]);
5187        assert_eq!(v5.max().unwrap(), 0);
5188
5189        let v6: Vector<i32, 3> = Vector::from([i32::MAX, 0, 0]);
5190        assert_eq!(v6.max().unwrap(), i32::MAX);
5191
5192        let v6: Vector<i32, 3> = Vector::from([i32::MAX, i32::MAX, i32::MAX]);
5193        assert_eq!(v6.max().unwrap(), i32::MAX);
5194
5195        let v_empty: Vector<i32, 0> = Vector::zero();
5196        assert!(v_empty.max().is_none());
5197    }
5198
5199    #[test]
5200    fn vector_method_max_fp() {
5201        let v1: Vector<f64, 3> = Vector::from([1.0, 2.0, 3.0]);
5202        assert_relative_eq!(v1.max_fp().unwrap(), 3.0);
5203
5204        let v2: Vector<f64, 3> = Vector::from([-1.0, -2.0, -3.0]);
5205        assert_relative_eq!(v2.max_fp().unwrap(), -1.0);
5206
5207        let v3: Vector<f64, 3> = Vector::from([-1.0, 2.0, 3.0]);
5208        assert_relative_eq!(v3.max_fp().unwrap(), 3.0);
5209
5210        let v4: Vector<f64, 3> = Vector::from([1.0, 1.0, 1.0]);
5211        assert_relative_eq!(v4.max_fp().unwrap(), 1.0);
5212
5213        let v5: Vector<f64, 3> = Vector::from([0.0, 0.0, 0.0]);
5214        assert_relative_eq!(v5.max_fp().unwrap(), 0.0);
5215
5216        let v6: Vector<f64, 3> = Vector::from([f64::MAX, 0.0, 0.0]);
5217        assert_relative_eq!(v6.max_fp().unwrap(), f64::MAX);
5218
5219        let v6: Vector<f64, 3> = Vector::from([f64::MAX, f64::MAX, f64::MAX]);
5220        assert_relative_eq!(v6.max_fp().unwrap(), f64::MAX);
5221
5222        let v7: Vector<f64, 3> = Vector::from([0.0, 0.0, -1.0]);
5223        assert_relative_eq!(v7.max_fp().unwrap(), 0.0);
5224
5225        let v_empty: Vector<f64, 0> = Vector::zero();
5226        assert!(v_empty.max_fp().is_none());
5227    }
5228
5229    // ===================================
5230    //
5231    // map_closure & map_func method tests
5232    //
5233    // ===================================
5234
5235    #[test]
5236    fn vector_method_map_closure() {
5237        let v1 = Vector::<i32, 2>::from([-1, 2]);
5238        let v2 = Vector::<f64, 2>::from([-1.0, 2.0]);
5239        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
5240        let v4 = Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
5241
5242        let square_int = |x: i32| x.pow(2);
5243        let square_float = |x: f64| x.powi(2);
5244        let square_complex_i32 = |x: Complex<i32>| x.powi(2);
5245        let square_complex_f64 = |x: Complex<f64>| x.powi(2);
5246
5247        let v1_squared = v1.map_closure(square_int);
5248        let v2_squared = v2.map_closure(square_float);
5249        let v3_squared = v3.map_closure(square_complex_i32);
5250        let v4_squared = v4.map_closure(square_complex_f64);
5251
5252        assert_eq!(v1_squared, Vector::<i32, 2>::from([1, 4]));
5253        assert_eq!(v2_squared, Vector::<f64, 2>::from([1.0, 4.0]));
5254
5255        assert_eq!(v1, Vector::<i32, 2>::from([-1, 2]));
5256        assert_eq!(v2, Vector::<f64, 2>::from([-1.0, 2.0]));
5257
5258        // Expacted values for complex multiplication
5259        // real part = (ac - bd)
5260        // imaginary part = (ad + bc)
5261        assert_eq!(v3_squared[0].re, -3);
5262        assert_eq!(v3_squared[0].im, 4);
5263        assert_eq!(v3_squared[1].re, -7);
5264        assert_eq!(v3_squared[1].im, 24);
5265
5266        assert_relative_eq!(v4_squared[0].re, -3.0);
5267        assert_relative_eq!(v4_squared[0].im, 4.0);
5268        assert_relative_eq!(v4_squared[1].re, -7.0);
5269        assert_relative_eq!(v4_squared[1].im, 24.0);
5270    }
5271
5272    #[test]
5273    fn vector_method_mut_map_closure() {
5274        let mut v1 = Vector::<i32, 2>::from([-1, 2]);
5275        let mut v2 = Vector::<f64, 2>::from([-1.0, 2.0]);
5276        let mut v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
5277        let mut v4 =
5278            Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
5279
5280        let square_int = |x: i32| x.pow(2);
5281        let square_float = |x: f64| x.powi(2);
5282        let square_complex_i32 = |x: Complex<i32>| x.powi(2);
5283        let square_complex_f64 = |x: Complex<f64>| x.powi(2);
5284
5285        v1.mut_map_closure(square_int);
5286        v2.mut_map_closure(square_float);
5287        v3.mut_map_closure(square_complex_i32);
5288        v4.mut_map_closure(square_complex_f64);
5289
5290        assert_eq!(v1, Vector::<i32, 2>::from([1, 4]));
5291        assert_eq!(v2, Vector::<f64, 2>::from([1.0, 4.0]));
5292
5293        // Expacted values for complex multiplication
5294        // real part = (ac - bd)
5295        // imaginary part = (ad + bc)
5296        assert_eq!(v3[0].re, -3);
5297        assert_eq!(v3[0].im, 4);
5298        assert_eq!(v3[1].re, -7);
5299        assert_eq!(v3[1].im, 24);
5300
5301        assert_relative_eq!(v4[0].re, -3.0);
5302        assert_relative_eq!(v4[0].im, 4.0);
5303        assert_relative_eq!(v4[1].re, -7.0);
5304        assert_relative_eq!(v4[1].im, 24.0);
5305    }
5306
5307    #[test]
5308    fn vector_method_map_fn() {
5309        let v1 = Vector::<i32, 2>::from([-1, 2]);
5310        let v2 = Vector::<f64, 2>::from([-1.0, 2.0]);
5311        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
5312        let v4 = Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
5313
5314        fn square_int(x: i32) -> i32 {
5315            x.pow(2)
5316        }
5317
5318        fn square_float(x: f64) -> f64 {
5319            x.powi(2)
5320        }
5321
5322        fn square_complex_int(x: Complex<i32>) -> Complex<i32> {
5323            x.powi(2)
5324        }
5325
5326        fn square_complex_float(x: Complex<f64>) -> Complex<f64> {
5327            x.powi(2)
5328        }
5329
5330        let v1_squared = v1.map_fn(square_int);
5331        let v2_squared = v2.map_fn(square_float);
5332        let v3_squared = v3.map_fn(square_complex_int);
5333        let v4_squared = v4.map_fn(square_complex_float);
5334
5335        assert_eq!(v1_squared, Vector::<i32, 2>::from([1, 4]));
5336        assert_eq!(v2_squared, Vector::<f64, 2>::from([1.0, 4.0]));
5337
5338        assert_eq!(v1, Vector::<i32, 2>::from([-1, 2]));
5339        assert_eq!(v2, Vector::<f64, 2>::from([-1.0, 2.0]));
5340
5341        // Expacted values for complex multiplication
5342        // real part = (ac - bd)
5343        // imaginary part = (ad + bc)
5344        assert_eq!(v3_squared[0].re, -3);
5345        assert_eq!(v3_squared[0].im, 4);
5346        assert_eq!(v3_squared[1].re, -7);
5347        assert_eq!(v3_squared[1].im, 24);
5348
5349        assert_relative_eq!(v4_squared[0].re, -3.0);
5350        assert_relative_eq!(v4_squared[0].im, 4.0);
5351        assert_relative_eq!(v4_squared[1].re, -7.0);
5352        assert_relative_eq!(v4_squared[1].im, 24.0);
5353    }
5354
5355    #[test]
5356    fn vector_method_mut_map_fn() {
5357        let mut v1 = Vector::<i32, 2>::from([-1, 2]);
5358        let mut v2 = Vector::<f64, 2>::from([-1.0, 2.0]);
5359        let mut v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
5360        let mut v4 =
5361            Vector::<Complex<f64>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
5362
5363        fn square_int(x: i32) -> i32 {
5364            x.pow(2)
5365        }
5366
5367        fn square_float(x: f64) -> f64 {
5368            x.powi(2)
5369        }
5370
5371        fn square_complex_int(x: Complex<i32>) -> Complex<i32> {
5372            x.powi(2)
5373        }
5374
5375        fn square_complex_float(x: Complex<f64>) -> Complex<f64> {
5376            x.powi(2)
5377        }
5378
5379        v1.mut_map_fn(square_int);
5380        v2.mut_map_fn(square_float);
5381        v3.mut_map_fn(square_complex_int);
5382        v4.mut_map_fn(square_complex_float);
5383
5384        assert_eq!(v1, Vector::<i32, 2>::from([1, 4]));
5385        assert_eq!(v2, Vector::<f64, 2>::from([1.0, 4.0]));
5386
5387        // Expacted values for complex multiplication
5388        // real part = (ac - bd)
5389        // imaginary part = (ad + bc)
5390        assert_eq!(v3[0].re, -3);
5391        assert_eq!(v3[0].im, 4);
5392        assert_eq!(v3[1].re, -7);
5393        assert_eq!(v3[1].im, 24);
5394
5395        assert_relative_eq!(v4[0].re, -3.0);
5396        assert_relative_eq!(v4[0].im, 4.0);
5397        assert_relative_eq!(v4[1].re, -7.0);
5398        assert_relative_eq!(v4[1].im, 24.0);
5399    }
5400
5401    // ================================
5402    //
5403    // Any trait introspection tests
5404    //
5405    // ================================
5406    #[test]
5407    fn vector_trait_any() {
5408        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
5409        assert!(TypeId::of::<Vector<i32, 3>>() == Any::type_id(&v1));
5410
5411        let boxed_v1: Box<dyn Any> = Box::new(Vector::from([1_i32, 2_i32, 3_i32]));
5412        assert!(TypeId::of::<Vector<i32, 3>>() == (&*boxed_v1).type_id());
5413
5414        let v2: Vector<f64, 3> = Vector::from([1.0, 2.0, 3.0]);
5415        assert!(TypeId::of::<Vector<f64, 3>>() == Any::type_id(&v2));
5416
5417        let boxed_v2: Box<dyn Any> = Box::new(Vector::from([1.0_f64, 2.0_f64, 3.0_f64]));
5418        assert!(TypeId::of::<Vector<f64, 3>>() == (&*boxed_v2).type_id());
5419
5420        let v3: Vector<Complex<i32>, 2> = Vector::from([Complex::new(0, 1), Complex::new(3, 4)]);
5421        assert!(TypeId::of::<Vector<Complex<i32>, 2>>() == Any::type_id(&v3));
5422
5423        let boxed_v3: Box<dyn Any> =
5424            Box::new(Vector::from([Complex::new(0, 1), Complex::new(3, 4)]));
5425        assert!(TypeId::of::<Vector<Complex<i32>, 2>>() == (&*boxed_v3).type_id());
5426    }
5427
5428    // ================================
5429    //
5430    // Display trait tests
5431    //
5432    // ================================
5433    #[test]
5434    fn vector_trait_display() {
5435        let v1: Vector<i32, 3> = Vector::from([-1, 2, 3]);
5436        let v2: Vector<f64, 3> = Vector::from([-1.0, 2.0, 3.0]);
5437        let v3: Vector<Complex<i32>, 2> = Vector::from([Complex::new(0, -1), Complex::new(3, 4)]);
5438
5439        assert_eq!(format!("{}", v1), String::from("[-1, 2, 3]"));
5440        assert_eq!(format!("{}", v2), String::from("[-1.0, 2.0, 3.0]"));
5441        assert_eq!(
5442            format!("{}", v3),
5443            String::from("[Complex { re: 0, im: -1 }, Complex { re: 3, im: 4 }]")
5444        );
5445    }
5446
5447    // ================================
5448    //
5449    // Index / IndexMut trait tests
5450    //
5451    // ================================
5452    #[test]
5453    fn vector_trait_index_access() {
5454        let v1 = Vector::<u32, 2>::from(&[1, 2]);
5455        let v2 = Vector::<f64, 2>::from(&[1.0, 2.0]);
5456        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
5457        assert_eq!(v1[0], 1);
5458        assert_eq!(v1[1], 2);
5459        assert_relative_eq!(v2[0], 1.0);
5460        assert_relative_eq!(v2[1], 2.0);
5461        assert_eq!(v3[0].re, 1);
5462        assert_eq!(v3[0].im, 2);
5463        assert_eq!(v3[1].re, 3);
5464        assert_eq!(v3[1].im, 4);
5465    }
5466
5467    #[test]
5468    #[should_panic(expected = "index out of bounds")]
5469    fn vector_trait_index_access_out_of_bounds() {
5470        let v = Vector::<u32, 10>::new();
5471        v[10];
5472    }
5473
5474    #[test]
5475    fn vector_trait_index_slicing() {
5476        let v = Vector::<i32, 3>::from(&[1, 2, 3]);
5477        let v_slice = &v[..];
5478
5479        assert_eq!(v_slice, [1, 2, 3]);
5480
5481        let v_slice = &v[0..2];
5482
5483        assert_eq!(v_slice, [1, 2]);
5484    }
5485
5486    #[test]
5487    #[should_panic(expected = "range end index 11 out of range for slice of length 10")]
5488    fn vector_trait_index_slice_access_out_of_bounds() {
5489        let v = Vector::<u32, 10>::new();
5490        let _ = &v[0..11];
5491    }
5492
5493    #[test]
5494    fn vector_trait_index_assignment() {
5495        let mut v1 = Vector::<u32, 2>::from(&[1, 2]);
5496        let mut v2 = Vector::<f64, 2>::from(&[1.0, 2.0]);
5497        let mut v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
5498        v1[0] = 5;
5499        v1[1] = 6;
5500        v2[0] = 5.0;
5501        v2[1] = 6.0;
5502        v3[0].re = 4;
5503        v3[0].im = 5;
5504        assert_eq!(v1[0], 5);
5505        assert_eq!(v1[1], 6);
5506        assert_relative_eq!(v2[0], 5.0);
5507        assert_relative_eq!(v2[1], 6.0);
5508        assert_eq!(v3[0].re, 4);
5509        assert_eq!(v3[0].im, 5);
5510    }
5511
5512    // ===================================
5513    //
5514    // IntoIterator traits tests
5515    //
5516    // ===================================
5517    #[test]
5518    fn vector_trait_intoiterator_ref() {
5519        let v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
5520        let v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
5521        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
5522
5523        let mut i: usize = 0;
5524        for x in &v1 {
5525            match i {
5526                0 => assert_eq!(x, &1),
5527                1 => assert_eq!(x, &2),
5528                2 => assert_eq!(x, &3),
5529                _ => unimplemented!(),
5530            }
5531            i += 1;
5532        }
5533
5534        let mut i: usize = 0;
5535        for x in &v2 {
5536            match i {
5537                0 => assert_relative_eq!(x, &1.0),
5538                1 => assert_relative_eq!(x, &2.0),
5539                2 => assert_relative_eq!(x, &3.0),
5540                _ => unimplemented!(),
5541            }
5542            i += 1;
5543        }
5544
5545        let mut i: usize = 0;
5546        for x in &v3 {
5547            match i {
5548                0 => assert_eq!(x, &Complex::new(1, 2)),
5549                1 => assert_eq!(x, &Complex::new(3, 4)),
5550                _ => unimplemented!(),
5551            }
5552            i += 1;
5553        }
5554    }
5555
5556    #[test]
5557    fn vector_trait_intoiterator_mut_ref() {
5558        let mut v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
5559        let mut v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
5560        let mut v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
5561
5562        let mut i: usize = 0;
5563        for x in &mut v1 {
5564            match i {
5565                0 => assert_eq!(x, &mut 1),
5566                1 => assert_eq!(x, &mut 2),
5567                2 => assert_eq!(x, &mut 3),
5568                _ => unimplemented!(),
5569            }
5570            i += 1;
5571        }
5572
5573        let mut i: usize = 0;
5574        for x in &mut v2 {
5575            match i {
5576                0 => assert_relative_eq!(x, &mut 1.0),
5577                1 => assert_relative_eq!(x, &mut 2.0),
5578                2 => assert_relative_eq!(x, &mut 3.0),
5579                _ => unimplemented!(),
5580            }
5581            i += 1;
5582        }
5583
5584        let mut i: usize = 0;
5585        for x in &mut v3 {
5586            match i {
5587                0 => assert_eq!(x, &mut Complex::new(1, 2)),
5588                1 => assert_eq!(x, &mut Complex::new(3, 4)),
5589                _ => unimplemented!(),
5590            }
5591            i += 1;
5592        }
5593    }
5594
5595    #[test]
5596    fn vector_trait_intoiterator_owned() {
5597        let v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
5598        let v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
5599        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
5600
5601        let mut i: usize = 0;
5602        for x in v1 {
5603            match i {
5604                0 => assert_eq!(x, 1),
5605                1 => assert_eq!(x, 2),
5606                2 => assert_eq!(x, 3),
5607                _ => unimplemented!(),
5608            }
5609            i += 1;
5610        }
5611
5612        let mut i: usize = 0;
5613        for x in v2 {
5614            match i {
5615                0 => assert_relative_eq!(x, 1.0),
5616                1 => assert_relative_eq!(x, 2.0),
5617                2 => assert_relative_eq!(x, 3.0),
5618                _ => unimplemented!(),
5619            }
5620            i += 1;
5621        }
5622
5623        let mut i: usize = 0;
5624        for x in v3 {
5625            match i {
5626                0 => assert_eq!(x, Complex::new(1, 2)),
5627                1 => assert_eq!(x, Complex::new(3, 4)),
5628                _ => unimplemented!(),
5629            }
5630            i += 1;
5631        }
5632    }
5633
5634    // =======================================
5635    //
5636    // rayon traits
5637    //
5638    // IntoParallelIterator trait tests
5639    // IntoParallelRefIterator trait tests
5640    // IntoParallelRefMutIterator trait tests
5641    // ParallelSlice trait tests
5642    // ParallelSliceMut trait tests
5643    //
5644    // =======================================
5645
5646    #[cfg(feature = "parallel")]
5647    #[test]
5648    fn vector_trait_intoparalleliterator_owned() {
5649        let v = Vector::<i32, 3>::from([1, 2, 3]);
5650
5651        let x: i32 = v.into_par_iter().map(|x| x + 1).sum();
5652
5653        assert_eq!(x, 9);
5654        assert_eq!(v, Vector::from([1, 2, 3]));
5655    }
5656
5657    #[cfg(feature = "parallel")]
5658    #[test]
5659    fn vector_trait_intoparalleliterator_ref() {
5660        let v = Vector::<i32, 3>::from([1, 2, 3]);
5661
5662        let x: i32 = (&v).into_par_iter().map(|&x| x + 1_i32).sum();
5663
5664        assert_eq!(x, 9);
5665        assert_eq!(v, Vector::from([1, 2, 3]));
5666    }
5667
5668    #[cfg(feature = "parallel")]
5669    #[test]
5670    fn vector_trait_intoparalleliterator_mut_ref() {
5671        let mut v = Vector::<i32, 3>::from([1, 2, 3]);
5672
5673        (&mut v).into_par_iter().enumerate().for_each(|(i, x)| *x = i as i32);
5674
5675        assert_eq!(v, Vector::from([0, 1, 2]));
5676    }
5677
5678    #[cfg(feature = "parallel")]
5679    #[test]
5680    fn vector_trait_intoparallelrefiterator() {
5681        let v = Vector::<i32, 3>::from([1, 2, 3]);
5682
5683        let x: i32 = v.par_iter().map(|&x| x + 1_i32).sum();
5684
5685        assert_eq!(x, 9);
5686        assert_eq!(v, Vector::from([1, 2, 3]));
5687    }
5688
5689    #[cfg(feature = "parallel")]
5690    #[test]
5691    fn vector_trait_intoparallelrefmutiterator() {
5692        let mut v = Vector::<i32, 3>::from([5, 6, 7]);
5693        v.par_iter_mut().enumerate().for_each(|(i, x)| *x = i as i32);
5694
5695        assert_eq!(v, Vector::from([0, 1, 2]));
5696    }
5697
5698    #[cfg(feature = "parallel")]
5699    #[test]
5700    fn vector_trait_parallelslice() {
5701        let v = Vector::<i32, 3>::from([1, 2, 3]);
5702
5703        let windows: Vec<_> = v.as_parallel_slice().par_windows(2).collect();
5704        assert_eq!(vec![[1, 2], [2, 3]], windows);
5705
5706        let windows: Vec<_> = (&v).as_parallel_slice().par_windows(2).collect();
5707        assert_eq!(vec![[1, 2], [2, 3]], windows);
5708    }
5709
5710    #[cfg(feature = "parallel")]
5711    #[test]
5712    fn vector_trait_parallelslicemut() {
5713        let mut v = Vector::<i32, 5>::from([1, 2, 3, 4, 5]);
5714
5715        v.as_parallel_slice_mut().par_chunks_mut(2).for_each(|slice| slice.reverse());
5716        assert_eq!(v, Vector::from([2, 1, 4, 3, 5]));
5717
5718        // reset
5719        let mut v = Vector::<i32, 5>::from([1, 2, 3, 4, 5]);
5720
5721        (&mut v).as_parallel_slice_mut().par_chunks_mut(2).for_each(|slice| slice.reverse());
5722        assert_eq!(v, Vector::from([2, 1, 4, 3, 5]));
5723    }
5724
5725    #[test]
5726    fn vector_method_iter() {
5727        let v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
5728        let v2 = Vector::<f64, 3>::from(&[1.0, 2.0, 3.0]);
5729        let v3 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
5730
5731        let mut v1_iter = v1.iter();
5732        let mut v2_iter = v2.iter();
5733        let mut v3_iter = v3.iter();
5734
5735        assert_eq!(v1_iter.next().unwrap(), &1);
5736        assert_eq!(v1_iter.next().unwrap(), &2);
5737        assert_eq!(v1_iter.next().unwrap(), &3);
5738        assert_eq!(v1_iter.next(), None);
5739
5740        assert_relative_eq!(v2_iter.next().unwrap(), &1.0);
5741        assert_relative_eq!(v2_iter.next().unwrap(), &2.0);
5742        assert_relative_eq!(v2_iter.next().unwrap(), &3.0);
5743        assert_eq!(v2_iter.next(), None);
5744
5745        assert_eq!(v3_iter.next().unwrap(), &Complex::new(1, 2));
5746        assert_eq!(v3_iter.next().unwrap(), &Complex::new(3, 4));
5747        assert_eq!(v3_iter.next(), None);
5748    }
5749
5750    // ==================================
5751    //
5752    // FromIterator trait / collect tests
5753    //
5754    // ==================================
5755
5756    #[test]
5757    fn vector_trait_fromiterator_collect() {
5758        let v1: Vector<i32, 3> = [1, 2, 3].into_iter().collect();
5759        assert_eq!(v1.components.len(), 3);
5760        assert_eq!(v1[0], 1 as i32);
5761        assert_eq!(v1[1], 2 as i32);
5762        assert_eq!(v1[2], 3 as i32);
5763
5764        // overflow test
5765        // should truncate at the Vector length for overflows
5766        let v2: Vector<i32, 2> = [1, 2, 3].into_iter().collect();
5767        assert_eq!(v2.components.len(), 2);
5768        assert_eq!(v2[0], 1 as i32);
5769        assert_eq!(v2[1], 2 as i32);
5770
5771        // underflow test
5772        // zero value fills for underflows
5773        let v3: Vector<i32, 5> = [1, 2, 3].into_iter().collect();
5774        assert_eq!(v3.components.len(), 5);
5775        assert_eq!(v3[0], 1 as i32);
5776        assert_eq!(v3[1], 2 as i32);
5777        assert_eq!(v3[2], 3 as i32);
5778        assert_eq!(v3[3], 0 as i32);
5779        assert_eq!(v3[4], 0 as i32);
5780
5781        // test with Vector as the iterable
5782        let v4: Vector<i32, 3> = Vector::from([1, 2, 3]).into_iter().map(|x| x * 2).collect();
5783        assert_eq!(v4.components.len(), 3);
5784        assert_eq!(v4[0], 2);
5785        assert_eq!(v4[1], 4);
5786        assert_eq!(v4[2], 6);
5787
5788        // empty iterable tests
5789        let v5: Vector<i32, 3> = [].into_iter().collect();
5790        assert_eq!(v5.components.len(), 3);
5791        assert_eq!(v5[0], 0 as i32);
5792        assert_eq!(v5[1], 0 as i32);
5793        assert_eq!(v5[2], 0 as i32);
5794
5795        let v6: Vector<Complex<i32>, 2> = [].into_iter().collect();
5796        assert_eq!(v6.components.len(), 2);
5797        assert_eq!(v6[0], Complex::new(0 as i32, 0 as i32));
5798        assert_eq!(v6[1], Complex::new(0 as i32, 0 as i32));
5799    }
5800
5801    // ================================
5802    //
5803    // PartialEq trait tests
5804    //
5805    // ================================
5806
5807    #[test]
5808    fn vector_trait_partial_eq_i8() {
5809        let v1 = Vector::<i8, 3>::from(&[-1, 2, 3]);
5810        let v2 = Vector::<i8, 3>::from(&[-1, 2, 3]);
5811        let v_eq = Vector::<i8, 3>::from(&[-1, 2, 3]);
5812        let v_diff = Vector::<i8, 3>::from(&[-1, 2, 4]);
5813
5814        let v_zero = Vector::<i8, 3>::zero();
5815        let v_zero_neg = Vector::<i8, 3>::from(&[-0, -0, -0]);
5816
5817        assert!(v1 == v_eq);
5818        assert!(v_eq == v1); // symmetry
5819        assert!(v2 == v_eq);
5820        assert!(v1 == v2); // transitivity
5821        assert!(v1 != v_diff);
5822        assert!(v_zero == v_zero);
5823        assert!(v_zero == v_zero_neg);
5824    }
5825
5826    #[test]
5827    fn vector_trait_partial_eq_i16() {
5828        let v1 = Vector::<i16, 3>::from(&[-1, 2, 3]);
5829        let v2 = Vector::<i16, 3>::from(&[-1, 2, 3]);
5830        let v_eq = Vector::<i16, 3>::from(&[-1, 2, 3]);
5831        let v_diff = Vector::<i16, 3>::from(&[-1, 2, 4]);
5832
5833        assert!(v1 == v_eq);
5834        assert!(v_eq == v1); // symmetry
5835        assert!(v2 == v_eq);
5836        assert!(v1 == v2); // transitivity
5837        assert!(v1 != v_diff);
5838    }
5839
5840    #[test]
5841    fn vector_trait_partial_eq_i32() {
5842        let v1 = Vector::<i32, 3>::from(&[-1, 2, 3]);
5843        let v2 = Vector::<i32, 3>::from(&[-1, 2, 3]);
5844        let v_eq = Vector::<i32, 3>::from(&[-1, 2, 3]);
5845        let v_diff = Vector::<i32, 3>::from(&[-1, 2, 4]);
5846
5847        assert!(v1 == v_eq);
5848        assert!(v_eq == v1); // symmetry
5849        assert!(v2 == v_eq);
5850        assert!(v1 == v2); // transitivity
5851        assert!(v1 != v_diff);
5852    }
5853
5854    #[test]
5855    fn vector_trait_partial_eq_i64() {
5856        let v1 = Vector::<i64, 3>::from(&[-1, 2, 3]);
5857        let v2 = Vector::<i64, 3>::from(&[-1, 2, 3]);
5858        let v_eq = Vector::<i64, 3>::from(&[-1, 2, 3]);
5859        let v_diff = Vector::<i64, 3>::from(&[-1, 2, 4]);
5860
5861        assert!(v1 == v_eq);
5862        assert!(v_eq == v1); // symmetry
5863        assert!(v2 == v_eq);
5864        assert!(v1 == v2); // transitivity
5865        assert!(v1 != v_diff);
5866    }
5867
5868    #[test]
5869    fn vector_trait_partial_eq_i128() {
5870        let v1 = Vector::<i128, 3>::from(&[-1, 2, 3]);
5871        let v2 = Vector::<i128, 3>::from(&[-1, 2, 3]);
5872        let v_eq = Vector::<i128, 3>::from(&[-1, 2, 3]);
5873        let v_diff = Vector::<i128, 3>::from(&[-1, 2, 4]);
5874
5875        assert!(v1 == v_eq);
5876        assert!(v_eq == v1); // symmetry
5877        assert!(v2 == v_eq);
5878        assert!(v1 == v2); // transitivity
5879        assert!(v1 != v_diff);
5880    }
5881
5882    #[test]
5883    fn vector_trait_partial_eq_u8() {
5884        let v1 = Vector::<u8, 3>::from(&[1, 2, 3]);
5885        let v2 = Vector::<u8, 3>::from(&[1, 2, 3]);
5886        let v_eq = Vector::<u8, 3>::from(&[1, 2, 3]);
5887        let v_diff = Vector::<u8, 3>::from(&[1, 2, 4]);
5888
5889        assert!(v1 == v_eq);
5890        assert!(v_eq == v1); // symmetry
5891        assert!(v2 == v_eq);
5892        assert!(v1 == v2); // transitivity
5893        assert!(v1 != v_diff);
5894    }
5895
5896    #[test]
5897    fn vector_trait_partial_eq_u16() {
5898        let v1 = Vector::<u16, 3>::from(&[1, 2, 3]);
5899        let v2 = Vector::<u16, 3>::from(&[1, 2, 3]);
5900        let v_eq = Vector::<u16, 3>::from(&[1, 2, 3]);
5901        let v_diff = Vector::<u16, 3>::from(&[1, 2, 4]);
5902
5903        assert!(v1 == v_eq);
5904        assert!(v_eq == v1); // symmetry
5905        assert!(v2 == v_eq);
5906        assert!(v1 == v2); // transitivity
5907        assert!(v1 != v_diff);
5908    }
5909
5910    #[test]
5911    fn vector_trait_partial_eq_u32() {
5912        let v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
5913        let v2 = Vector::<u32, 3>::from(&[1, 2, 3]);
5914        let v_eq = Vector::<u32, 3>::from(&[1, 2, 3]);
5915        let v_diff = Vector::<u32, 3>::from(&[1, 2, 4]);
5916
5917        assert!(v1 == v_eq);
5918        assert!(v_eq == v1); // symmetry
5919        assert!(v2 == v_eq);
5920        assert!(v1 == v2); // transitivity
5921        assert!(v1 != v_diff);
5922    }
5923
5924    #[test]
5925    fn vector_trait_partial_eq_u64() {
5926        let v1 = Vector::<u64, 3>::from(&[1, 2, 3]);
5927        let v2 = Vector::<u64, 3>::from(&[1, 2, 3]);
5928        let v_eq = Vector::<u64, 3>::from(&[1, 2, 3]);
5929        let v_diff = Vector::<u64, 3>::from(&[1, 2, 4]);
5930
5931        assert!(v1 == v_eq);
5932        assert!(v_eq == v1); // symmetry
5933        assert!(v2 == v_eq);
5934        assert!(v1 == v2); // transitivity
5935        assert!(v1 != v_diff);
5936    }
5937
5938    #[test]
5939    fn vector_trait_partial_eq_u128() {
5940        let v1 = Vector::<u128, 3>::from(&[1, 2, 3]);
5941        let v2 = Vector::<u128, 3>::from(&[1, 2, 3]);
5942        let v_eq = Vector::<u128, 3>::from(&[1, 2, 3]);
5943        let v_diff = Vector::<u128, 3>::from(&[1, 2, 4]);
5944
5945        assert!(v1 == v_eq);
5946        assert!(v_eq == v1); // symmetry
5947        assert!(v2 == v_eq);
5948        assert!(v1 == v2); // transitivity
5949        assert!(v1 != v_diff);
5950    }
5951
5952    #[test]
5953    fn vector_trait_partial_eq_isize() {
5954        let v1 = Vector::<isize, 3>::from(&[1, 2, 3]);
5955        let v2 = Vector::<isize, 3>::from(&[1, 2, 3]);
5956        let v_eq = Vector::<isize, 3>::from(&[1, 2, 3]);
5957        let v_diff = Vector::<isize, 3>::from(&[1, 2, 4]);
5958
5959        assert!(v1 == v_eq);
5960        assert!(v_eq == v1); // symmetry
5961        assert!(v2 == v_eq);
5962        assert!(v1 == v2); // transitivity
5963        assert!(v1 != v_diff);
5964    }
5965
5966    #[test]
5967    fn vector_trait_partial_eq_usize() {
5968        let v1 = Vector::<usize, 3>::from(&[1, 2, 3]);
5969        let v2 = Vector::<usize, 3>::from(&[1, 2, 3]);
5970        let v_eq = Vector::<usize, 3>::from(&[1, 2, 3]);
5971        let v_diff = Vector::<usize, 3>::from(&[1, 2, 4]);
5972
5973        assert!(v1 == v_eq);
5974        assert!(v_eq == v1); // symmetry
5975        assert!(v2 == v_eq);
5976        assert!(v1 == v2); // transitivity
5977        assert!(v1 != v_diff);
5978    }
5979
5980    #[test]
5981    fn vector_trait_partial_eq_f32() {
5982        let v1 = Vector::<f32, 3>::from(&[-1.1, 2.2, 3.3]);
5983        let v2 = Vector::<f32, 3>::from(&[-1.1, 2.2, 3.3]);
5984        let v_eq = Vector::<f32, 3>::from(&[-1.1, 2.2, 3.3]);
5985        let v_diff = Vector::<f32, 3>::from(&[-1.1, 2.2, 4.4]);
5986        let v_close = Vector::<f32, 3>::from(&[-1.1 + (f32::EPSILON * 2.), 2.2, 3.3]);
5987
5988        let v_zero = Vector::<f32, 3>::zero();
5989        let v_zero_eq = Vector::<f32, 3>::zero();
5990        let v_zero_neg_eq = Vector::<f32, 3>::from(&[-0.0, -0.0, -0.0]);
5991
5992        let v_nan = Vector::<f32, 3>::from(&[f32::NAN, 0.0, 0.0]);
5993        let v_nan_diff = Vector::<f32, 3>::from(&[f32::NAN, 0.0, 0.0]);
5994
5995        let v_inf_pos = Vector::<f32, 3>::from(&[f32::INFINITY, 0.0, 0.0]);
5996        let v_inf_pos_eq = Vector::<f32, 3>::from(&[f32::INFINITY, 0.0, 0.0]);
5997        let v_inf_neg = Vector::<f32, 3>::from(&[f32::NEG_INFINITY, 0.0, 0.0]);
5998        let v_inf_neg_eq = Vector::<f32, 3>::from(&[f32::NEG_INFINITY, 0.0, 0.0]);
5999
6000        assert!(v1 == v_eq);
6001        assert!(v_eq == v1); // symmetry
6002        assert!(v2 == v_eq);
6003        assert!(v1 == v2); // transitivity
6004        assert!(v1 != v_diff);
6005        assert!(v1 != v_close);
6006        assert!(v_zero == v_zero_eq);
6007        assert!(v_zero == v_zero_neg_eq); // zero and neg zero are defined as equivalent
6008        assert!(v_nan != v_nan_diff); // NaN comparisons are defined as different
6009        assert!(v_inf_pos == v_inf_pos_eq); // postive infinity comparisons are defined as equivalent
6010        assert!(v_inf_neg == v_inf_neg_eq); // negative infinity comparisons are defined as equivalent
6011    }
6012
6013    #[test]
6014    fn vector_trait_partial_eq_f64() {
6015        let v1 = Vector::<f64, 3>::from(&[-1.1, 2.2, 3.3]);
6016        let v2 = Vector::<f64, 3>::from(&[-1.1, 2.2, 3.3]);
6017        let v_eq = Vector::<f64, 3>::from(&[-1.1, 2.2, 3.3]);
6018        let v_diff = Vector::<f64, 3>::from(&[-1.1, 2.2, 4.4]);
6019        let v_close = Vector::<f64, 3>::from(&[-1.1 + (f64::EPSILON * 2.), 2.2, 3.3]);
6020
6021        let v_zero = Vector::<f64, 3>::zero();
6022        let v_zero_eq = Vector::<f64, 3>::zero();
6023        let v_zero_neg_eq = Vector::<f64, 3>::from(&[-0.0, -0.0, -0.0]);
6024
6025        let v_nan = Vector::<f64, 3>::from(&[f64::NAN, 0.0, 0.0]);
6026        let v_nan_diff = Vector::<f64, 3>::from(&[f64::NAN, 0.0, 0.0]);
6027
6028        let v_inf_pos = Vector::<f64, 3>::from(&[f64::INFINITY, 0.0, 0.0]);
6029        let v_inf_pos_eq = Vector::<f64, 3>::from(&[f64::INFINITY, 0.0, 0.0]);
6030        let v_inf_neg = Vector::<f64, 3>::from(&[f64::NEG_INFINITY, 0.0, 0.0]);
6031        let v_inf_neg_eq = Vector::<f64, 3>::from(&[f64::NEG_INFINITY, 0.0, 0.0]);
6032
6033        assert!(v1 == v_eq);
6034        assert!(v_eq == v1); // symmetry
6035        assert!(v2 == v_eq);
6036        assert!(v1 == v2); // transitivity
6037        assert!(v1 != v_diff);
6038        assert!(v1 != v_close);
6039        assert!(v_zero == v_zero_eq);
6040        assert!(v_zero == v_zero_neg_eq); // zero and neg zero are defined as equivalent
6041        assert!(v_nan != v_nan_diff); // NaN comparisons are defined as different
6042        assert!(v_inf_pos == v_inf_pos_eq); // postive infinity comparisons are defined as equivalent
6043        assert!(v_inf_neg == v_inf_neg_eq); // negative infinity comparisons are defined as equivalent
6044    }
6045
6046    #[test]
6047    fn vector_trait_partial_eq_complex_i32() {
6048        // Note: Complex types with integer real and imaginary parts are only tested with i32 data types
6049        let v1 = Vector::<Complex<i32>, 2>::from([Complex::new(1, -2), Complex::new(3, 4)]);
6050        let v2 = Vector::<Complex<i32>, 2>::from([Complex::new(1, -2), Complex::new(3, 4)]);
6051        let v_eq = Vector::<Complex<i32>, 2>::from([Complex::new(1, -2), Complex::new(3, 4)]);
6052        let v_diff = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6053
6054        assert!(v1 == v_eq);
6055        assert!(v_eq == v1); // symmetry
6056        assert!(v2 == v_eq);
6057        assert!(v1 == v2); // transitivity
6058        assert!(v1 != v_diff);
6059    }
6060
6061    #[test]
6062    fn vector_trait_partial_eq_complex_f64() {
6063        let v1 = Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.2), Complex::new(2.2, 3.3)]);
6064        let v2 = Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.2), Complex::new(2.2, 3.3)]);
6065        let v_eq =
6066            Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.2), Complex::new(2.2, 3.3)]);
6067        let v_diff_re =
6068            Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.2), Complex::new(3.3, 3.3)]);
6069        let v_diff_im =
6070            Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.2), Complex::new(2.2, 4.4)]);
6071        let v_diff_re_im =
6072            Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.2), Complex::new(3.3, 4.4)]);
6073
6074        let v_close = Vector::<Complex<f64>, 2>::from([
6075            Complex::new(-1.1 + (f64::EPSILON * 2.), 2.2),
6076            Complex::new(2.2, 3.3),
6077        ]);
6078
6079        let v_zero = Vector::<Complex<f64>, 2>::zero();
6080        let v_zero_eq = Vector::<Complex<f64>, 2>::zero();
6081        let v_zero_neg_eq =
6082            Vector::<Complex<f64>, 2>::from([Complex::new(-0.0, -0.0), Complex::new(-0.0, -0.0)]);
6083
6084        let v_nan =
6085            Vector::<Complex<f64>, 2>::from([Complex::new(f64::NAN, 1.0), Complex::new(2.0, 3.0)]);
6086        let v_nan_diff =
6087            Vector::<Complex<f64>, 2>::from([Complex::new(f64::NAN, 1.0), Complex::new(2.0, 3.0)]);
6088
6089        let v_inf_pos = Vector::<Complex<f64>, 2>::from([
6090            Complex::new(f64::INFINITY, 0.0),
6091            Complex::new(3.0, 4.0),
6092        ]);
6093        let v_inf_pos_eq = Vector::<Complex<f64>, 2>::from([
6094            Complex::new(f64::INFINITY, 0.0),
6095            Complex::new(3.0, 4.0),
6096        ]);
6097        let v_inf_neg = Vector::<Complex<f64>, 2>::from([
6098            Complex::new(f64::NEG_INFINITY, 0.0),
6099            Complex::new(3.0, 4.0),
6100        ]);
6101        let v_inf_neg_eq = Vector::<Complex<f64>, 2>::from([
6102            Complex::new(f64::NEG_INFINITY, 0.0),
6103            Complex::new(3.0, 4.0),
6104        ]);
6105
6106        assert!(v1 == v_eq);
6107        assert!(v_eq == v1); // symmetry
6108        assert!(v2 == v_eq);
6109        assert!(v1 == v2); // transitivity
6110        assert!(v1 != v_diff_re);
6111        assert!(v1 != v_diff_im);
6112        assert!(v1 != v_diff_re_im);
6113        assert!(v1 != v_close);
6114        assert!(v_zero == v_zero_eq);
6115        assert!(v_zero == v_zero_neg_eq); // zero and neg zero are defined as equivalent
6116        assert!(v_nan != v_nan_diff); // NaN comparisons are defined as different
6117        assert!(v_inf_pos == v_inf_pos_eq); // postive infinity comparisons are defined as equivalent
6118        assert!(v_inf_neg == v_inf_neg_eq); // negative infinity comparisons are defined as equivalent
6119    }
6120
6121    // ======================================================
6122    //
6123    // approx crate float approximate equivalence trait tests
6124    // AbsDiffEq, RelativeEq, UlpsEq traits
6125    //
6126    // ======================================================
6127
6128    #[test]
6129    fn vector_trait_absdiffeq_f64() {
6130        let v1 = Vector::<f64, 3>::from([-1.1, 2.2, 3.3]);
6131        let v2 = Vector::<f64, 3>::from([-0.1 - 1.0, 2.2, 3.3]);
6132        let v_eq = Vector::<f64, 3>::from([-1.1, 2.2, 3.3]);
6133        let v_diff = Vector::<f64, 3>::from([-1.1, 2.2, 4.4]);
6134        let v_close = Vector::<f64, 3>::from([-1.1 + (f64::EPSILON), 2.2, 3.3]);
6135        let v_not_close_enough = Vector::<f64, 3>::from([-1.1 + (f64::EPSILON * 2.), 2.2, 3.3]);
6136
6137        let v_zero = Vector::<f64, 3>::zero();
6138        let v_zero_eq = Vector::<f64, 3>::zero();
6139        let v_zero_neg_eq = Vector::<f64, 3>::from([-0.0, -0.0, -0.0]);
6140        let v_zero_close = Vector::<f64, 3>::from([0.0 + f64::EPSILON, 0.0, 0.0]);
6141
6142        let v_nan = Vector::<f64, 3>::from([f64::NAN, 0.0, 0.0]);
6143        let v_nan_diff = Vector::<f64, 3>::from([f64::NAN, 0.0, 0.0]);
6144
6145        let v_inf_pos = Vector::<f64, 3>::from([f64::INFINITY, 0.0, 0.0]);
6146        let v_inf_pos_eq = Vector::<f64, 3>::from([f64::INFINITY, 0.0, 0.0]);
6147        let v_inf_neg = Vector::<f64, 3>::from([f64::NEG_INFINITY, 0.0, 0.0]);
6148        let v_inf_neg_eq = Vector::<f64, 3>::from([f64::NEG_INFINITY, 0.0, 0.0]);
6149
6150        assert!(v1.abs_diff_eq(&v_eq, f64::default_epsilon()));
6151        assert!(v_eq.abs_diff_eq(&v1, f64::default_epsilon()));
6152        assert!(v2.abs_diff_eq(&v_eq, f64::default_epsilon()));
6153        assert!(v1.abs_diff_eq(&v2, f64::default_epsilon()));
6154        assert!(!v1.abs_diff_eq(&v_diff, f64::default_epsilon()));
6155        assert!(v1.abs_diff_eq(&v_close, f64::default_epsilon()));
6156        // when difference is epsilon multipled by a factor of 2,
6157        // we are outside of the absolute diff bounds
6158        assert!(!v1.abs_diff_eq(&v_not_close_enough, f64::default_epsilon()));
6159        // unless we adjust the acceptable epsilon threshold, now we consider it eq
6160        assert!(v1.abs_diff_eq(&v_not_close_enough, f64::default_epsilon() * 2.));
6161
6162        assert!(v_zero.abs_diff_eq(&v_zero_eq, f64::default_epsilon()));
6163        assert!(v_zero.abs_diff_eq(&v_zero_neg_eq, f64::default_epsilon()));
6164        // we are within epsilon of zero, consider this eq
6165        assert!(v_zero.abs_diff_eq(&v_zero_close, f64::default_epsilon()));
6166        // but is defined as ne when we decrease epsilon value
6167        assert!(!v_zero.abs_diff_eq(&v_zero_close, f64::default_epsilon() / 2.));
6168
6169        assert!(!v_nan.abs_diff_eq(&v_nan_diff, f64::default_epsilon()));
6170
6171        // note: different result than with relative eq comparison when we test
6172        // infinite values
6173        assert!(!v_inf_pos.abs_diff_eq(&v_inf_pos_eq, f64::default_epsilon()));
6174        assert!(!v_inf_neg.abs_diff_eq(&v_inf_neg_eq, f64::default_epsilon()));
6175        assert!(!v_inf_pos.abs_diff_eq(&v_inf_neg, f64::default_epsilon()));
6176    }
6177
6178    #[test]
6179    fn vector_trait_absdiffeq_complex_f64() {
6180        let v1 = Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.2), Complex::new(3.3, 4.4)]);
6181        let v2 = Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.2), Complex::new(3.3, 4.4)]);
6182        let v_eq =
6183            Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.2), Complex::new(3.3, 4.4)]);
6184        let v_diff_re =
6185            Vector::<Complex<f64>, 2>::from([Complex::new(-1.3, 2.2), Complex::new(3.3, 4.4)]);
6186        let v_diff_im =
6187            Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.4), Complex::new(3.3, 4.4)]);
6188        let v_close = Vector::<Complex<f64>, 2>::from([
6189            Complex::new(-1.1 + (f64::EPSILON), 2.2),
6190            Complex::new(3.3, 4.4),
6191        ]);
6192        let v_not_close_enough_re = Vector::<Complex<f64>, 2>::from([
6193            Complex::new(-1.1 + (f64::EPSILON * 2.), 2.2),
6194            Complex::new(3.3, 4.4),
6195        ]);
6196
6197        let v_not_close_enough_im = Vector::<Complex<f64>, 2>::from([
6198            Complex::new(-1.1, 2.2 + (f64::EPSILON * 2.)),
6199            Complex::new(3.3, 4.4),
6200        ]);
6201
6202        let v_zero = Vector::<Complex<f64>, 2>::zero();
6203        let v_zero_eq = Vector::<Complex<f64>, 2>::zero();
6204        let v_zero_neg_eq =
6205            Vector::<Complex<f64>, 2>::from([Complex::new(-0.0, -0.0), Complex::new(-0.0, -0.0)]);
6206        let v_zero_close = Vector::<Complex<f64>, 2>::from([
6207            Complex::new(0.0 + f64::EPSILON, -0.0),
6208            Complex::new(-0.0, -0.0),
6209        ]);
6210
6211        let v_nan =
6212            Vector::<Complex<f64>, 2>::from([Complex::new(f64::NAN, 0.0), Complex::new(1.0, 2.0)]);
6213        let v_nan_diff =
6214            Vector::<Complex<f64>, 2>::from([Complex::new(f64::NAN, 0.0), Complex::new(1.0, 2.0)]);
6215
6216        let v_inf_pos = Vector::<Complex<f64>, 2>::from([
6217            Complex::new(f64::INFINITY, 0.0),
6218            Complex::new(0.0, f64::INFINITY),
6219        ]);
6220        let v_inf_pos_eq = Vector::<Complex<f64>, 2>::from([
6221            Complex::new(f64::INFINITY, 0.0),
6222            Complex::new(0.0, f64::INFINITY),
6223        ]);
6224        let v_inf_neg = Vector::<Complex<f64>, 2>::from([
6225            Complex::new(f64::NEG_INFINITY, 0.0),
6226            Complex::new(0.0, f64::NEG_INFINITY),
6227        ]);
6228        let v_inf_neg_eq = Vector::<Complex<f64>, 2>::from([
6229            Complex::new(f64::NEG_INFINITY, 0.0),
6230            Complex::new(0.0, f64::NEG_INFINITY),
6231        ]);
6232
6233        assert!(v1.abs_diff_eq(&v_eq, f64::default_epsilon()));
6234        assert!(v_eq.abs_diff_eq(&v1, f64::default_epsilon()));
6235        assert!(v2.abs_diff_eq(&v_eq, f64::default_epsilon()));
6236        assert!(v1.abs_diff_eq(&v2, f64::default_epsilon()));
6237        assert!(!v1.abs_diff_eq(&v_diff_re, f64::default_epsilon()));
6238        assert!(!v1.abs_diff_eq(&v_diff_im, f64::default_epsilon()));
6239        assert!(v1.abs_diff_eq(&v_close, f64::default_epsilon()));
6240        // when difference is epsilon multipled by a factor of 2,
6241        // we are outside of the absolute diff bounds
6242        assert!(!v1.abs_diff_eq(&v_not_close_enough_re, f64::default_epsilon()));
6243        assert!(!v1.abs_diff_eq(&v_not_close_enough_im, f64::default_epsilon()));
6244        // unless we adjust the acceptable epsilon threshold, now we consider it eq
6245        assert!(v1.abs_diff_eq(&v_not_close_enough_re, f64::default_epsilon() * 2.));
6246        assert!(v1.abs_diff_eq(&v_not_close_enough_im, f64::default_epsilon() * 2.));
6247
6248        assert!(v_zero.abs_diff_eq(&v_zero_eq, f64::default_epsilon()));
6249        assert!(v_zero.abs_diff_eq(&v_zero_neg_eq, f64::default_epsilon()));
6250        // we are within epsilon of zero, consider this eq
6251        assert!(v_zero.abs_diff_eq(&v_zero_close, f64::default_epsilon()));
6252        // but is defined as ne when we decrease epsilon value
6253        assert!(!v_zero.abs_diff_eq(&v_zero_close, f64::default_epsilon() / 2.));
6254
6255        assert!(!v_nan.abs_diff_eq(&v_nan_diff, f64::default_epsilon()));
6256
6257        // note: different result than with relative eq comparison when we test
6258        // infinite values
6259        assert!(!v_inf_pos.abs_diff_eq(&v_inf_pos_eq, f64::default_epsilon()));
6260        assert!(!v_inf_neg.abs_diff_eq(&v_inf_neg_eq, f64::default_epsilon()));
6261        assert!(!v_inf_pos.abs_diff_eq(&v_inf_neg, f64::default_epsilon()));
6262    }
6263
6264    #[test]
6265    fn vector_trait_relativeeq_f64() {
6266        let v1 = Vector::<f64, 3>::from([-1.1, 2.2, 3.3]);
6267        let v2 = Vector::<f64, 3>::from([-0.1 - 1.0, 2.2, 3.3]);
6268        let v_eq = Vector::<f64, 3>::from([-1.1, 2.2, 3.3]);
6269        let v_diff = Vector::<f64, 3>::from([-1.1, 2.2, 4.4]);
6270        let v_close = Vector::<f64, 3>::from([-1.1 + (f64::EPSILON), 2.2, 3.3]);
6271        let v_not_close_enough = Vector::<f64, 3>::from([-1.1 + (f64::EPSILON * 2.), 2.2, 3.3]);
6272
6273        let v_zero = Vector::<f64, 3>::zero();
6274        let v_zero_eq = Vector::<f64, 3>::zero();
6275        let v_zero_neg_eq = Vector::<f64, 3>::from([-0.0, -0.0, -0.0]);
6276        let v_zero_close = Vector::<f64, 3>::from([0.0 + f64::EPSILON, 0.0, 0.0]);
6277
6278        let v_nan = Vector::<f64, 3>::from([f64::NAN, 0.0, 0.0]);
6279        let v_nan_diff = Vector::<f64, 3>::from([f64::NAN, 0.0, 0.0]);
6280
6281        let v_inf_pos = Vector::<f64, 3>::from([f64::INFINITY, 0.0, 0.0]);
6282        let v_inf_pos_eq = Vector::<f64, 3>::from([f64::INFINITY, 0.0, 0.0]);
6283        let v_inf_neg = Vector::<f64, 3>::from([f64::NEG_INFINITY, 0.0, 0.0]);
6284        let v_inf_neg_eq = Vector::<f64, 3>::from([f64::NEG_INFINITY, 0.0, 0.0]);
6285
6286        assert!(v1.relative_eq(&v_eq, f64::default_epsilon(), f64::default_epsilon()));
6287        assert!(v_eq.relative_eq(&v1, f64::default_epsilon(), f64::default_epsilon()));
6288        assert!(v2.relative_eq(&v_eq, f64::default_epsilon(), f64::default_epsilon()));
6289        assert!(v1.relative_eq(&v2, f64::default_epsilon(), f64::default_epsilon()));
6290        assert!(!v1.relative_eq(&v_diff, f64::default_epsilon(), f64::default_epsilon()));
6291        assert!(v1.relative_eq(&v_close, f64::default_epsilon(), f64::default_epsilon()));
6292        // when difference is epsilon multiplied by a factor of 2,
6293        // we are outside of the relative diff bounds
6294        assert!(!v1.relative_eq(
6295            &v_not_close_enough,
6296            f64::default_epsilon(),
6297            f64::default_epsilon()
6298        ));
6299        // unless we adjust the acceptable max relative diff
6300        assert!(v1.relative_eq(
6301            &v_not_close_enough,
6302            f64::default_epsilon(),
6303            f64::default_epsilon() * 2.
6304        ));
6305
6306        // near zero use the absolute diff vs. epsilon comparisons
6307        assert!(v_zero.relative_eq(&v_zero_eq, f64::default_epsilon(), f64::default_epsilon()));
6308        assert!(v_zero.relative_eq(&v_zero_neg_eq, f64::default_epsilon(), f64::default_epsilon()));
6309        // considered eq when within epsilon of zero
6310        assert!(v_zero.relative_eq(&v_zero_close, f64::default_epsilon(), f64::default_epsilon()));
6311        // considered ne when we decrease the epsilon definition below the diff from zero
6312        assert!(!v_zero.relative_eq(
6313            &v_zero_close,
6314            f64::default_epsilon() / 2.,
6315            f64::default_epsilon()
6316        ));
6317
6318        assert!(!v_nan.relative_eq(&v_nan_diff, f64::default_epsilon(), f64::default_epsilon()));
6319
6320        assert!(v_inf_pos.relative_eq(
6321            &v_inf_pos_eq,
6322            f64::default_epsilon(),
6323            f64::default_epsilon()
6324        ));
6325        assert!(v_inf_neg.relative_eq(
6326            &v_inf_neg_eq,
6327            f64::default_epsilon(),
6328            f64::default_epsilon()
6329        ));
6330        assert!(!v_inf_pos.relative_eq(&v_inf_neg, f64::default_epsilon(), f64::default_epsilon()));
6331    }
6332
6333    #[test]
6334    fn vector_trait_relativeeq_complex_f64() {
6335        let v1 = Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 1.1), Complex::new(3.3, 4.4)]);
6336        let v2 = Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 1.1), Complex::new(3.3, 4.4)]);
6337        let v_eq =
6338            Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 1.1), Complex::new(3.3, 4.4)]);
6339        let v_diff_re =
6340            Vector::<Complex<f64>, 2>::from([Complex::new(-1.3, 1.1), Complex::new(3.3, 4.4)]);
6341        let v_diff_im =
6342            Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.4), Complex::new(3.3, 4.4)]);
6343        let v_close = Vector::<Complex<f64>, 2>::from([
6344            Complex::new(-1.1 + (f64::EPSILON), 1.1),
6345            Complex::new(3.3, 4.4),
6346        ]);
6347        let v_not_close_enough_re = Vector::<Complex<f64>, 2>::from([
6348            Complex::new(-1.1 + (f64::EPSILON * 2.), 1.1),
6349            Complex::new(3.3, 4.4),
6350        ]);
6351
6352        let v_not_close_enough_im = Vector::<Complex<f64>, 2>::from([
6353            Complex::new(-1.1, 1.1 - (f64::EPSILON * 2.)),
6354            Complex::new(3.3, 4.4),
6355        ]);
6356
6357        let v_zero = Vector::<Complex<f64>, 2>::zero();
6358        let v_zero_eq = Vector::<Complex<f64>, 2>::zero();
6359        let v_zero_neg_eq =
6360            Vector::<Complex<f64>, 2>::from([Complex::new(-0.0, -0.0), Complex::new(-0.0, -0.0)]);
6361        let v_zero_close = Vector::<Complex<f64>, 2>::from([
6362            Complex::new(0.0 + f64::EPSILON, -0.0),
6363            Complex::new(-0.0, -0.0),
6364        ]);
6365
6366        let v_nan =
6367            Vector::<Complex<f64>, 2>::from([Complex::new(f64::NAN, 0.0), Complex::new(1.0, 2.0)]);
6368        let v_nan_diff =
6369            Vector::<Complex<f64>, 2>::from([Complex::new(f64::NAN, 0.0), Complex::new(1.0, 2.0)]);
6370
6371        let v_inf_pos = Vector::<Complex<f64>, 2>::from([
6372            Complex::new(f64::INFINITY, 0.0),
6373            Complex::new(0.0, f64::INFINITY),
6374        ]);
6375        let v_inf_pos_eq = Vector::<Complex<f64>, 2>::from([
6376            Complex::new(f64::INFINITY, 0.0),
6377            Complex::new(0.0, f64::INFINITY),
6378        ]);
6379        let v_inf_neg = Vector::<Complex<f64>, 2>::from([
6380            Complex::new(f64::NEG_INFINITY, 0.0),
6381            Complex::new(0.0, f64::NEG_INFINITY),
6382        ]);
6383        let v_inf_neg_eq = Vector::<Complex<f64>, 2>::from([
6384            Complex::new(f64::NEG_INFINITY, 0.0),
6385            Complex::new(0.0, f64::NEG_INFINITY),
6386        ]);
6387
6388        assert!(v1.relative_eq(&v_eq, f64::default_epsilon(), f64::default_epsilon()));
6389        assert!(v_eq.relative_eq(&v1, f64::default_epsilon(), f64::default_epsilon()));
6390        assert!(v2.relative_eq(&v_eq, f64::default_epsilon(), f64::default_epsilon()));
6391        assert!(v1.relative_eq(&v2, f64::default_epsilon(), f64::default_epsilon()));
6392        assert!(!v1.relative_eq(&v_diff_re, f64::default_epsilon(), f64::default_epsilon()));
6393        assert!(!v1.relative_eq(&v_diff_im, f64::default_epsilon(), f64::default_epsilon()));
6394        assert!(v1.relative_eq(&v_close, f64::default_epsilon(), f64::default_epsilon()));
6395        // when difference is epsilon multiplied by a factor of 2,
6396        // we are outside of the relative diff bounds
6397        assert!(!v1.relative_eq(
6398            &v_not_close_enough_re,
6399            f64::default_epsilon(),
6400            f64::default_epsilon()
6401        ));
6402        assert!(!v1.relative_eq(
6403            &v_not_close_enough_im,
6404            f64::default_epsilon(),
6405            f64::default_epsilon()
6406        ));
6407        // unless we adjust the acceptable max relative diff
6408        assert!(v1.relative_eq(
6409            &v_not_close_enough_re,
6410            f64::default_epsilon(),
6411            f64::default_epsilon() * 2.
6412        ));
6413        assert!(v1.relative_eq(
6414            &v_not_close_enough_im,
6415            f64::default_epsilon(),
6416            f64::default_epsilon() * 2.
6417        ));
6418
6419        // near zero use the absolute diff vs. epsilon comparisons
6420        assert!(v_zero.relative_eq(&v_zero_eq, f64::default_epsilon(), f64::default_epsilon()));
6421        assert!(v_zero.relative_eq(&v_zero_neg_eq, f64::default_epsilon(), f64::default_epsilon()));
6422        // considered eq when within epsilon of zero
6423        assert!(v_zero.relative_eq(&v_zero_close, f64::default_epsilon(), f64::default_epsilon()));
6424        // considered ne when we decrease the epsilon definition below the diff from zero
6425        assert!(!v_zero.relative_eq(
6426            &v_zero_close,
6427            f64::default_epsilon() / 2.,
6428            f64::default_epsilon()
6429        ));
6430
6431        assert!(!v_nan.relative_eq(&v_nan_diff, f64::default_epsilon(), f64::default_epsilon()));
6432
6433        assert!(v_inf_pos.relative_eq(
6434            &v_inf_pos_eq,
6435            f64::default_epsilon(),
6436            f64::default_epsilon()
6437        ));
6438        assert!(v_inf_neg.relative_eq(
6439            &v_inf_neg_eq,
6440            f64::default_epsilon(),
6441            f64::default_epsilon()
6442        ));
6443        assert!(!v_inf_pos.relative_eq(&v_inf_neg, f64::default_epsilon(), f64::default_epsilon()));
6444    }
6445
6446    #[test]
6447    fn vector_trait_ulpseq_f64() {
6448        let v1 = Vector::<f64, 3>::from([-1.1, 2.2, 3.3]);
6449        let v2 = Vector::<f64, 3>::from([-0.1 - 1.0, 2.2, 3.3]);
6450        let v_eq = Vector::<f64, 3>::from([-1.1, 2.2, 3.3]);
6451        let v_diff = Vector::<f64, 3>::from([-1.1, 2.2, 4.4]);
6452        let v_close = Vector::<f64, 3>::from([-1.1 + (f64::EPSILON), 2.2, 3.3]);
6453        let v_not_close_enough = Vector::<f64, 3>::from([-1.1 + (f64::EPSILON * 2.), 2.2, 3.3]);
6454
6455        let v_zero = Vector::<f64, 3>::zero();
6456        let v_zero_eq = Vector::<f64, 3>::zero();
6457        let v_zero_neg_eq = Vector::<f64, 3>::from([-0.0, -0.0, -0.0]);
6458        let v_zero_close = Vector::<f64, 3>::from([0.0 + f64::EPSILON, 0.0, 0.0]);
6459
6460        let v_nan = Vector::<f64, 3>::from([f64::NAN, 0.0, 0.0]);
6461        let v_nan_diff = Vector::<f64, 3>::from([f64::NAN, 0.0, 0.0]);
6462
6463        let v_inf_pos = Vector::<f64, 3>::from([f64::INFINITY, 0.0, 0.0]);
6464        let v_inf_pos_eq = Vector::<f64, 3>::from([f64::INFINITY, 0.0, 0.0]);
6465        let v_inf_neg = Vector::<f64, 3>::from([f64::NEG_INFINITY, 0.0, 0.0]);
6466        let v_inf_neg_eq = Vector::<f64, 3>::from([f64::NEG_INFINITY, 0.0, 0.0]);
6467
6468        assert!(v1.ulps_eq(&v_eq, f64::default_epsilon(), 1));
6469        assert!(v_eq.ulps_eq(&v1, f64::default_epsilon(), 1));
6470        assert!(v2.ulps_eq(&v_eq, f64::default_epsilon(), 1));
6471        assert!(v1.ulps_eq(&v2, f64::default_epsilon(), 1));
6472        assert!(!v1.ulps_eq(&v_diff, f64::default_epsilon(), 1));
6473        assert!(v1.ulps_eq(&v_close, f64::default_epsilon(), 1));
6474        // when difference is epsilon multipled by a factor of 2,
6475        // we are outside of the diff bounds defined by max ulps = 1
6476        assert!(!v1.ulps_eq(&v_not_close_enough, f64::default_epsilon(), 1));
6477        // unless we adjust the acceptable ulps threshold
6478        assert!(v1.ulps_eq(&v_not_close_enough, f64::default_epsilon(), 2));
6479
6480        // near zero, use the epsilon value and absolute diff vs. epsilon comparisons
6481        assert!(v_zero.ulps_eq(&v_zero_eq, f64::default_epsilon(), 1));
6482        assert!(v_zero.ulps_eq(&v_zero_neg_eq, f64::default_epsilon(), 1));
6483        // we are within epsilon of zero, consider this eq
6484        assert!(v_zero.ulps_eq(&v_zero_close, f64::default_epsilon(), 1));
6485        // but is defined as ne when we decrease epsilon value
6486        assert!(!v_zero.ulps_eq(&v_zero_close, f64::default_epsilon() / 2., 1));
6487
6488        assert!(!v_nan.ulps_eq(&v_nan_diff, f64::default_epsilon(), 1));
6489
6490        assert!(v_inf_pos.ulps_eq(&v_inf_pos_eq, f64::default_epsilon(), 1));
6491        assert!(v_inf_neg.ulps_eq(&v_inf_neg_eq, f64::default_epsilon(), 1));
6492        assert!(!v_inf_pos.ulps_eq(&v_inf_neg, f64::default_epsilon(), 1));
6493    }
6494
6495    #[test]
6496    fn vector_trait_ulpseq_complex_f64() {
6497        let v1 = Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 1.1), Complex::new(3.3, 4.4)]);
6498        let v2 = Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 1.1), Complex::new(3.3, 4.4)]);
6499        let v_eq =
6500            Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 1.1), Complex::new(3.3, 4.4)]);
6501        let v_diff_re =
6502            Vector::<Complex<f64>, 2>::from([Complex::new(-1.3, 1.1), Complex::new(3.3, 4.4)]);
6503        let v_diff_im =
6504            Vector::<Complex<f64>, 2>::from([Complex::new(-1.1, 2.4), Complex::new(3.3, 4.4)]);
6505        let v_close = Vector::<Complex<f64>, 2>::from([
6506            Complex::new(-1.1 + (f64::EPSILON), 1.1),
6507            Complex::new(3.3, 4.4),
6508        ]);
6509        let v_not_close_enough_re = Vector::<Complex<f64>, 2>::from([
6510            Complex::new(-1.1 + (f64::EPSILON * 2.), 1.1),
6511            Complex::new(3.3, 4.4),
6512        ]);
6513
6514        let v_not_close_enough_im = Vector::<Complex<f64>, 2>::from([
6515            Complex::new(-1.1, 1.1 - (f64::EPSILON * 2.)),
6516            Complex::new(3.3, 4.4),
6517        ]);
6518
6519        let v_zero = Vector::<Complex<f64>, 2>::zero();
6520        let v_zero_eq = Vector::<Complex<f64>, 2>::zero();
6521        let v_zero_neg_eq =
6522            Vector::<Complex<f64>, 2>::from([Complex::new(-0.0, -0.0), Complex::new(-0.0, -0.0)]);
6523        let v_zero_close = Vector::<Complex<f64>, 2>::from([
6524            Complex::new(0.0 + f64::EPSILON, -0.0),
6525            Complex::new(-0.0, -0.0),
6526        ]);
6527
6528        let v_nan =
6529            Vector::<Complex<f64>, 2>::from([Complex::new(f64::NAN, 0.0), Complex::new(1.0, 2.0)]);
6530        let v_nan_diff =
6531            Vector::<Complex<f64>, 2>::from([Complex::new(f64::NAN, 0.0), Complex::new(1.0, 2.0)]);
6532
6533        let v_inf_pos = Vector::<Complex<f64>, 2>::from([
6534            Complex::new(f64::INFINITY, 0.0),
6535            Complex::new(0.0, f64::INFINITY),
6536        ]);
6537        let v_inf_pos_eq = Vector::<Complex<f64>, 2>::from([
6538            Complex::new(f64::INFINITY, 0.0),
6539            Complex::new(0.0, f64::INFINITY),
6540        ]);
6541        let v_inf_neg = Vector::<Complex<f64>, 2>::from([
6542            Complex::new(f64::NEG_INFINITY, 0.0),
6543            Complex::new(0.0, f64::NEG_INFINITY),
6544        ]);
6545        let v_inf_neg_eq = Vector::<Complex<f64>, 2>::from([
6546            Complex::new(f64::NEG_INFINITY, 0.0),
6547            Complex::new(0.0, f64::NEG_INFINITY),
6548        ]);
6549
6550        assert!(v1.ulps_eq(&v_eq, f64::default_epsilon(), 1));
6551        assert!(v_eq.ulps_eq(&v1, f64::default_epsilon(), 1));
6552        assert!(v2.ulps_eq(&v_eq, f64::default_epsilon(), 1));
6553        assert!(v1.ulps_eq(&v2, f64::default_epsilon(), 1));
6554        assert!(!v1.ulps_eq(&v_diff_re, f64::default_epsilon(), 1));
6555        assert!(!v1.ulps_eq(&v_diff_im, f64::default_epsilon(), 1));
6556        assert!(v1.ulps_eq(&v_close, f64::default_epsilon(), 1));
6557        // when difference is epsilon multipled by a factor of 2,
6558        // we are outside of the diff bounds defined by max ulps = 1
6559        assert!(!v1.ulps_eq(&v_not_close_enough_re, f64::default_epsilon(), 1));
6560        assert!(!v1.ulps_eq(&v_not_close_enough_im, f64::default_epsilon(), 1));
6561        // unless we adjust the acceptable ulps threshold
6562        assert!(v1.ulps_eq(&v_not_close_enough_re, f64::default_epsilon(), 2));
6563        assert!(v1.ulps_eq(&v_not_close_enough_im, f64::default_epsilon(), 2));
6564
6565        // near zero, use the epsilon value and absolute diff vs. epsilon comparisons
6566        assert!(v_zero.ulps_eq(&v_zero_eq, f64::default_epsilon(), 1));
6567        assert!(v_zero.ulps_eq(&v_zero_neg_eq, f64::default_epsilon(), 1));
6568        // we are within epsilon of zero, consider this eq
6569        assert!(v_zero.ulps_eq(&v_zero_close, f64::default_epsilon(), 1));
6570        // but is defined as ne when we decrease epsilon value
6571        assert!(!v_zero.ulps_eq(&v_zero_close, f64::default_epsilon() / 2., 1));
6572
6573        assert!(!v_nan.ulps_eq(&v_nan_diff, f64::default_epsilon(), 1));
6574
6575        assert!(v_inf_pos.ulps_eq(&v_inf_pos_eq, f64::default_epsilon(), 1));
6576        assert!(v_inf_neg.ulps_eq(&v_inf_neg_eq, f64::default_epsilon(), 1));
6577        assert!(!v_inf_pos.ulps_eq(&v_inf_neg, f64::default_epsilon(), 1));
6578    }
6579
6580    // ================================
6581    //
6582    // AsRef / AsMutRef trait tests
6583    //
6584    // ================================
6585    #[test]
6586    fn vector_trait_as_ref() {
6587        let v = Vector::<u32, 3>::from(&[1, 2, 3]);
6588        let test_vector: &Vector<u32, 3> = v.as_ref();
6589        let test_slice: &[u32] = v.as_ref();
6590
6591        assert_eq!(test_vector[0], 1);
6592        assert_eq!(test_vector[1], 2);
6593        assert_eq!(test_vector[2], 3);
6594
6595        assert_eq!(test_slice[0], 1);
6596        assert_eq!(test_slice[1], 2);
6597        assert_eq!(test_slice[2], 3);
6598    }
6599
6600    #[test]
6601    fn vector_trait_as_mut() {
6602        let mut v1 = Vector::<u32, 3>::from(&[1, 2, 3]);
6603        let mut v2 = Vector::<u32, 3>::from(&[1, 2, 3]);
6604        let test_vector: &mut Vector<u32, 3> = v1.as_mut();
6605        let test_slice: &mut [u32] = v2.as_mut();
6606
6607        test_vector[0] = 10;
6608        test_slice[0] = 10;
6609
6610        assert_eq!(test_vector.components.len(), 3);
6611        assert_eq!(test_vector[0], 10);
6612        assert_eq!(test_vector[1], 2);
6613        assert_eq!(test_vector[2], 3);
6614
6615        assert_eq!(test_slice.len(), 3);
6616        assert_eq!(test_slice[0], 10);
6617        assert_eq!(test_slice[1], 2);
6618        assert_eq!(test_slice[2], 3);
6619    }
6620
6621    // ================================
6622    //
6623    // Borrow / BorrowMut trait tests
6624    //
6625    // ================================
6626    #[test]
6627    fn vector_trait_borrow() {
6628        let v = Vector::<u32, 3>::from(&[1, 2, 3]);
6629        let test_slice: &[u32] = v.borrow();
6630
6631        assert_eq!(test_slice, [1, 2, 3]);
6632    }
6633
6634    #[test]
6635    fn vector_trait_borrow_mut() {
6636        let mut v = Vector::<u32, 3>::from(&[1, 2, 3]);
6637        let test_slice: &mut [u32] = v.borrow_mut();
6638
6639        test_slice[0] = 10;
6640
6641        assert_eq!(test_slice, [10, 2, 3]);
6642    }
6643
6644    // ================================
6645    //
6646    // Deref / DerefMut trait tests
6647    //
6648    // ================================
6649    #[test]
6650    fn vector_trait_deref() {
6651        let v = Vector::<u32, 3>::from(&[1, 2, 3]);
6652        let test_slice: &[u32] = &v;
6653
6654        assert_eq!(test_slice, [1, 2, 3]);
6655    }
6656
6657    #[test]
6658    fn vector_trait_deref_mut() {
6659        let mut v = Vector::<u32, 3>::from(&[1, 2, 3]);
6660        let test_slice: &mut [u32] = &mut v;
6661
6662        assert_eq!(test_slice, [1, 2, 3]);
6663    }
6664
6665    // ================================
6666    //
6667    // From trait tests
6668    //
6669    // ================================
6670    #[test]
6671    fn vector_trait_from_into_uint_to_uint() {
6672        let v_u8 = Vector::<u8, 3>::from(&[1, 2, 3]);
6673        let v_u16 = Vector::<u16, 3>::new();
6674        let v_u32 = Vector::<u32, 3>::new();
6675        let v_u64 = Vector::<u64, 3>::new();
6676
6677        let v_new_16: Vector<u16, 3> = Vector::<u16, 3>::from(v_u8);
6678        let _: Vector<u16, 3> = v_u8.into();
6679        assert_eq!(v_new_16.components.len(), 3);
6680        assert_eq!(v_new_16[0], 1 as u16);
6681        assert_eq!(v_new_16[1], 2 as u16);
6682        assert_eq!(v_new_16[2], 3 as u16);
6683
6684        let _: Vector<u32, 3> = Vector::<u32, 3>::from(v_u8);
6685        let _: Vector<u32, 3> = v_u8.into();
6686
6687        let _: Vector<u64, 3> = Vector::<u64, 3>::from(v_u8);
6688        let _: Vector<u64, 3> = v_u8.into();
6689
6690        let _: Vector<u128, 3> = Vector::<u128, 3>::from(v_u8);
6691        let _: Vector<u128, 3> = v_u8.into();
6692
6693        let _: Vector<u32, 3> = Vector::<u32, 3>::from(v_u16);
6694        let _: Vector<u32, 3> = v_u16.into();
6695
6696        let _: Vector<u64, 3> = Vector::<u64, 3>::from(v_u16);
6697        let _: Vector<u64, 3> = v_u16.into();
6698
6699        let _: Vector<u128, 3> = Vector::<u128, 3>::from(v_u16);
6700        let _: Vector<u128, 3> = v_u16.into();
6701
6702        let _: Vector<u64, 3> = Vector::<u64, 3>::from(v_u32);
6703        let _: Vector<u64, 3> = v_u32.into();
6704
6705        let _: Vector<u128, 3> = Vector::<u128, 3>::from(v_u32);
6706        let _: Vector<u128, 3> = v_u32.into();
6707
6708        let _: Vector<u128, 3> = Vector::<u128, 3>::from(v_u64);
6709        let _: Vector<u128, 3> = v_u64.into();
6710    }
6711
6712    #[test]
6713    fn vector_trait_from_into_complex_uint_to_complex_uint() {
6714        let v_u8 = Vector::<Complex<u8>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6715        let v_u16 = Vector::<Complex<u16>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6716        let v_u32 = Vector::<Complex<u32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6717        let v_u64 = Vector::<Complex<u64>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6718
6719        let v_new_16: Vector<Complex<u16>, 2> = Vector::from(v_u8);
6720        let _: Vector<Complex<u16>, 2> = v_u8.into();
6721        assert_eq!(v_new_16.components.len(), 2);
6722        assert_eq!(v_new_16[0].re, 1 as u16);
6723        assert_eq!(v_new_16[1].re, 3 as u16);
6724        assert_eq!(v_new_16[0].im, 2 as u16);
6725        assert_eq!(v_new_16[1].im, 4 as u16);
6726
6727        let _: Vector<Complex<u32>, 2> = Vector::from(v_u8);
6728        let _: Vector<Complex<u32>, 2> = v_u8.into();
6729
6730        let _: Vector<Complex<u64>, 2> = Vector::from(v_u8);
6731        let _: Vector<Complex<u64>, 2> = v_u8.into();
6732
6733        let _: Vector<Complex<u128>, 2> = Vector::from(v_u8);
6734        let _: Vector<Complex<u128>, 2> = v_u8.into();
6735
6736        let _: Vector<Complex<u32>, 2> = Vector::from(v_u16);
6737        let _: Vector<Complex<u32>, 2> = v_u16.into();
6738
6739        let _: Vector<Complex<u64>, 2> = Vector::from(v_u16);
6740        let _: Vector<Complex<u64>, 2> = v_u16.into();
6741
6742        let _: Vector<Complex<u128>, 2> = Vector::from(v_u16);
6743        let _: Vector<Complex<u128>, 2> = v_u16.into();
6744
6745        let _: Vector<Complex<u64>, 2> = Vector::from(v_u32);
6746        let _: Vector<Complex<u64>, 2> = v_u32.into();
6747
6748        let _: Vector<Complex<u128>, 2> = Vector::from(v_u32);
6749        let _: Vector<Complex<u128>, 2> = v_u32.into();
6750
6751        let _: Vector<Complex<u128>, 2> = Vector::from(v_u64);
6752        let _: Vector<Complex<u128>, 2> = v_u64.into();
6753    }
6754
6755    #[test]
6756    fn vector_trait_from_into_iint_to_iint() {
6757        let v_i8 = Vector::<i8, 3>::from(&[1, 2, 3]);
6758        let v_i16 = Vector::<i16, 3>::new();
6759        let v_i32 = Vector::<i32, 3>::new();
6760        let v_i64 = Vector::<i64, 3>::new();
6761
6762        let v_new_16: Vector<i16, 3> = Vector::<i16, 3>::from(v_i8);
6763        let _: Vector<i16, 3> = v_i8.into();
6764        assert_eq!(v_new_16.components.len(), 3);
6765        assert_eq!(v_new_16[0], 1 as i16);
6766        assert_eq!(v_new_16[1], 2 as i16);
6767        assert_eq!(v_new_16[2], 3 as i16);
6768
6769        let _: Vector<i32, 3> = Vector::<i32, 3>::from(v_i8);
6770        let _: Vector<i32, 3> = v_i8.into();
6771
6772        let _: Vector<i64, 3> = Vector::<i64, 3>::from(v_i8);
6773        let _: Vector<i64, 3> = v_i8.into();
6774
6775        let _: Vector<i128, 3> = Vector::<i128, 3>::from(v_i8);
6776        let _: Vector<i128, 3> = v_i8.into();
6777
6778        let _: Vector<i32, 3> = Vector::<i32, 3>::from(v_i16);
6779        let _: Vector<i32, 3> = v_i16.into();
6780
6781        let _: Vector<i64, 3> = Vector::<i64, 3>::from(v_i16);
6782        let _: Vector<i64, 3> = v_i16.into();
6783
6784        let _: Vector<i128, 3> = Vector::<i128, 3>::from(v_i16);
6785        let _: Vector<i128, 3> = v_i16.into();
6786
6787        let _: Vector<i64, 3> = Vector::<i64, 3>::from(v_i32);
6788        let _: Vector<i64, 3> = v_i32.into();
6789
6790        let _: Vector<i128, 3> = Vector::<i128, 3>::from(v_i32);
6791        let _: Vector<i128, 3> = v_i32.into();
6792
6793        let _: Vector<i128, 3> = Vector::<i128, 3>::from(v_i64);
6794        let _: Vector<i128, 3> = v_i64.into();
6795    }
6796
6797    #[test]
6798    fn vector_trait_from_into_complex_iint_to_complex_iint() {
6799        let v_i8 = Vector::<Complex<i8>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6800        let v_i16 = Vector::<Complex<i16>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6801        let v_i32 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6802        let v_i64 = Vector::<Complex<i64>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6803
6804        let v_new_16: Vector<Complex<i16>, 2> = Vector::from(v_i8);
6805        let _: Vector<Complex<i16>, 2> = v_i8.into();
6806        assert_eq!(v_new_16.components.len(), 2);
6807        assert_eq!(v_new_16[0].re, 1 as i16);
6808        assert_eq!(v_new_16[1].re, 3 as i16);
6809        assert_eq!(v_new_16[0].im, 2 as i16);
6810        assert_eq!(v_new_16[1].im, 4 as i16);
6811
6812        let _: Vector<Complex<i32>, 2> = Vector::from(v_i8);
6813        let _: Vector<Complex<i32>, 2> = v_i8.into();
6814
6815        let _: Vector<Complex<i64>, 2> = Vector::from(v_i8);
6816        let _: Vector<Complex<i64>, 2> = v_i8.into();
6817
6818        let _: Vector<Complex<i128>, 2> = Vector::from(v_i8);
6819        let _: Vector<Complex<i128>, 2> = v_i8.into();
6820
6821        let _: Vector<Complex<i32>, 2> = Vector::from(v_i16);
6822        let _: Vector<Complex<i32>, 2> = v_i16.into();
6823
6824        let _: Vector<Complex<i64>, 2> = Vector::from(v_i16);
6825        let _: Vector<Complex<i64>, 2> = v_i16.into();
6826
6827        let _: Vector<Complex<i128>, 2> = Vector::from(v_i16);
6828        let _: Vector<Complex<i128>, 2> = v_i16.into();
6829
6830        let _: Vector<Complex<i64>, 2> = Vector::from(v_i32);
6831        let _: Vector<Complex<i64>, 2> = v_i32.into();
6832
6833        let _: Vector<Complex<i128>, 2> = Vector::from(v_i32);
6834        let _: Vector<Complex<i128>, 2> = v_i32.into();
6835
6836        let _: Vector<Complex<i128>, 2> = Vector::from(v_i64);
6837        let _: Vector<Complex<i128>, 2> = v_i64.into();
6838    }
6839
6840    #[test]
6841    fn vector_trait_from_into_uint_to_iint() {
6842        let v_u8 = Vector::<u8, 3>::from(&[1, 2, 3]);
6843        let v_u16 = Vector::<u16, 3>::new();
6844        let v_u32 = Vector::<u32, 3>::new();
6845        let v_u64 = Vector::<u64, 3>::new();
6846
6847        let v_new_16: Vector<i16, 3> = Vector::<i16, 3>::from(v_u8);
6848        let _: Vector<i16, 3> = v_u8.into();
6849        assert_eq!(v_new_16.components.len(), 3);
6850        assert_eq!(v_new_16[0], 1 as i16);
6851        assert_eq!(v_new_16[1], 2 as i16);
6852        assert_eq!(v_new_16[2], 3 as i16);
6853
6854        let _: Vector<i32, 3> = Vector::<i32, 3>::from(v_u8);
6855        let _: Vector<i32, 3> = v_u8.into();
6856
6857        let _: Vector<i64, 3> = Vector::<i64, 3>::from(v_u8);
6858        let _: Vector<i64, 3> = v_u8.into();
6859
6860        let _: Vector<i64, 3> = Vector::<i64, 3>::from(v_u8);
6861        let _: Vector<i64, 3> = v_u8.into();
6862
6863        let _: Vector<i128, 3> = Vector::<i128, 3>::from(v_u8);
6864        let _: Vector<i128, 3> = v_u8.into();
6865
6866        let _: Vector<i32, 3> = Vector::<i32, 3>::from(v_u16);
6867        let _: Vector<i32, 3> = v_u16.into();
6868
6869        let _: Vector<i64, 3> = Vector::<i64, 3>::from(v_u16);
6870        let _: Vector<i64, 3> = v_u16.into();
6871
6872        let _: Vector<i128, 3> = Vector::<i128, 3>::from(v_u16);
6873        let _: Vector<i128, 3> = v_u16.into();
6874
6875        let _: Vector<i64, 3> = Vector::<i64, 3>::from(v_u32);
6876        let _: Vector<i64, 3> = v_u32.into();
6877
6878        let _: Vector<i128, 3> = Vector::<i128, 3>::from(v_u32);
6879        let _: Vector<i128, 3> = v_u32.into();
6880
6881        let _: Vector<i128, 3> = Vector::<i128, 3>::from(v_u64);
6882        let _: Vector<i128, 3> = v_u64.into();
6883    }
6884
6885    #[test]
6886    fn vector_trait_from_into_complex_uint_to_complex_iint() {
6887        let v_u8 = Vector::<Complex<u8>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6888        let v_u16 = Vector::<Complex<u16>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6889        let v_u32 = Vector::<Complex<u32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6890        let v_u64 = Vector::<Complex<u64>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6891
6892        let v_new_16: Vector<Complex<i16>, 2> = Vector::from(v_u8);
6893        let _: Vector<Complex<i16>, 2> = v_u8.into();
6894        assert_eq!(v_new_16.components.len(), 2);
6895        assert_eq!(v_new_16[0].re, 1 as i16);
6896        assert_eq!(v_new_16[1].re, 3 as i16);
6897        assert_eq!(v_new_16[0].im, 2 as i16);
6898        assert_eq!(v_new_16[1].im, 4 as i16);
6899
6900        let _: Vector<Complex<i32>, 2> = Vector::from(v_u8);
6901        let _: Vector<Complex<i32>, 2> = v_u8.into();
6902
6903        let _: Vector<Complex<i64>, 2> = Vector::from(v_u8);
6904        let _: Vector<Complex<i64>, 2> = v_u8.into();
6905
6906        let _: Vector<Complex<i128>, 2> = Vector::from(v_u8);
6907        let _: Vector<Complex<i128>, 2> = v_u8.into();
6908
6909        let _: Vector<Complex<i32>, 2> = Vector::from(v_u16);
6910        let _: Vector<Complex<i32>, 2> = v_u16.into();
6911
6912        let _: Vector<Complex<i64>, 2> = Vector::from(v_u16);
6913        let _: Vector<Complex<i64>, 2> = v_u16.into();
6914
6915        let _: Vector<Complex<i128>, 2> = Vector::from(v_u16);
6916        let _: Vector<Complex<i128>, 2> = v_u16.into();
6917
6918        let _: Vector<Complex<i64>, 2> = Vector::from(v_u32);
6919        let _: Vector<Complex<i64>, 2> = v_u32.into();
6920
6921        let _: Vector<Complex<i128>, 2> = Vector::from(v_u32);
6922        let _: Vector<Complex<i128>, 2> = v_u32.into();
6923
6924        let _: Vector<Complex<i128>, 2> = Vector::from(v_u64);
6925        let _: Vector<Complex<i128>, 2> = v_u64.into();
6926    }
6927
6928    #[test]
6929    fn vector_trait_from_into_uint_to_float() {
6930        let v_u8 = Vector::<u8, 3>::from(&[1, 2, 3]);
6931        let v_u16 = Vector::<u16, 3>::new();
6932        let v_u32 = Vector::<u32, 3>::new();
6933
6934        let v_new_32: Vector<f32, 3> = Vector::<f32, 3>::from(v_u8);
6935        let _: Vector<f32, 3> = v_u8.into();
6936        assert_eq!(v_new_32.components.len(), 3);
6937        assert_relative_eq!(v_new_32[0], 1.0 as f32);
6938        assert_relative_eq!(v_new_32[1], 2.0 as f32);
6939        assert_relative_eq!(v_new_32[2], 3.0 as f32);
6940
6941        let _: Vector<f64, 3> = Vector::<f64, 3>::from(v_u8);
6942        let _: Vector<f64, 3> = v_u8.into();
6943
6944        let _: Vector<f32, 3> = Vector::<f32, 3>::from(v_u16);
6945        let _: Vector<f32, 3> = v_u16.into();
6946
6947        let _: Vector<f64, 3> = Vector::<f64, 3>::from(v_u16);
6948        let _: Vector<f64, 3> = v_u16.into();
6949
6950        let _: Vector<f64, 3> = Vector::<f64, 3>::from(v_u32);
6951        let _: Vector<f64, 3> = v_u32.into();
6952    }
6953
6954    #[test]
6955    fn vector_trait_from_into_complex_uint_to_complex_float() {
6956        let v_u8 = Vector::<Complex<u8>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6957        let v_u16 = Vector::<Complex<u16>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6958        let v_u32 = Vector::<Complex<u32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
6959
6960        let v_new_32: Vector<Complex<f32>, 2> = Vector::from(v_u8);
6961        let _: Vector<Complex<f32>, 2> = v_u8.into();
6962        assert_eq!(v_new_32.components.len(), 2);
6963        assert_relative_eq!(v_new_32[0].re, 1.0 as f32);
6964        assert_relative_eq!(v_new_32[0].im, 2.0 as f32);
6965        assert_relative_eq!(v_new_32[1].re, 3.0 as f32);
6966        assert_relative_eq!(v_new_32[1].im, 4.0 as f32);
6967
6968        let _: Vector<Complex<f64>, 2> = Vector::from(v_u8);
6969        let _: Vector<Complex<f64>, 2> = v_u8.into();
6970
6971        let _: Vector<Complex<f64>, 2> = Vector::from(v_u16);
6972        let _: Vector<Complex<f64>, 2> = v_u16.into();
6973
6974        let _: Vector<Complex<f64>, 2> = Vector::from(v_u16);
6975        let _: Vector<Complex<f64>, 2> = v_u16.into();
6976
6977        let _: Vector<Complex<f64>, 2> = Vector::from(v_u32);
6978        let _: Vector<Complex<f64>, 2> = v_u32.into();
6979    }
6980
6981    #[test]
6982    fn vector_trait_from_into_iint_to_float() {
6983        let v_i8 = Vector::<i8, 3>::from(&[1, 2, 3]);
6984        let v_i16 = Vector::<i16, 3>::new();
6985        let v_i32 = Vector::<i32, 3>::new();
6986
6987        let v_new_32: Vector<f32, 3> = Vector::<f32, 3>::from(v_i8);
6988        let _: Vector<f32, 3> = v_i8.into();
6989        assert_eq!(v_new_32.components.len(), 3);
6990        assert_relative_eq!(v_new_32[0], 1.0 as f32);
6991        assert_relative_eq!(v_new_32[1], 2.0 as f32);
6992        assert_relative_eq!(v_new_32[2], 3.0 as f32);
6993
6994        let _: Vector<f64, 3> = Vector::<f64, 3>::from(v_i8);
6995        let _: Vector<f64, 3> = v_i8.into();
6996
6997        let _: Vector<f32, 3> = Vector::<f32, 3>::from(v_i16);
6998        let _: Vector<f32, 3> = v_i16.into();
6999
7000        let _: Vector<f64, 3> = Vector::<f64, 3>::from(v_i16);
7001        let _: Vector<f64, 3> = v_i16.into();
7002
7003        let _: Vector<f64, 3> = Vector::<f64, 3>::from(v_i32);
7004        let _: Vector<f64, 3> = v_i32.into();
7005    }
7006
7007    #[test]
7008    fn vector_trait_from_into_complex_iint_to_complex_float() {
7009        let v_i8 = Vector::<Complex<i8>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
7010        let v_i16 = Vector::<Complex<i16>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
7011        let v_i32 = Vector::<Complex<i32>, 2>::from([Complex::new(1, 2), Complex::new(3, 4)]);
7012
7013        let v_new_32: Vector<Complex<f32>, 2> = Vector::from(v_i8);
7014        let _: Vector<Complex<f32>, 2> = v_i8.into();
7015        assert_eq!(v_new_32.components.len(), 2);
7016        assert_relative_eq!(v_new_32[0].re, 1.0 as f32);
7017        assert_relative_eq!(v_new_32[0].im, 2.0 as f32);
7018        assert_relative_eq!(v_new_32[1].re, 3.0 as f32);
7019        assert_relative_eq!(v_new_32[1].im, 4.0 as f32);
7020
7021        let _: Vector<Complex<f64>, 2> = Vector::from(v_i8);
7022        let _: Vector<Complex<f64>, 2> = v_i8.into();
7023
7024        let _: Vector<Complex<f64>, 2> = Vector::from(v_i16);
7025        let _: Vector<Complex<f64>, 2> = v_i16.into();
7026
7027        let _: Vector<Complex<f64>, 2> = Vector::from(v_i16);
7028        let _: Vector<Complex<f64>, 2> = v_i16.into();
7029
7030        let _: Vector<Complex<f64>, 2> = Vector::from(v_i32);
7031        let _: Vector<Complex<f64>, 2> = v_i32.into();
7032    }
7033
7034    #[test]
7035    fn vector_trait_from_into_float_to_float() {
7036        let v_f32 = Vector::<f32, 3>::from([1.0, 2.0, 3.0]);
7037
7038        let v_new_f64: Vector<f64, 3> = Vector::from(v_f32);
7039        let _: Vector<f64, 3> = v_f32.into();
7040        assert_relative_eq!(v_new_f64[0], 1.0 as f64);
7041        assert_relative_eq!(v_new_f64[1], 2.0 as f64);
7042        assert_relative_eq!(v_new_f64[2], 3.0 as f64);
7043    }
7044
7045    #[test]
7046    fn vector_trait_from_into_complex_float_to_complex_float() {
7047        let v_f32 =
7048            Vector::<Complex<f32>, 2>::from([Complex::new(1.0, 2.0), Complex::new(3.0, 4.0)]);
7049
7050        let v_new_f64: Vector<Complex<f64>, 2> = Vector::from(v_f32);
7051        let _: Vector<Complex<f64>, 2> = v_f32.into();
7052        assert_relative_eq!(v_new_f64[0].re, 1.0 as f64);
7053        assert_relative_eq!(v_new_f64[0].im, 2.0 as f64);
7054        assert_relative_eq!(v_new_f64[1].re, 3.0 as f64);
7055        assert_relative_eq!(v_new_f64[1].im, 4.0 as f64);
7056    }
7057
7058    #[test]
7059    fn vector_trait_from_into_array_to_vector() {
7060        let a = [1, 2, 3];
7061        let a_slice = &a[..];
7062        // from / into with array
7063        let va = Vector::<i32, 3>::from(a);
7064        let va2: Vector<i32, 3> = Vector::from(&a);
7065        let va3: Vector<i32, 3> = a.into();
7066        assert_eq!(va.components.len(), 3);
7067        assert_eq!(va[0], 1 as i32);
7068        assert_eq!(va[1], 2 as i32);
7069        assert_eq!(va[2], 3 as i32);
7070        assert_eq!(va, va2);
7071        assert_eq!(va, va3);
7072        // from / into with array slice
7073        let vas: Vector<i32, 3> = Vector::<i32, 3>::try_from(a_slice).unwrap();
7074        let vas2: Vector<i32, 3> = Vector::try_from(&a[..]).unwrap();
7075        let vas3: Vector<i32, 3> = a_slice.try_into().unwrap();
7076        assert_eq!(vas.components.len(), 3);
7077        assert_eq!(vas[0], 1 as i32);
7078        assert_eq!(vas[1], 2 as i32);
7079        assert_eq!(vas[2], 3 as i32);
7080        assert_eq!(vas, vas2);
7081        assert_eq!(vas, vas3);
7082    }
7083
7084    #[test]
7085    fn vector_trait_from_into_vec_to_vector() {
7086        let v = Vec::from([1, 2, 3]);
7087        let v_slice = &v[..];
7088        let v_to_owned = Vec::from([1, 2, 3]);
7089        // from / into with Vec
7090        let vv = Vector::<i32, 3>::try_from(&v).unwrap();
7091        let vv2: Vector<i32, 3> = (&v).try_into().unwrap();
7092        let vv3: Vector<i32, 3> = Vector::<i32, 3>::try_from(v_to_owned).unwrap();
7093        assert_eq!(vv.components.len(), 3);
7094        assert_eq!(vv[0], 1 as i32);
7095        assert_eq!(vv[1], 2 as i32);
7096        assert_eq!(vv[2], 3 as i32);
7097        assert_eq!(vv, vv2);
7098        assert_eq!(vv, vv3);
7099        // from / into with Vector slice
7100        let vvs: Vector<i32, 3> = Vector::<i32, 3>::try_from(v_slice).unwrap();
7101        let vvs2: Vector<i32, 3> = Vector::try_from(v.as_slice()).unwrap();
7102        let vvs3: Vector<i32, 3> = v_slice.try_into().unwrap();
7103        assert_eq!(vvs.components.len(), 3);
7104        assert_eq!(vvs[0], 1 as i32);
7105        assert_eq!(vvs[1], 2 as i32);
7106        assert_eq!(vvs[2], 3 as i32);
7107        assert_eq!(vvs, vvs2);
7108        assert_eq!(vvs, vvs3);
7109    }
7110
7111    #[test]
7112    fn vector_trait_from_into_slice_err() {
7113        let v = Vec::from([1, 2, 3]);
7114        let v_slice = &v[..];
7115        let e1 = Vector::<i32, 2>::try_from(v_slice);
7116        let e2 = Vector::<i32, 4>::try_from(v_slice);
7117        assert!(matches!(e1, Err(VectorError::TryFromSliceError(_))));
7118        assert!(matches!(e2, Err(VectorError::TryFromSliceError(_))));
7119    }
7120
7121    // ================================
7122    //
7123    // Operator overloads
7124    //
7125    // ================================
7126
7127    #[test]
7128    fn vector_trait_neg_unary() {
7129        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7130        let v2: Vector<i32, 3> = Vector::from([-1, -2, -3]);
7131        let v3: Vector<f64, 3> = Vector::from([1.0, 2.0, 3.0]);
7132        let v4: Vector<f64, 3> = Vector::from([-1.0, -2.0, -3.0]);
7133        let v5: Vector<Complex<f64>, 2> =
7134            Vector::from([Complex::new(1.0, -2.0), Complex::new(-3.0, 4.0)]);
7135        let v6: Vector<Complex<f64>, 2> =
7136            Vector::from([Complex::new(-1.0, 2.0), Complex::new(3.0, -4.0)]);
7137
7138        assert_eq!(-v1, -v1);
7139        assert_eq!(-v1, v2);
7140        assert_eq!(-v2, v1);
7141        assert_eq!(v1 + -v1, Vector::<i32, 3>::zero());
7142        assert_eq!(-v3, -v3);
7143        assert_eq!(-v3, v4);
7144        assert_eq!(-v4, v3);
7145        assert_eq!(v3 + -v3, Vector::<f64, 3>::zero());
7146        assert_eq!(-v5, -v5);
7147        assert_eq!(-v5, v6);
7148        assert_eq!(-v6, v5);
7149        assert_eq!(v5 + -v5, Vector::<Complex<f64>, 2>::zero());
7150    }
7151
7152    #[test]
7153    fn vector_trait_add() {
7154        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7155        let v2: Vector<i32, 3> = Vector::from([4, 5, 6]);
7156        let v3: Vector<i32, 3> = Vector::from([-2, -3, -4]);
7157        let v_zero: Vector<i32, 3> = Vector::zero();
7158
7159        assert_eq!(v1 + v2, Vector::<i32, 3>::from([5, 7, 9]));
7160        assert_eq!(v2 + v3, Vector::<i32, 3>::from([2, 2, 2]));
7161        assert_eq!(v1 + v2 + v3, Vector::<i32, 3>::from([3, 4, 5]));
7162        assert_eq!(v1 + v_zero, v1);
7163        assert_eq!(v_zero + v1, v1);
7164        assert_eq!(v1 + v2, v2 + v1);
7165        assert_eq!((v1 + v2) + v3, v1 + (v2 + v3));
7166        assert_eq!(v1 + (-v1), v_zero);
7167        assert_eq!((v1 + v2) * 10, (v1 * 10) + (v2 * 10));
7168
7169        let v1: Vector<f64, 3> = Vector::from([1.0, 2.0, 3.0]);
7170        let v2: Vector<f64, 3> = Vector::from([4.0, 5.0, 6.0]);
7171        let v3: Vector<f64, 3> = Vector::from([-2.0, -3.0, -4.0]);
7172        let v_zero: Vector<f64, 3> = Vector::zero();
7173
7174        assert_eq!(v1 + v2, Vector::<f64, 3>::from([5.0, 7.0, 9.0]));
7175        assert_eq!(v2 + v3, Vector::<f64, 3>::from([2.0, 2.0, 2.0]));
7176        assert_eq!(v1 + v2 + v3, Vector::<f64, 3>::from([3.0, 4.0, 5.0]));
7177        assert_eq!(v1 + v_zero, v1);
7178        assert_eq!(v_zero + v1, v1);
7179        assert_eq!(-v_zero + v1, v1);
7180        assert_eq!(v1 + v2, v2 + v1);
7181        assert_eq!((v1 + v2) + v3, v1 + (v2 + v3));
7182        assert_eq!(v1 + (-v1), v_zero);
7183        assert_eq!((v1 + v2) * 10.0, (v1 * 10.0) + (v2 * 10.0));
7184
7185        let v1: Vector<Complex<f64>, 2> =
7186            Vector::from([Complex::new(1.0, -2.0), Complex::new(-3.0, 4.0)]);
7187        let v2: Vector<Complex<f64>, 2> =
7188            Vector::from([Complex::new(5.0, -6.0), Complex::new(-7.0, 8.0)]);
7189        let v3: Vector<Complex<f64>, 2> =
7190            Vector::from([Complex::new(-1.0, 2.0), Complex::new(3.0, -4.0)]);
7191        let v_zero = Vector::<Complex<f64>, 2>::zero();
7192
7193        assert_eq!(
7194            v1 + v2,
7195            Vector::<Complex<f64>, 2>::from([Complex::new(6.0, -8.0), Complex::new(-10.0, 12.0)])
7196        );
7197        assert_eq!(
7198            v2 + v3,
7199            Vector::<Complex<f64>, 2>::from([Complex::new(4.0, -4.0), Complex::new(-4.0, 4.0)])
7200        );
7201        assert_eq!(
7202            v1 + v2 + v3,
7203            Vector::<Complex<f64>, 2>::from([Complex::new(5.0, -6.0), Complex::new(-7.0, 8.0)])
7204        );
7205        assert_eq!(v1 + v_zero, v1);
7206        assert_eq!(v_zero + v1, v1);
7207        assert_eq!(-v_zero + v1, v1);
7208        assert_eq!(v1 + v2, v2 + v1);
7209        assert_eq!((v1 + v2) + v3, v1 + (v2 + v3));
7210        assert_eq!(v1 + (-v1), v_zero);
7211        assert_eq!(
7212            (v1 + v2) * Complex::new(10.0, 0.0),
7213            (v1 * Complex::new(10.0, 0.0)) + (v2 * Complex::new(10.0, 0.0))
7214        );
7215    }
7216
7217    #[test]
7218    fn vector_method_mut_add() {
7219        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7220        let mut v2: Vector<i32, 3> = Vector::from([4, 5, 6]);
7221        let v3: Vector<i32, 3> = Vector::from([-2, -3, -4]);
7222
7223        v1.mut_add(&v2);
7224        v2.mut_add(&v3);
7225
7226        assert_eq!(v1, Vector::<i32, 3>::from([5, 7, 9]));
7227        assert_eq!(v2, Vector::<i32, 3>::from([2, 2, 2]));
7228
7229        // reset
7230        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7231        let v2: Vector<i32, 3> = Vector::from([4, 5, 6]);
7232        let v3: Vector<i32, 3> = Vector::from([-2, -3, -4]);
7233
7234        v1.mut_add(&v2).mut_add(&v3);
7235        assert_eq!(v1, Vector::<i32, 3>::from([3, 4, 5]));
7236
7237        // reset
7238        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7239        let v_zero: Vector<i32, 3> = Vector::zero();
7240
7241        v1.mut_add(&v_zero);
7242
7243        assert_eq!(v1, Vector::<i32, 3>::from([1, 2, 3]));
7244
7245        // reset
7246        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7247        let mut v_zero: Vector<i32, 3> = Vector::zero();
7248
7249        v_zero.mut_add(&v1);
7250
7251        assert_eq!(v_zero, v1);
7252
7253        // reset
7254        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7255        let v2: Vector<i32, 3> = Vector::from([4, 5, 6]);
7256        let v3: Vector<i32, 3> = Vector::from([1, 2, 3]);
7257        let mut v4: Vector<i32, 3> = Vector::from([4, 5, 6]);
7258
7259        v1.mut_add(&v2);
7260        v4.mut_add(&v3);
7261
7262        assert_eq!(v1, v4);
7263
7264        // reset
7265        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7266        let v2: Vector<i32, 3> = Vector::from([4, 5, 6]);
7267        let v3: Vector<i32, 3> = Vector::from([7, 8, 9]);
7268        let v4: Vector<i32, 3> = Vector::from([1, 2, 3]);
7269        let v5: Vector<i32, 3> = Vector::from([4, 5, 6]);
7270        let mut v6: Vector<i32, 3> = Vector::from([7, 8, 9]);
7271
7272        assert_eq!(v1.mut_add(&v2).mut_add(&v3), v6.mut_add(&v5).mut_add(&v4));
7273        assert_eq!(v1, Vector::from([12, 15, 18]));
7274        assert_eq!(v6, Vector::from([12, 15, 18]));
7275
7276        // reset
7277        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7278        v1.mut_add(&v1.neg());
7279        assert_eq!(v1, Vector::<i32, 3>::zero());
7280
7281        // reset
7282        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7283        let v2: Vector<i32, 3> = Vector::from([4, 5, 6]);
7284        let v3: Vector<i32, 3> = Vector::from([1, 2, 3]);
7285        let v4: Vector<i32, 3> = Vector::from([4, 5, 6]);
7286        v1.mut_add(&v2);
7287        assert_eq!(v1 * 10, *(v3 * 10).mut_add(&(v4 * 10)));
7288
7289        // reset
7290        let mut v1: Vector<Complex<i32>, 2> =
7291            Vector::from([Complex::new(1, -2), Complex::new(-3, 4)]);
7292        let v2: Vector<Complex<i32>, 2> = Vector::from([Complex::new(5, -6), Complex::new(-7, 8)]);
7293        v1.mut_add(&v2);
7294        assert_eq!(v1, Vector::from([Complex::new(6, -8), Complex::new(-10, 12)]));
7295    }
7296
7297    #[test]
7298    #[should_panic(expected = "attempt to add with overflow")]
7299    fn vector_trait_add_panics_on_overflow() {
7300        let v1: Vector<u8, 3> = Vector::from([u8::MAX, 2, 3]);
7301        let v2: Vector<u8, 3> = Vector::from([1, 1, 1]);
7302        let _ = v1 + v2;
7303    }
7304
7305    #[test]
7306    #[should_panic(expected = "attempt to add with overflow")]
7307    fn vector_method_mut_add_panics_on_overflow() {
7308        let mut v1: Vector<u8, 3> = Vector::from([u8::MAX, 2, 3]);
7309        let v2: Vector<u8, 3> = Vector::from([1, 1, 1]);
7310        v1.mut_add(&v2);
7311    }
7312
7313    #[test]
7314    fn vector_trait_sub() {
7315        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7316        let v2: Vector<i32, 3> = Vector::from([4, 5, 6]);
7317        let v3: Vector<i32, 3> = Vector::from([-2, -3, -4]);
7318        let v_zero: Vector<i32, 3> = Vector::zero();
7319
7320        assert_eq!(v1 - v2, Vector::<i32, 3>::from([-3, -3, -3]));
7321        assert_eq!(v2 - v1, Vector::<i32, 3>::from([3, 3, 3]));
7322        assert_eq!(v1 - v2 - v3, Vector::<i32, 3>::from([-1, 0, 1]));
7323        assert_eq!((v1 - v2) - v3, v1 - v2 - v3);
7324        assert_eq!(v1 - (v2 - v3), Vector::<i32, 3>::from([-5, -6, -7]));
7325        assert_eq!(v1 - v_zero, v1);
7326        assert_eq!(v1 - (-v_zero), v1);
7327        assert_eq!(v_zero - v1, -v1);
7328        assert_eq!(-v_zero - v1, -v1);
7329
7330        let v1: Vector<f64, 3> = Vector::from([1.0, 2.0, 3.0]);
7331        let v2: Vector<f64, 3> = Vector::from([4.0, 5.0, 6.0]);
7332        let v3: Vector<f64, 3> = Vector::from([-2.0, -3.0, -4.0]);
7333        let v_zero: Vector<f64, 3> = Vector::zero();
7334
7335        assert_eq!(v1 - v2, Vector::<f64, 3>::from([-3.0, -3.0, -3.0]));
7336        assert_eq!(v2 - v1, Vector::<f64, 3>::from([3.0, 3.0, 3.0]));
7337        assert_eq!(v1 - v2 - v3, Vector::<f64, 3>::from([-1.0, 0.0, 1.0]));
7338        assert_eq!((v1 - v2) - v3, v1 - v2 - v3);
7339        assert_eq!(v1 - (v2 - v3), Vector::<f64, 3>::from([-5.0, -6.0, -7.0]));
7340        assert_eq!(v1 - v_zero, v1);
7341        assert_eq!(v1 - (-v_zero), v1);
7342        assert_eq!(v_zero - v1, -v1);
7343        assert_eq!(-v_zero - v1, -v1);
7344
7345        let v1: Vector<Complex<f64>, 2> =
7346            Vector::from([Complex::new(1.0, -2.0), Complex::new(-3.0, 4.0)]);
7347        let v2: Vector<Complex<f64>, 2> =
7348            Vector::from([Complex::new(5.0, -6.0), Complex::new(-7.0, 8.0)]);
7349        let v3: Vector<Complex<f64>, 2> =
7350            Vector::from([Complex::new(-1.0, 2.0), Complex::new(3.0, -4.0)]);
7351        let v_zero = Vector::<Complex<f64>, 2>::zero();
7352
7353        assert_eq!(
7354            v1 - v2,
7355            Vector::<Complex<f64>, 2>::from([Complex::new(-4.0, 4.0), Complex::new(4.0, -4.0)])
7356        );
7357        assert_eq!(
7358            v2 - v3,
7359            Vector::<Complex<f64>, 2>::from([Complex::new(6.0, -8.0), Complex::new(-10.0, 12.0)])
7360        );
7361        assert_eq!(
7362            v1 - v2 - v3,
7363            Vector::<Complex<f64>, 2>::from([Complex::new(-3.0, 2.0), Complex::new(1.0, 0.0)])
7364        );
7365        assert_eq!((v1 - v2) - v3, v1 - v2 - v3);
7366        assert_eq!(
7367            v1 - (v2 - v3),
7368            Vector::<Complex<f64>, 2>::from([Complex::new(-5.0, 6.0), Complex::new(7.0, -8.0)])
7369        );
7370        assert_eq!(v1 - v_zero, v1);
7371        assert_eq!(v1 - (-v_zero), v1);
7372        assert_eq!(v_zero - v1, -v1);
7373        assert_eq!(-v_zero - v1, -v1);
7374    }
7375
7376    #[test]
7377    fn vector_method_mut_sub() {
7378        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7379        let v2: Vector<i32, 3> = Vector::from([4, 5, 6]);
7380
7381        v1.mut_sub(&v2);
7382
7383        assert_eq!(v1, Vector::<i32, 3>::from([-3, -3, -3]));
7384
7385        // reset
7386        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7387        let mut v2: Vector<i32, 3> = Vector::from([4, 5, 6]);
7388
7389        v2.mut_sub(&v1);
7390
7391        assert_eq!(v2, Vector::<i32, 3>::from([3, 3, 3]));
7392
7393        // reset
7394        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7395        let v2: Vector<i32, 3> = Vector::from([4, 5, 6]);
7396        let v3: Vector<i32, 3> = Vector::from([-2, -3, -4]);
7397
7398        v1.mut_sub(&v2).mut_sub(&v3);
7399
7400        assert_eq!(v1, Vector::<i32, 3>::from([-1, 0, 1]));
7401
7402        // reset
7403        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7404        let v_zero: Vector<i32, 3> = Vector::zero();
7405
7406        v1.mut_sub(&v_zero);
7407
7408        assert_eq!(v1, Vector::<i32, 3>::from([1, 2, 3]));
7409
7410        // reset
7411        let mut v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7412        let v_zero: Vector<i32, 3> = Vector::zero();
7413
7414        v1.mut_sub(&v_zero.neg());
7415
7416        assert_eq!(v1, Vector::<i32, 3>::from([1, 2, 3]));
7417
7418        // reset
7419        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7420        let mut v_zero: Vector<i32, 3> = Vector::zero();
7421
7422        v_zero.mut_sub(&v1);
7423
7424        assert_eq!(v_zero, Vector::<i32, 3>::from([-1, -2, -3]));
7425
7426        // reset
7427        let v1: Vector<i32, 3> = Vector::from([1, 2, 3]);
7428        // note unary negation of the vector definition
7429        let mut v_zero: Vector<i32, 3> = -Vector::zero();
7430
7431        v_zero.mut_sub(&v1);
7432
7433        assert_eq!(v_zero, Vector::<i32, 3>::from([-1, -2, -3]));
7434
7435        // reset
7436        let mut v1: Vector<Complex<f64>, 2> =
7437            Vector::from([Complex::new(1.0, -2.0), Complex::new(-3.0, 4.0)]);
7438        let v2: Vector<Complex<f64>, 2> =
7439            Vector::from([Complex::new(-2.0, 3.0), Complex::new(2.0, -3.0)]);
7440
7441        v1.mut_sub(&v2);
7442
7443        assert_eq!(v1, Vector::from([Complex::new(3.0, -5.0), Complex::new(-5.0, 7.0)]));
7444    }
7445
7446    #[test]
7447    #[should_panic(expected = "attempt to subtract with overflow")]
7448    fn vector_trait_sub_panics_on_overflow() {
7449        let v1: Vector<u32, 3> = Vector::from([1, 2, 3]);
7450        let v2: Vector<u32, 3> = Vector::from([4, 5, 6]);
7451        let _ = v1 - v2;
7452    }
7453
7454    #[test]
7455    #[should_panic(expected = "attempt to subtract with overflow")]
7456    fn vector_method_mut_sub_panics_on_overflow() {
7457        let mut v1: Vector<u32, 3> = Vector::from([1, 2, 3]);
7458        let v2: Vector<u32, 3> = Vector::from([4, 5, 6]);
7459        let _ = v1.mut_sub(&v2);
7460    }
7461
7462    #[test]
7463    fn vector_trait_mul() {
7464        let v1: Vector<i32, 3> = Vector::from([1, 1, 1]);
7465        assert_eq!(v1 * 10, Vector::from([10, 10, 10]));
7466        assert_eq!(v1 * -10, Vector::from([-10, -10, -10]));
7467        assert_eq!(v1 * 0, Vector::from([0, 0, 0]));
7468        assert_eq!(v1 * -0, Vector::from([0, 0, 0]));
7469        assert_eq!(v1 * 10 * 5, Vector::from([50, 50, 50]));
7470        assert_eq!(v1 * 10 * -5, Vector::from([-50, -50, -50]));
7471        assert_eq!((v1 * 10) * 5, v1 * (10 * 5));
7472        assert_eq!(v1 * 1, v1);
7473        assert_eq!(v1 * -1, -v1);
7474        assert_eq!(v1 * 10 + v1 * 5, v1 * (10 + 5));
7475
7476        let v1: Vector<f64, 3> = Vector::from([1.0, 1.0, 1.0]);
7477        assert_eq!(v1 * 10.0, Vector::from([10.0, 10.0, 10.0]));
7478        assert_eq!(v1 * -10.0, Vector::from([-10.0, -10.0, -10.0]));
7479        assert_eq!(v1 * 0.0, Vector::from([0.0, 0.0, 0.0]));
7480        assert_eq!(v1 * -0.0, Vector::from([0.0, 0.0, 0.0]));
7481        assert_eq!(v1 * 10.0 * 5.0, Vector::from([50.0, 50.0, 50.0]));
7482        assert_eq!(v1 * 10.0 * -5.0, Vector::from([-50.0, -50.0, -50.0]));
7483        assert_eq!((v1 * 10.0) * 5.0, v1 * (10.0 * 5.0));
7484        assert_eq!(v1 * 1.0, v1);
7485        assert_eq!(v1 * -1.0, -v1);
7486        assert_eq!(v1 * 10.0 + v1 * 5.0, v1 * (10.0 + 5.0));
7487
7488        // complex * scalar integer
7489        let v: Vector<Complex<i32>, 2> = Vector::from([Complex::new(3, 2), Complex::new(-3, -2)]);
7490        assert_eq!(v * 10, Vector::from([Complex::new(30, 20), Complex::new(-30, -20)]));
7491
7492        // complex * scalar float
7493        let v: Vector<Complex<f64>, 2> =
7494            Vector::from([Complex::new(3.0, 2.0), Complex::new(-3.0, -2.0)]);
7495        assert_eq!(v * 10.0, Vector::from([Complex::new(30.0, 20.0), Complex::new(-30.0, -20.0)]));
7496
7497        // complex * complex
7498        let v: Vector<Complex<f64>, 2> =
7499            Vector::from([Complex::new(3.0, 2.0), Complex::new(-3.0, -2.0)]);
7500        let c1: Complex<f64> = Complex::new(1.0, 7.0);
7501        let c2: Complex<f64> = Complex::new(0.0, 7.0);
7502        let c3: Complex<f64> = Complex::new(1.0, 0.0);
7503        assert_eq!(v * c1, Vector::from([Complex::new(-11.0, 23.0), Complex::new(11.0, -23.0)]));
7504        assert_eq!(v * c2, Vector::from([Complex::new(-14.0, 21.0), Complex::new(14.0, -21.0)]));
7505        assert_eq!(v * c3, Vector::from([Complex::new(3.0, 2.0), Complex::new(-3.0, -2.0)]));
7506    }
7507
7508    #[test]
7509    fn vector_method_mut_mul() {
7510        let mut v1: Vector<i32, 3> = Vector::from([1, 1, 1]);
7511        v1.mut_mul(10);
7512        assert_eq!(v1, Vector::from([10, 10, 10]));
7513
7514        // reset
7515        let mut v1: Vector<i32, 3> = Vector::from([1, 1, 1]);
7516        v1.mut_mul(-10);
7517        assert_eq!(v1, Vector::from([-10, -10, -10]));
7518
7519        // reset
7520        let mut v1: Vector<i32, 3> = Vector::from([1, 1, 1]);
7521        v1.mut_mul(0);
7522        assert_eq!(v1, Vector::zero());
7523
7524        // reset
7525        let mut v1: Vector<i32, 3> = Vector::from([1, 1, 1]);
7526        v1.mut_mul(-0);
7527        assert_eq!(v1, Vector::zero());
7528
7529        // reset
7530        let mut v1: Vector<i32, 3> = Vector::from([1, 1, 1]);
7531        v1.mut_mul(10).mut_mul(5);
7532        assert_eq!(v1, Vector::from([50, 50, 50]));
7533
7534        // reset
7535        let mut v1: Vector<i32, 3> = Vector::from([1, 1, 1]);
7536        v1.mut_mul(10).mut_mul(-5);
7537        assert_eq!(v1, Vector::from([-50, -50, -50]));
7538
7539        // reset
7540        let mut v1: Vector<i32, 3> = Vector::from([1, 1, 1]);
7541        let mut v2: Vector<i32, 3> = Vector::from([1, 1, 1]);
7542        v1.mut_mul(10).mut_mul(5);
7543        v2.mut_mul(10 * 5);
7544        assert_eq!(v1, v2);
7545
7546        // reset
7547        let mut v1: Vector<i32, 3> = Vector::from([1, 1, 1]);
7548        let v2: Vector<i32, 3> = Vector::from([1, 1, 1]);
7549
7550        v1.mut_mul(1);
7551
7552        assert_eq!(v1, v2);
7553
7554        v1.mut_mul(-1);
7555
7556        assert_eq!(v1, -v2);
7557
7558        // reset
7559        let mut v1: Vector<Complex<f64>, 2> =
7560            Vector::from([Complex::new(3.0, 2.0), Complex::new(-3.0, -2.0)]);
7561        let c1: Complex<f64> = Complex::new(1.0, 7.0);
7562        v1.mut_mul(c1);
7563        assert_eq!(v1, Vector::from([Complex::new(-11.0, 23.0), Complex::new(11.0, -23.0)]));
7564        // num::Complex supports Copy and we can use it again
7565        v1.mut_mul(c1);
7566    }
7567
7568    #[test]
7569    #[should_panic(expected = "attempt to multiply with overflow")]
7570    fn vector_trait_mul_overflow_panic() {
7571        let v1: Vector<u8, 2> = Vector::from([2, 2]);
7572        let _ = v1 * u8::MAX;
7573    }
7574
7575    #[test]
7576    #[should_panic(expected = "attempt to multiply with overflow")]
7577    fn vector_method_mut_mul_overflow_panic() {
7578        let mut v1: Vector<u8, 2> = Vector::from([2, 2]);
7579        let _ = v1.mut_mul(u8::MAX);
7580    }
7581
7582    #[test]
7583    fn vector_multi_overloaded_operator_precedence() {
7584        let v1: Vector<i32, 3> = Vector::from([1, 1, 1]);
7585        let v2: Vector<i32, 3> = Vector::from([-2, -2, -2]);
7586        let v_zero: Vector<i32, 3> = Vector::zero();
7587        assert_eq!(v1 + -v2 * 10, Vector::<i32, 3>::from([21, 21, 21]));
7588        assert_eq!((v1 + -v2) * 10, Vector::<i32, 3>::from([30, 30, 30]));
7589        assert_eq!(v1 - -v2 * 10, Vector::<i32, 3>::from([-19, -19, -19]));
7590        assert_eq!((v1 - -v2) * 10, Vector::<i32, 3>::from([-10, -10, -10]));
7591        assert_eq!(v1 + v2 * 0, v1);
7592        assert_eq!((v1 + v2) * 0, v_zero);
7593
7594        let v1: Vector<f64, 3> = Vector::from([1.0, 1.0, 1.0]);
7595        let v2: Vector<f64, 3> = Vector::from([-2.0, -2.0, -2.0]);
7596        let v_zero: Vector<f64, 3> = Vector::zero();
7597        assert_eq!(v1 + -v2 * 10.0, Vector::<f64, 3>::from([21.0, 21.0, 21.0]));
7598        assert_eq!((v1 + -v2) * 10.0, Vector::<f64, 3>::from([30.0, 30.0, 30.0]));
7599        assert_eq!(v1 - -v2 * 10.0, Vector::<f64, 3>::from([-19.0, -19.0, -19.0]));
7600        assert_eq!((v1 - -v2) * 10.0, Vector::<f64, 3>::from([-10.0, -10.0, -10.0]));
7601        assert_eq!(v1 + v2 * 0.0, v1);
7602        assert_eq!((v1 + v2) * 0.0, v_zero);
7603    }
7604}