use crate::LUInt;
pub(crate) fn condest(
m: usize,
u_begin: &[LUInt],
u_i: &[LUInt],
u_x: &[f64],
pivot: Option<&[f64]>,
perm: Option<&[LUInt]>,
upper: i32,
work: &mut [f64],
norm: Option<&mut f64>,
norminv: Option<&mut f64>,
) -> f64 {
let mut u_norm = 0.0;
for j in 0..m {
let mut colsum: f64 = if let Some(pivot) = pivot {
pivot[j].abs()
} else {
1.0
};
let mut p = u_begin[j] as usize;
while u_i[p] >= 0 {
colsum += u_x[p].abs();
p += 1;
}
u_norm = f64::max(u_norm, colsum);
}
let u_invnorm = normest(m, u_begin, u_i, u_x, pivot, perm, upper, work);
if let Some(norm) = norm {
*norm = u_norm;
}
if let Some(norminv) = norminv {
*norminv = u_invnorm;
}
u_norm * u_invnorm
}
pub(crate) fn normest(
m: usize,
u_begin: &[LUInt],
u_i: &[LUInt],
u_x: &[f64],
pivot: Option<&[f64]>,
perm: Option<&[LUInt]>,
upper: i32,
work: &mut [f64],
) -> f64 {
let mut x1norm = 0.0;
let mut xinfnorm = 0.0;
let (kbeg, kend, kinc): (LUInt, LUInt, LUInt) = if upper != 0 {
let kbeg = 0;
let kend = m as LUInt;
let kinc = 1;
(kbeg, kend, kinc)
} else {
let kbeg = (m as LUInt) - 1;
let kend = -1;
let kinc = -1;
(kbeg, kend, kinc)
};
let mut k = kbeg;
while k != kend {
let j = if let Some(perm) = perm {
perm[k as usize] as usize
} else {
k as usize
};
let mut temp = 0.0;
let mut p = u_begin[j] as usize;
while u_i[p] >= 0 {
temp -= work[u_i[p] as usize] * u_x[p];
p += 1;
}
temp += if temp >= 0.0 { 1.0 } else { -1.0 }; if let Some(pivot) = pivot {
temp /= pivot[j];
}
work[j] = temp;
x1norm += temp.abs();
xinfnorm = f64::max(xinfnorm, temp.abs());
k += kinc;
}
let mut y1norm = 0.0;
let (kbeg, kend, kinc): (LUInt, LUInt, LUInt) = if upper != 0 {
let kbeg = (m as LUInt) - 1;
let kend = -1;
let kinc = -1;
(kbeg, kend, kinc)
} else {
let kbeg = 0;
let kend = m as LUInt;
let kinc = 1;
(kbeg, kend, kinc)
};
let mut k = kbeg;
while k != kend {
let j = if let Some(perm) = perm {
perm[k as usize] as usize
} else {
k as usize
};
if let Some(pivot) = pivot {
work[j] /= pivot[j];
}
let temp = work[j];
let mut p = u_begin[j] as usize;
while u_i[p] >= 0 {
work[u_i[p] as usize] -= temp * u_x[p];
p += 1;
}
y1norm += temp.abs();
k += kinc;
}
f64::max(y1norm / x1norm, xinfnorm)
}