ferrix/
vector.rs

1use num_traits::{Float, One, PrimInt, Zero};
2use rand::distributions::uniform::SampleUniform;
3use rand::distributions::{Distribution, Standard, Uniform};
4use rand::Rng;
5use std::default::Default;
6use std::fmt;
7use std::ops::{Index, IndexMut};
8
9use crate::matrix::Matrix;
10use crate::matrix_transpose_view::MatrixTransposeView;
11use crate::matrix_transpose_view_mut::MatrixTransposeViewMut;
12use crate::matrix_view::MatrixView;
13use crate::matrix_view_mut::MatrixViewMut;
14use crate::row_vector_view::RowVectorView;
15use crate::row_vector_view_mut::RowVectorViewMut;
16use crate::traits::{DotProduct, FloatRandom, IntRandom};
17use crate::vector_view::VectorView;
18use crate::vector_view_mut::VectorViewMut;
19
20/// A static column vector type.
21#[derive(Debug, Clone)]
22pub struct Vector<T, const N: usize> {
23    data: [T; N],
24}
25
26/// A static 2D vector alias for [`Vector<T, 2>`].
27pub type Vector2<T> = Vector<T, 2>;
28
29/// A static 3D vector alias for [`Vector<T, 3>`].
30pub type Vector3<T> = Vector<T, 3>;
31
32impl<T: Default, const N: usize> Default for Vector<T, N> {
33    /// Creates a new [`Vector`] with default values.
34    ///
35    /// This method initializes a new [`Vector`] of size N, where each element is set to its default value.
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use ferrix::Vector;
41    ///
42    /// let vec: Vector<f64, 3> = Vector::new();
43    /// assert_eq!(vec, Vector::from([0.0, 0.0, 0.0]));
44    /// ```
45    fn default() -> Self {
46        Self {
47            data: std::array::from_fn(|_| T::default()),
48        }
49    }
50}
51
52impl<T: Default, const N: usize> Vector<T, N> {
53    /// Creates a new [`Vector`] with default values.
54    ///
55    /// This method initializes a new [`Vector`] of size N, where each element is set to its default value.
56    ///
57    /// # Examples
58    ///
59    /// ```
60    /// use ferrix::Vector;
61    ///
62    /// let vec: Vector<f64, 3> = Vector::new();
63    /// assert_eq!(vec, Vector::from([0.0, 0.0, 0.0]));
64    /// ```
65    pub fn new() -> Self {
66        Self::default()
67    }
68}
69
70impl<T, const N: usize> Vector<T, N> {
71    /// Returns the shape (number of elements) of the [`Vector`].
72    ///
73    /// The shape is always equal to `N`.
74    ///
75    /// # Examples
76    ///
77    /// ```
78    /// use ferrix::Vector;
79    ///
80    /// let vec: Vector<f64, 5> = Vector::new();
81    /// assert_eq!(vec.shape(), 5);
82    /// ```
83    #[inline]
84    pub fn shape(&self) -> usize {
85        N
86    }
87
88    /// Returns the total number of elements in the [`Vector`].
89    ///
90    /// The total number of elements is always equal to `N`.
91    ///
92    /// # Examples
93    ///
94    /// ```
95    /// use ferrix::Vector;
96    ///
97    /// let vec: Vector<f64, 5> = Vector::new();
98    /// assert_eq!(vec.capacity(), 5);
99    /// ```
100    #[inline]
101    pub fn capacity(&self) -> usize {
102        N
103    }
104
105    /// Returns the number of rows in the [`Vector`].
106    ///
107    /// The number of rows is always equal to `N`.
108    ///
109    /// # Examples
110    ///
111    /// ```
112    /// use ferrix::Vector;
113    ///
114    /// let vec: Vector<f64, 5> = Vector::new();
115    /// assert_eq!(vec.rows(), 5);
116    /// ```
117    #[inline]
118    pub fn rows(&self) -> usize {
119        N
120    }
121
122    /// Returns the number of columns in the [`Vector`].
123    ///
124    /// The number of columns is always `1`.
125    ///
126    /// # Examples
127    ///
128    /// ```
129    /// use ferrix::Vector;
130    ///
131    /// let vec: Vector<f64, 5> = Vector::new();
132    /// assert_eq!(vec.cols(), 1);
133    /// ```
134    #[inline]
135    pub fn cols(&self) -> usize {
136        1
137    }
138}
139
140impl<T: PrimInt, const N: usize> IntRandom for Vector<T, N>
141where
142    Standard: Distribution<T>,
143{
144    fn random() -> Self {
145        let mut rng = rand::thread_rng();
146        Self {
147            data: std::array::from_fn(|_| rng.gen()),
148        }
149    }
150}
151
152impl<T: Float + SampleUniform, const N: usize> FloatRandom for Vector<T, N>
153where
154    Standard: Distribution<T>,
155{
156    fn random() -> Self {
157        let mut rng = rand::thread_rng();
158        let dist = Uniform::new_inclusive(-T::one(), T::one());
159        Self {
160            data: std::array::from_fn(|_| dist.sample(&mut rng)),
161        }
162    }
163}
164
165impl<T: Copy> Vector<T, 1> {
166    /// Converts a 1-dimensional [`Vector`] into its scalar value.
167    ///
168    /// # Examples
169    ///
170    /// ```
171    /// use ferrix::Vector;
172    ///
173    /// let vec = Vector::from([42]);
174    /// assert_eq!(vec.into(), 42);
175    /// ```
176    pub fn into(self) -> T {
177        self[0]
178    }
179}
180
181impl<T: Copy, const N: usize> Vector<T, N> {
182    /// Creates a new [`Vector`] filled with a specified value.
183    ///
184    /// This method initializes a new [`Vector`] of size N, where each element is set to the provided value.
185    ///
186    /// # Examples
187    ///
188    /// ```
189    /// use ferrix::Vector;
190    ///
191    /// let vec = Vector::<i32, 3>::fill(42);
192    /// assert_eq!(vec, Vector::from([42, 42, 42]));
193    /// ```
194    pub fn fill(value: T) -> Self {
195        Self {
196            data: std::array::from_fn(|_| value),
197        }
198    }
199}
200
201impl<T: Copy + Zero, const N: usize> Vector<T, N> {
202    /// Creates a new [`Vector`] filled with zeros.
203    ///
204    /// This method initializes a new [`Vector`] of size N, where each element is set to zero.
205    ///
206    /// # Examples
207    ///
208    /// ```
209    /// use ferrix::Vector;
210    ///
211    /// let vec = Vector::<f64, 3>::zeros();
212    /// assert_eq!(vec, Vector::from([0.0, 0.0, 0.0]));
213    /// ```
214    pub fn zeros() -> Self {
215        Self::fill(T::zero())
216    }
217}
218
219impl<T: Copy + One, const N: usize> Vector<T, N> {
220    /// Creates a new Vector filled with ones.
221    ///
222    /// This method initializes a new [`Vector`] of size N, where each element is set to one.
223    ///
224    /// # Examples
225    ///
226    /// ```
227    /// use ferrix::Vector;
228    ///
229    /// let vec = Vector::<f64, 3>::ones();
230    /// assert_eq!(vec, Vector::from([1.0, 1.0, 1.0]));
231    /// ```
232    pub fn ones() -> Self {
233        Self::fill(T::one())
234    }
235}
236
237impl<T: Copy + Zero, const N: usize> Vector<T, N> {
238    /// Creates a diagonal matrix from the [`Vector`].
239    ///
240    /// This method returns a new NxN [`Matrix`] where the diagonal elements are set to the values of the [`Vector`],
241    /// and all other elements are zero.
242    ///
243    /// # Examples
244    ///
245    /// ```
246    /// use ferrix::{Vector, Matrix};
247    ///
248    /// let vec = Vector::from([1, 2, 3]);
249    /// let mat = vec.diag();
250    /// assert_eq!(mat, Matrix::from([[1, 0, 0], [0, 2, 0], [0, 0, 3]]));
251    /// ```
252    pub fn diag(&self) -> Matrix<T, N, N> {
253        let mut m = Matrix::<T, N, N>::zeros();
254        for i in 0..N {
255            m[(i, i)] = self[i];
256        }
257        m
258    }
259}
260
261impl<T, const N: usize> Vector<T, N> {
262    /// Returns a transposed view of the [`Vector`].
263    ///
264    /// This method returns a [`RowVectorView`], which is a read-only view of the [`Vector`] as a row vector.
265    ///
266    /// # Examples
267    ///
268    /// ```
269    /// use ferrix::{Vector, RowVector};
270    ///
271    /// let vec = Vector::from([1, 2, 3]);
272    /// let row_view = vec.t();
273    /// assert_eq!(row_view, RowVector::from([1, 2, 3]));
274    /// ```
275    pub fn t(&self) -> RowVectorView<'_, Vector<T, N>, T, N, N> {
276        RowVectorView::new(self, 0)
277    }
278
279    /// Returns a mutable transposed view of the [`Vector`].
280    ///
281    /// This method returns a [`RowVectorViewMut`], which is a mutable view of the [`Vector`] as a row vector.
282    ///
283    /// # Examples
284    ///
285    /// ```
286    /// use ferrix::Vector;
287    ///
288    /// let mut vec = Vector::from([1, 2, 3]);
289    /// let mut row_view = vec.t_mut();
290    /// row_view[1] = 5;
291    /// assert_eq!(vec, Vector::from([1, 5, 3]));
292    /// ```
293    pub fn t_mut(&mut self) -> RowVectorViewMut<'_, Vector<T, N>, T, N, N> {
294        RowVectorViewMut::new(self, 0)
295    }
296}
297
298impl<T, const N: usize> Vector<T, N> {
299    /// Returns a view of [`Vector`].
300    ///
301    /// This method returns a [`VectorView`] of size `M`` starting from the given index.
302    /// Returns `None` if the requested view is out of bounds or if `M`` is zero.
303    ///
304    /// # Examples
305    ///
306    /// ```
307    /// use ferrix::Vector;
308    ///
309    /// let vec = Vector::from([1, 2, 3, 4, 5]);
310    /// let view = vec.view::<3>(1).unwrap();
311    /// assert_eq!(view, Vector::from([2, 3, 4]));
312    /// ```
313    pub fn view<const M: usize>(
314        &self,
315        start: usize,
316    ) -> Option<VectorView<'_, Vector<T, N>, T, N, M>> {
317        if start + M > N || M == 0 {
318            return None;
319        }
320        Some(VectorView::new(self, start))
321    }
322
323    /// Returns a mutable view of [`Vector`].
324    ///
325    /// This method returns a [`VectorViewMut`] of size `M` starting from the given index.
326    /// Returns `None` if the requested view is out of bounds or if `M` is zero.
327    ///
328    /// # Examples
329    ///
330    /// ```
331    /// use ferrix::Vector;
332    ///
333    /// let mut vec = Vector::from([1, 2, 3, 4, 5]);
334    /// let mut view = vec.view_mut::<3>(1).unwrap();
335    /// view[1] = 10;
336    /// assert_eq!(vec, Vector::from([1, 2, 10, 4, 5]));
337    /// ```
338    pub fn view_mut<const M: usize>(
339        &mut self,
340        start: usize,
341    ) -> Option<VectorViewMut<'_, Vector<T, N>, T, N, M>> {
342        if start + M > N || M == 0 {
343            return None;
344        }
345        Some(VectorViewMut::new(self, start))
346    }
347}
348
349impl<T: Float, const N: usize> Vector<T, N> {
350    /// Calculates the magnitude (Euclidean norm) of the [`Vector`].
351    ///
352    /// # Examples
353    ///
354    /// ```
355    /// use ferrix::Vector;
356    ///
357    /// let vec = Vector::from([3.0, 4.0]);
358    /// assert_eq!(vec.magnitude(), 5.0);
359    /// ```
360    pub fn magnitude(&self) -> T {
361        self.dot(self).sqrt()
362    }
363}
364
365////////////////////////////////
366//  Equality Implementations  //
367////////////////////////////////
368
369// Vector == Vector
370impl<T: PartialEq, const N: usize> PartialEq for Vector<T, N> {
371    fn eq(&self, other: &Self) -> bool {
372        self.data == other.data
373    }
374}
375
376// Vector == VectorView
377impl<T: PartialEq, const N: usize, V: Index<usize, Output = T>, const A: usize>
378    PartialEq<VectorView<'_, V, T, A, N>> for Vector<T, N>
379{
380    fn eq(&self, other: &VectorView<'_, V, T, A, N>) -> bool {
381        (0..N).all(|i| self[i] == other[i])
382    }
383}
384
385// Vector == VectorViewMut
386impl<T: PartialEq, const N: usize, V: Index<usize, Output = T>, const A: usize>
387    PartialEq<VectorViewMut<'_, V, T, A, N>> for Vector<T, N>
388{
389    fn eq(&self, other: &VectorViewMut<'_, V, T, A, N>) -> bool {
390        (0..N).all(|i| self[i] == other[i])
391    }
392}
393
394impl<T: Eq, const N: usize> Eq for Vector<T, N> {}
395
396/////////////////////////////////////
397//  Display Trait Implementations  //
398/////////////////////////////////////
399
400impl<T: fmt::Display, const N: usize> fmt::Display for Vector<T, N> {
401    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
402        if f.alternate() {
403            write!(f, "Vector(")?;
404        }
405
406        write!(f, "[")?;
407        for i in 0..N - 1 {
408            if i > 0 {
409                write!(f, " ")?;
410                if f.alternate() {
411                    write!(f, "       ")?;
412                }
413            }
414            writeln!(f, "{}", self[i])?;
415        }
416        if f.alternate() {
417            write!(f, "       ")?;
418        }
419
420        write!(f, " {}]", self[N - 1])?;
421
422        if f.alternate() {
423            write!(f, ", dtype={})", std::any::type_name::<T>())?;
424        }
425
426        Ok(())
427    }
428}
429
430///////////////////////////////////
431//  Index Trait Implementations  //
432///////////////////////////////////
433
434impl<T, const N: usize> Index<usize> for Vector<T, N> {
435    type Output = T;
436
437    fn index(&self, index: usize) -> &Self::Output {
438        &self.data[index]
439    }
440}
441
442impl<T, const N: usize> IndexMut<usize> for Vector<T, N> {
443    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
444        &mut self.data[index]
445    }
446}
447
448impl<T, const N: usize> Index<(usize, usize)> for Vector<T, N> {
449    type Output = T;
450
451    fn index(&self, index: (usize, usize)) -> &Self::Output {
452        &self.data[index.0]
453    }
454}
455
456impl<T, const N: usize> IndexMut<(usize, usize)> for Vector<T, N> {
457    fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
458        &mut self.data[index.0]
459    }
460}
461
462//////////////////////////////////
463//  From Trait Implementations  //
464//////////////////////////////////
465
466impl<T, const N: usize> From<[T; N]> for Vector<T, N> {
467    fn from(data: [T; N]) -> Self {
468        Self { data }
469    }
470}
471
472impl<T: Copy, const N: usize> From<[[T; 1]; N]> for Vector<T, N> {
473    fn from(data: [[T; 1]; N]) -> Self {
474        Self {
475            data: std::array::from_fn(|i| data[i][0]),
476        }
477    }
478}
479
480impl<V: Index<usize, Output = T>, T: Copy, const A: usize, const N: usize>
481    From<VectorView<'_, V, T, A, N>> for Vector<T, N>
482{
483    fn from(vector: VectorView<'_, V, T, A, N>) -> Self {
484        Self {
485            data: std::array::from_fn(|i| vector[i]),
486        }
487    }
488}
489
490impl<V: IndexMut<usize, Output = T>, T: Copy, const A: usize, const N: usize>
491    From<VectorViewMut<'_, V, T, A, N>> for Vector<T, N>
492{
493    fn from(vector: VectorViewMut<'_, V, T, A, N>) -> Self {
494        Self {
495            data: std::array::from_fn(|i| vector[i]),
496        }
497    }
498}
499
500impl<T: Copy, const N: usize> From<Matrix<T, N, 1>> for Vector<T, N> {
501    fn from(matrix: Matrix<T, N, 1>) -> Self {
502        Self {
503            data: std::array::from_fn(|i| matrix[(i, 0)]),
504        }
505    }
506}
507
508impl<T: Copy, const A: usize, const B: usize, const N: usize> From<MatrixView<'_, T, A, B, N, 1>>
509    for Vector<T, N>
510{
511    fn from(matrix: MatrixView<'_, T, A, B, N, 1>) -> Self {
512        Self {
513            data: std::array::from_fn(|i| matrix[(i, 0)]),
514        }
515    }
516}
517
518impl<T: Copy, const A: usize, const B: usize, const N: usize> From<MatrixViewMut<'_, T, A, B, N, 1>>
519    for Vector<T, N>
520{
521    fn from(matrix: MatrixViewMut<'_, T, A, B, N, 1>) -> Self {
522        Self {
523            data: std::array::from_fn(|i| matrix[(i, 0)]),
524        }
525    }
526}
527
528impl<T: Copy, const A: usize, const B: usize, const N: usize>
529    From<MatrixTransposeView<'_, T, A, B, N, 1>> for Vector<T, N>
530{
531    fn from(matrix: MatrixTransposeView<'_, T, A, B, N, 1>) -> Self {
532        Self {
533            data: std::array::from_fn(|i| matrix[(i, 0)]),
534        }
535    }
536}
537
538impl<T: Copy, const A: usize, const B: usize, const N: usize>
539    From<MatrixTransposeViewMut<'_, T, A, B, N, 1>> for Vector<T, N>
540{
541    fn from(matrix: MatrixTransposeViewMut<'_, T, A, B, N, 1>) -> Self {
542        Self {
543            data: std::array::from_fn(|i| matrix[(i, 0)]),
544        }
545    }
546}