numerical_linear_algebra/
vector.rs1use 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}