use assert2::assert as fancy_assert;
use dyn_stack::{DynStack, SizeOverflow, StackReq};
use faer_core::{
mul::triangular::{self, BlockStructure},
temp_mat_req, temp_mat_uninit, ComplexField, Conj, MatMut, MatRef, Parallelism,
};
use reborrow::*;
pub fn reconstruct_lower_req<T: 'static>(dimension: usize) -> Result<StackReq, SizeOverflow> {
let _ = dimension;
Ok(StackReq::default())
}
pub fn reconstruct_lower_in_place_req<T: 'static>(
dimension: usize,
) -> Result<StackReq, SizeOverflow> {
temp_mat_req::<T>(dimension, dimension)
}
#[track_caller]
pub fn reconstruct_lower<T: ComplexField>(
dst: MatMut<'_, T>,
cholesky_factor: MatRef<'_, T>,
parallelism: Parallelism,
stack: DynStack<'_>,
) {
fancy_assert!(cholesky_factor.nrows() == cholesky_factor.ncols());
fancy_assert!((dst.nrows(), dst.ncols()) == (cholesky_factor.nrows(), cholesky_factor.ncols()));
let _ = &stack;
triangular::matmul(
dst,
BlockStructure::TriangularLower,
Conj::No,
cholesky_factor,
BlockStructure::TriangularLower,
Conj::No,
cholesky_factor.transpose(),
BlockStructure::TriangularUpper,
Conj::Yes,
None,
T::one(),
parallelism,
);
}
#[track_caller]
pub fn reconstruct_lower_in_place<T: ComplexField>(
cholesky_factor: MatMut<'_, T>,
parallelism: Parallelism,
stack: DynStack<'_>,
) {
let n = cholesky_factor.nrows();
temp_mat_uninit! {
let (mut tmp, stack) = unsafe { temp_mat_uninit::<T>(n, n, stack) };
}
reconstruct_lower(tmp.rb_mut(), cholesky_factor.rb(), parallelism, stack);
cholesky_factor
.cwise()
.zip(tmp.rb())
.for_each_triangular_lower(faer_core::zip::Diag::Include, |dst, src| *dst = *src);
}