use crate::parallel::ParallelOptions;
use scirs2_core::ndarray::ArrayView1;
#[derive(Debug, Clone)]
pub struct SparseFiniteDiffOptions {
pub method: String,
pub rel_step: Option<f64>,
pub abs_step: Option<f64>,
pub bounds: Option<Vec<(f64, f64)>>,
pub parallel: Option<ParallelOptions>,
pub seed: Option<u64>,
pub max_group_size: usize,
}
impl Default for SparseFiniteDiffOptions {
fn default() -> Self {
Self {
method: "2-point".to_string(),
rel_step: None,
abs_step: None,
bounds: None,
parallel: None,
seed: None,
max_group_size: 100,
}
}
}
#[allow(dead_code)]
pub fn compute_step_sizes(x: &ArrayView1<f64>, options: &SparseFiniteDiffOptions) -> Vec<f64> {
let n = x.len();
let mut h = vec![0.0; n];
let typical_rel_step = match options.method.as_str() {
"2-point" => 1e-8,
"3-point" => 1e-5,
"cs" => 1e-14, _ => 1e-8, };
let rel_step = options.rel_step.unwrap_or(typical_rel_step);
let abs_step = options.abs_step.unwrap_or(1e-8);
for i in 0..n {
let xi = x[i];
let mut hi = abs_step.max(rel_step * xi.abs());
if xi == 0.0 {
hi = abs_step;
}
if let Some(ref bounds) = options.bounds {
if i < bounds.len() {
let (lower, upper) = bounds[i];
if xi + hi > upper {
hi = -hi; }
if xi + hi < lower {
hi = abs_step.min((upper - xi) / 2.0); }
}
}
h[i] = hi;
}
h
}