use crate::{
assert,
linalg::{
matmul::triangular::{self, BlockStructure},
temp_mat_req, temp_mat_uninit,
zip::Diag,
},
unzipped, zipped_rw, ComplexField, Entity, MatMut, MatRef, Parallelism,
};
use dyn_stack::{PodStack, SizeOverflow, StackReq};
use reborrow::*;
pub fn reconstruct_lower_req<E: Entity>(dimension: usize) -> Result<StackReq, SizeOverflow> {
let _ = dimension;
Ok(StackReq::default())
}
pub fn reconstruct_lower_in_place_req<E: Entity>(
dimension: usize,
) -> Result<StackReq, SizeOverflow> {
temp_mat_req::<E>(dimension, dimension)
}
#[track_caller]
pub fn reconstruct_lower<E: ComplexField>(
dst: MatMut<'_, E>,
cholesky_factor: MatRef<'_, E>,
parallelism: Parallelism,
stack: &mut PodStack,
) {
assert!(cholesky_factor.nrows() == cholesky_factor.ncols());
assert!((dst.nrows(), dst.ncols()) == (cholesky_factor.nrows(), cholesky_factor.ncols()));
let _ = &stack;
triangular::matmul(
dst,
BlockStructure::TriangularLower,
cholesky_factor,
BlockStructure::TriangularLower,
cholesky_factor.adjoint(),
BlockStructure::TriangularUpper,
None,
E::faer_one(),
parallelism,
);
}
#[track_caller]
pub fn reconstruct_lower_in_place<E: ComplexField>(
cholesky_factor: MatMut<'_, E>,
parallelism: Parallelism,
stack: &mut PodStack,
) {
let n = cholesky_factor.nrows();
let (mut tmp, stack) = temp_mat_uninit::<E>(n, n, stack);
let mut tmp = tmp.as_mut();
reconstruct_lower(tmp.rb_mut(), cholesky_factor.rb(), parallelism, stack);
zipped_rw!(cholesky_factor, tmp.rb())
.for_each_triangular_lower(Diag::Include, |unzipped!(mut dst, src)| {
dst.write(src.read())
});
}