use crate::lu::lu::*;
use crate::LUInt;
use crate::Status;
pub fn get_factors(
lu: &mut LU,
rowperm: Option<&mut [LUInt]>,
colperm: Option<&mut [LUInt]>,
l_colptr: Option<&mut [LUInt]>,
l_rowidx: Option<&mut [LUInt]>,
l_value_: Option<&mut [f64]>,
u_colptr: Option<&mut [LUInt]>,
u_rowidx: Option<&mut [LUInt]>,
u_value_: Option<&mut [f64]>,
) -> Status {
if lu.nupdate.unwrap() != 0 {
return Status::ErrorInvalidCall;
}
let m = lu.m;
if let Some(rowperm) = rowperm {
rowperm.copy_from_slice(&pivotrow![lu][..m]);
}
if let Some(colperm) = colperm {
colperm.copy_from_slice(&pivotcol![lu][..m]);
}
if l_colptr.is_some() && l_rowidx.is_some() && l_value_.is_some() {
let l_colptr = l_colptr.unwrap();
let l_rowidx = l_rowidx.unwrap();
let l_value_ = l_value_.unwrap();
let lt_begin_p = <_begin_p!(lu);
let l_index = &lu.l_index;
let l_value = &lu.l_value;
let p = &p!(lu);
let colptr = &mut iwork1!(lu);
let mut put = 0;
for k in 0..m {
l_colptr[k] = put;
l_rowidx[put as usize] = k as LUInt;
l_value_[put as usize] = 1.0;
put += 1;
colptr[p[k] as usize] = put; put += lu.l_begin_p[k + 1] - lu.l_begin_p[k] - 1;
}
l_colptr[m] = put;
assert_eq!(put as usize, lu.l_nz + m);
for k in 0..m {
let mut pos = lt_begin_p[k];
while l_index[pos as usize] >= 0 {
let i = l_index[pos as usize];
put = colptr[i as usize];
colptr[i as usize] += 1;
l_rowidx[put as usize] = k as LUInt;
l_value_[put as usize] = l_value[pos as usize];
pos += 1;
}
}
if cfg!(feature = "debug") {
for k in 0..m {
assert_eq!(colptr[p[k] as usize], l_colptr[k + 1]);
}
}
}
if u_colptr.is_some() && u_rowidx.is_some() && u_value_.is_some() {
let u_colptr = u_colptr.unwrap();
let u_rowidx = u_rowidx.unwrap();
let u_value_ = u_value_.unwrap();
let w_index = &lu.w_index;
let w_value = &lu.w_value;
let pivotcol = &pivotcol!(lu);
let colptr = &mut iwork1!(lu);
colptr.fill(0); for j in 0..m {
for pos in lu.w_begin[j]..lu.w_end[j] {
colptr[w_index[pos as usize] as usize] += 1;
}
}
let mut put = 0;
for k in 0..m {
let j = pivotcol[k];
u_colptr[k] = put;
put += colptr[j as usize];
colptr[j as usize] = u_colptr[k]; u_rowidx[put as usize] = k as LUInt;
u_value_[put as usize] = lu.col_pivot[j as usize];
put += 1;
}
u_colptr[m] = put;
assert_eq!(put as usize, lu.u_nz + m);
for k in 0..m {
let j = pivotcol[k];
for pos in lu.w_begin[j as usize]..lu.w_end[j as usize] {
put = colptr[w_index[pos as usize] as usize];
colptr[w_index[pos as usize] as usize] += 1;
u_rowidx[put as usize] = k as LUInt;
u_value_[put as usize] = w_value[pos as usize];
}
}
if cfg!(feature = "debug") {
for k in 0..m {
assert_eq!(colptr[pivotcol[k] as usize], u_colptr[k + 1] - 1);
}
for k in 0..m {
assert_eq!(u_rowidx[u_colptr[k + 1] as usize - 1] as usize, k);
}
}
}
Status::OK
}