use nalgebra::DVector;
use crate::gradient::InitialGradientCalculator;
use crate::minimum::error::MinimumError;
use crate::minimum::parameters::MinimumParameters;
use crate::minimum::seed::MinimumSeed;
use crate::minimum::state::MinimumState;
use crate::mn_fcn::MnFcn;
use crate::strategy::MnStrategy;
use crate::user_transformation::MnUserTransformation;
pub struct SimplexSeedGenerator;
impl SimplexSeedGenerator {
pub fn generate(
fcn: &MnFcn,
trafo: &MnUserTransformation,
strategy: &MnStrategy,
) -> MinimumSeed {
let n = trafo.variable_parameters();
let int_values = trafo.initial_internal_values();
let int_vec = DVector::from_vec(int_values.clone());
let fval = fcn.call(&int_values);
let params = MinimumParameters::new(int_vec, fval);
let grad_calc = InitialGradientCalculator::new(*strategy);
let gradient = grad_calc.compute(fcn, ¶ms, trafo);
let mut diag = nalgebra::DMatrix::zeros(n, n);
let eps2 = trafo.precision().eps2();
for i in 0..n {
let g2i = gradient.g2()[i];
diag[(i, i)] = if g2i.abs() > eps2 { 1.0 / g2i } else { 1.0 };
}
let error = MinimumError::new(diag, 1.0);
let edm = {
let g = gradient.grad();
let e = error.matrix();
let tmp = e * g;
g.dot(&tmp)
};
let state = MinimumState::new(params, error, gradient, edm, fcn.num_of_calls());
MinimumSeed::new(state, trafo.clone())
}
}