use dyn_stack::MemStack;
use faer::sparse::linalg::triangular_solve;
use faer::{Conj, MatMut, Par};
use faer_traits::math_utils::zero;
use faer_traits::{ComplexField, Index};
use super::numeric::Ilutp;
pub(crate) fn solve_in_place<I, T>(
pc: &Ilutp<I, T>,
conj: Conj,
rhs: MatMut<'_, T>,
par: Par,
stack: &mut MemStack,
) where
I: Index,
T: ComplexField,
{
let l = pc.l_view();
let u = pc.u_view();
let mut rhs = rhs;
triangular_solve::solve_unit_lower_triangular_in_place(l, conj, rhs.as_mut(), par);
triangular_solve::solve_upper_triangular_in_place(u, conj, rhs.as_mut(), par);
if pc.permuted {
permute_rows(rhs.as_mut(), &pc.perm_inv, stack);
}
}
pub(crate) fn solve_transpose_in_place<I, T>(
pc: &Ilutp<I, T>,
conj: Conj,
rhs: MatMut<'_, T>,
par: Par,
stack: &mut MemStack,
) where
I: Index,
T: ComplexField,
{
let mut rhs = rhs;
if pc.permuted {
permute_rows(rhs.as_mut(), &pc.perm, stack);
}
let l = pc.l_view();
let u = pc.u_view();
triangular_solve::solve_upper_triangular_transpose_in_place(u, conj, rhs.as_mut(), par);
triangular_solve::solve_unit_lower_triangular_transpose_in_place(l, conj, rhs.as_mut(), par);
}
fn permute_rows<T>(rhs: MatMut<'_, T>, map: &[usize], stack: &mut MemStack)
where
T: ComplexField,
{
let mut rhs = rhs;
let n = rhs.nrows();
let ncols = rhs.ncols();
let (mut tmp, _) = stack.make_with::<T>(n, |_| zero::<T>());
for j in 0..ncols {
for r in 0..n {
tmp[r] = rhs.as_ref().get(map[r], j).clone();
}
for r in 0..n {
*rhs.as_mut().get_mut(r, j) = tmp[r].clone();
}
}
}