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}