use crate::internal::OFF;
use crate::scalar::Scalar;
pub fn ludfs<S: Scalar>(
jcol: usize,
a: &[S],
arow: &[usize],
acolst: &[usize],
lastlu: &mut usize,
lurow: &mut [isize],
lcolst: &mut [usize],
ucolst: &[usize],
rperm: &[usize],
cperm: &[usize],
dense: &mut [S],
found: &mut [usize],
parent: &mut [usize],
child: &mut [usize],
) -> Result<(), String> {
let nzast = acolst[cperm[jcol - OFF] - OFF];
let nzaend = acolst[cperm[jcol - OFF]];
if nzaend < nzast {
return Err(format!(
"ludfs, negative length for column {} of A. nzast={} nzend={}",
jcol, nzast, nzaend
));
}
let nzaend = nzaend - 1;
for nzaptr in nzast - 1..nzaend {
let mut krow: isize = arow[nzaptr] as isize - 1;
dense[krow as usize] = a[nzaptr];
if rperm[krow as usize] == 0
|| found[krow as usize] == jcol
|| dense[krow as usize] == S::zero()
{
continue;
}
parent[krow as usize] = 0;
found[krow as usize] = jcol;
let mut chdptr = lcolst[rperm[krow as usize] - OFF];
'l100: loop {
let chdend = ucolst[rperm[krow as usize]];
'l200: loop {
if chdptr < chdend {
let nextk: isize = lurow[chdptr - OFF] - 1;
chdptr = chdptr + 1;
if rperm[nextk as usize] == 0 {
continue 'l200;
}
if found[nextk as usize] == jcol {
continue 'l200;
}
child[krow as usize] = chdptr;
parent[nextk as usize] = krow as usize + 1;
krow = nextk;
found[krow as usize] = jcol;
chdptr = lcolst[rperm[krow as usize] - OFF];
continue 'l100;
}
break;
}
*lastlu = *lastlu + 1;
lurow[*lastlu - OFF] = krow + 1;
krow = parent[krow as usize] as isize - 1;
if krow >= 0 {
chdptr = child[krow as usize];
continue 'l100;
}
break;
}
}
lcolst[jcol - OFF] = *lastlu + 1;
for nzaptr in nzast - 1..nzaend {
let krow = arow[nzaptr];
if rperm[krow - OFF] == 0 {
found[krow - OFF] = jcol;
*lastlu += 1;
lurow[*lastlu - OFF] = krow as isize;
}
}
Ok(())
}