numerical_linear_algebra/
vector.rs

1use num_complex::{Complex64, ComplexFloat};
2use rayon::iter::{ParallelBridge, ParallelIterator};
3
4use crate::Matrix;
5
6pub type Vector<const N: usize> = Matrix<N, 1>;
7
8impl<const N: usize> Vector<N> {
9    pub fn dot(&self, rhs: &Vector<N>) -> Complex64 {
10        self.iter()
11            .zip(rhs.iter())
12            .par_bridge()
13            .map(|(a, b)| a * b)
14            .sum()
15    }
16
17    pub fn norm(&self, p: u32) -> f64 {
18        self.iter()
19            .par_bridge()
20            .map(|x_i| x_i.abs().powi(p as i32))
21            .sum::<f64>()
22            .powf(1. / p as f64)
23    }
24
25    pub fn normalize(self) -> Self {
26        let length = Complex64::new(self.norm(2), 0.);
27        1. / length * self
28    }
29
30    pub fn project(self, rhs: Self) -> Self {
31        self.dot(&rhs) / rhs.dot(&rhs) * rhs
32    }
33
34    pub fn gram_schimidt_process<const M: usize>(vectors: [Vector<N>; M]) -> [Vector<N>; M] {
35        let mut basis_vectors = vectors.into_iter().enumerate().fold(
36            [Vector::<N>::ZEROS; M],
37            |mut basis_vectors, (i, vector)| {
38                basis_vectors[i] = vector.clone()
39                    - basis_vectors
40                        .iter()
41                        .take(i)
42                        .map(|basis_vector| vector.clone().project(basis_vector.clone()))
43                        .sum();
44
45                basis_vectors
46            },
47        );
48
49        basis_vectors
50            .iter_mut()
51            .par_bridge()
52            .for_each(|vector| *vector = vector.clone().normalize());
53
54        basis_vectors
55    }
56}