use crate::{
algebra::{
abstr::{Field, Scalar},
linear::{
matrix::{General, HessenbergDec, HessenbergDecomposition, Transpose, UpperHessenberg},
vector::Vector,
},
},
elementary::Power,
};
impl<T> HessenbergDecomposition<T> for General<T>
where
T: Field + Scalar + Power,
{
fn dec_hessenberg(&self) -> HessenbergDec<T> {
let (m, n): (usize, usize) = self.dim();
debug_assert_eq!(
m, n,
"Unable to compute the hessenberg decomposition of a non-square matrix"
);
debug_assert_ne!(
m, 0,
"Unable to compute the hessenberg decomposition of an empty matrix."
);
let (m, _n): (usize, usize) = self.dim();
let mut q: General<T> = General::one(m);
let mut h: General<T> = self.clone();
for k in 1..m - 1 {
let v: Vector<T> = h.get_column(k - 1);
let househ: General<T> = General::householder(&v, k);
h = &househ.clone().transpose() * &h;
q = &househ * &q;
h = &h.clone() * &househ;
}
HessenbergDec::new(q, UpperHessenberg::new(h))
}
}