use crate::lu::build_factors;
use crate::lu::condest;
use crate::lu::def::*;
use crate::lu::factorize_bump;
use crate::lu::lu::*;
use crate::lu::residual_test;
use crate::lu::setup_bump;
use crate::lu::singletons;
use crate::Status;
use std::time::Instant;
pub fn factorize(
lu: &mut LU,
b_begin: &[usize],
b_end: &[usize],
b_i: &[usize],
b_x: &[f64],
c0ntinue: bool,
) -> Status {
let tic = Instant::now();
if !c0ntinue {
lu.reset();
lu.task = Task::Singletons;
}
fn return_to_caller(tic: Instant, lu: &mut LU, status: Status) -> Status {
let elapsed = tic.elapsed().as_secs_f64();
lu.time_factorize += elapsed;
lu.time_factorize_total += elapsed;
status
}
match lu.task {
Task::Singletons => {
let status = singletons(lu, b_begin, b_end, b_i, b_x);
if status != Status::OK {
return return_to_caller(tic, lu, status);
}
lu.task = Task::SetupBump;
let status = setup_bump(lu, b_begin, b_end, b_i, b_x);
if status != Status::OK {
return return_to_caller(tic, lu, status);
}
lu.task = Task::FactorizeBump;
let status = factorize_bump(lu);
if status != Status::OK {
return return_to_caller(tic, lu, status);
}
}
Task::SetupBump => {
let status = setup_bump(lu, b_begin, b_end, b_i, b_x);
if status != Status::OK {
return return_to_caller(tic, lu, status);
}
lu.task = Task::FactorizeBump;
let status = factorize_bump(lu);
if status != Status::OK {
return return_to_caller(tic, lu, status);
}
}
Task::FactorizeBump => {
let status = factorize_bump(lu);
if status != Status::OK {
return return_to_caller(tic, lu, status);
}
}
Task::BuildFactors => {}
_ => {
let status = Status::ErrorInvalidCall;
return status;
}
};
lu.task = Task::BuildFactors;
let status = build_factors(lu);
if status != Status::OK {
return return_to_caller(tic, lu, status);
}
lu.task = Task::NoTask;
lu.nupdate = Some(0); lu.ftran_for_update = None;
lu.btran_for_update = None;
lu.nfactorize += 1;
lu.condest_l = condest(
lu.m,
&l_begin!(lu),
&lu.l_index,
&lu.l_value,
None,
Some(&p!(lu)),
0,
&mut lu.work1,
Some(&mut lu.norm_l),
Some(&mut lu.normest_l_inv),
);
lu.condest_u = condest(
lu.m,
&lu.u_begin,
&lu.u_index,
&lu.u_value,
Some(&lu.row_pivot),
Some(&p!(lu)),
1,
&mut lu.work1,
Some(&mut lu.norm_u),
Some(&mut lu.normest_u_inv),
);
residual_test(lu, b_begin, b_end, b_i, b_x);
let factor_cost = 0.04 * (lu.m as f64)
+ 0.07 * (lu.matrix_nz as f64)
+ 0.20 * (lu.bump_nz as f64)
+ 0.20 * (lu.nsearch_pivot as f64)
+ 0.008 * (lu.factor_flops as f64);
lu.update_cost_denom = factor_cost * 250.0;
if cfg!(feature = "debug") {
let elapsed = lu.time_factorize + tic.elapsed().as_secs_f64();
println!(
" 1e-6 * factor_cost / time_factorize: {}",
1e-6 * factor_cost / elapsed,
);
}
if lu.rank < lu.m {
let status = Status::WarningSingularMatrix;
return_to_caller(tic, lu, status);
}
return_to_caller(tic, lu, status)
}