array_matrix/matrix/
qr_householder.rs1use num_complex::Complex;
2use num_traits::{Float, Zero, One};
3
4use crate::{Matrix, SquareMatrix, matrix_init, MMul, Transpose};
5
6pub trait QRHouseholder: Matrix
7{
8 type OutputQ;
9 type OutputR;
10
11 fn qr_householder(&self) -> (Self::OutputQ, Self::OutputR);
25}
26
27impl<F: Float, const L: usize, const H: usize> QRHouseholder for [[Complex<F>; L]; H]
28where
29 Self: Matrix,
30 [[Complex<F>; H]; H]: SquareMatrix
31{
32 type OutputQ = [[Complex<F>; H]; H];
33 type OutputR = [[Complex<F>; L]; H];
34
35 fn qr_householder(&self) -> (Self::OutputQ, Self::OutputR)
36 {
37 assert!(H >= L);
38 let mut a: Vec<Vec<Complex<F>>> = (0..H)
39 .map(|r| (0..L)
40 .map(|c| self[r][c])
41 .collect()
42 ).collect();
43 let mut q: [[Complex<F>; H]; H] = SquareMatrix::identity();
44 for t in 0..L.min(H - 1)
45 {
46 let x: Vec<Complex<F>> = (0..H - t)
47 .map(|r| a[r][0])
48 .collect();
49 let x_abs = x.iter()
50 .map(|xn| xn.norm_sqr())
51 .reduce(|a, b| a + b)
52 .unwrap_or(F::zero())
53 .sqrt();
54 let alpha = -Complex::cis(x[t].arg())*x_abs;
55 let mut u = x;
56 u[0] = u[0] - alpha;
57 let u_abs = u.iter()
58 .map(|un| un.norm_sqr())
59 .reduce(|a, b| a + b)
60 .unwrap_or(F::zero())
61 .sqrt();
62 let v: Vec<Complex<F>> = u.iter()
63 .map(|un| un/u_abs)
64 .collect();
65 let q_: Vec<Vec<Complex<F>>> = (0..H - t)
66 .map(|r| (0..H - t)
67 .map(|c| if r == c {Complex::<F>::one()} else {Complex::zero()} - v[r]*v[c].conj()*F::from(2.0).unwrap())
68 .collect()
69 ).collect();
70 let qt: [[Complex<F>; H]; H] = matrix_init(|r, c| if r >= t && c >= t
71 {
72 q_[c - t][r - t]
73 }
74 else
75 {
76 if r == c {Complex::one()} else {Complex::zero()}
77 }
78 );
79 q = q.mul(qt);
80 a = (1..H - t)
81 .map(|r| (1..L - t)
82 .map(|c| (0..H - t)
83 .map(|i| q_[r][i]*a[i][c])
84 .reduce(|a, b| a + b)
85 .unwrap_or(Complex::zero())
86 ).collect()
87 ).collect()
88 }
89 let r = q.transpose().mul(self.clone());
90 return (q, r)
91 }
92}
93
94impl<const L: usize, const H: usize> QRHouseholder for [[f32; L]; H]
95where
96 Self: Matrix,
97 [[Complex<f32>; L]; H]: QRHouseholder
98{
99 type OutputQ = <[[Complex<f32>; L]; H] as QRHouseholder>::OutputQ;
100 type OutputR = <[[Complex<f32>; L]; H] as QRHouseholder>::OutputR;
101 fn qr_householder(&self) -> (Self::OutputQ, Self::OutputR)
102 {
103 self.map(|ar| ar.map(|arc| Complex::from(arc))).qr_householder()
104 }
105}
106
107impl<const L: usize, const H: usize> QRHouseholder for [[f64; L]; H]
108where
109 Self: Matrix,
110 [[Complex<f64>; L]; H]: QRHouseholder
111{
112 type OutputQ = <[[Complex<f64>; L]; H] as QRHouseholder>::OutputQ;
113 type OutputR = <[[Complex<f64>; L]; H] as QRHouseholder>::OutputR;
114 fn qr_householder(&self) -> (Self::OutputQ, Self::OutputR)
115 {
116 self.map(|ar| ar.map(|arc| Complex::from(arc))).qr_householder()
117 }
118}