sciforge 0.0.3

A comprehensive scientific computing library in pure Rust with zero dependencies
Documentation
pub fn local_sensitivity(
    output_perturbed: f64,
    output_base: f64,
    param_perturbed: f64,
    param_base: f64,
) -> f64 {
    let delta_output = output_perturbed - output_base;
    let delta_param = param_perturbed - param_base;
    (delta_output / output_base.max(1e-30)) / (delta_param / param_base.max(1e-30))
}

pub fn morris_elementary_effect(output_high: f64, output_base: f64, delta: f64) -> f64 {
    (output_high - output_base) / delta
}

pub fn sobol_first_order(variance_conditional: f64, variance_total: f64) -> f64 {
    variance_conditional / variance_total.max(1e-30)
}

pub fn sobol_total_order(variance_remaining: f64, variance_total: f64) -> f64 {
    1.0 - variance_remaining / variance_total.max(1e-30)
}

pub fn prcc_partial_rank_correlation(r_xy_given_z: f64) -> f64 {
    r_xy_given_z
}

pub fn parameter_identifiability(fisher_information_diagonal: f64) -> f64 {
    1.0 / fisher_information_diagonal.max(1e-30)
}

pub fn robustness_index(
    outputs_perturbed: &[f64],
    output_nominal: f64,
    perturbation_range: f64,
) -> f64 {
    if outputs_perturbed.is_empty() {
        return 1.0;
    }
    let max_deviation = outputs_perturbed
        .iter()
        .map(|o| (o - output_nominal).abs())
        .fold(0.0, f64::max);
    1.0 - max_deviation / (output_nominal.abs() * perturbation_range).max(1e-30)
}

pub fn bifurcation_distance(parameter: f64, critical_value: f64) -> f64 {
    (parameter - critical_value).abs()
}

pub fn latin_hypercube_sample(n_samples: usize, n_params: usize) -> Vec<Vec<f64>> {
    let mut samples = Vec::with_capacity(n_samples);
    for i in 0..n_samples {
        let mut row = Vec::with_capacity(n_params);
        for j in 0..n_params {
            let base = i as f64 / n_samples as f64;
            let offset = ((i + j) % n_samples) as f64 / n_samples as f64;
            row.push((base + offset) % 1.0);
        }
        samples.push(row);
    }
    samples
}

pub fn metabolic_control_coefficient(
    flux_change: f64,
    flux_base: f64,
    enzyme_change: f64,
    enzyme_base: f64,
) -> f64 {
    (flux_change / flux_base.max(1e-30)) / (enzyme_change / enzyme_base.max(1e-30))
}