sciforge-lib 0.0.4

Scientific computing library — mathematics, physics, chemistry, biology, astronomy, geology, meteorology.
Documentation
pub fn goodwin_oscillator_step(
    mrna: f64,
    protein: f64,
    repressor: f64,
    dt: f64,
    k1: f64,
    k2: f64,
    k3: f64,
    d1: f64,
    d2: f64,
    d3: f64,
    n: f64,
    ki: f64,
) -> (f64, f64, f64) {
    let dm = k1 / (1.0 + (repressor / ki).powf(n)) - d1 * mrna;
    let dp = k2 * mrna - d2 * protein;
    let dr = k3 * protein - d3 * repressor;
    (
        (mrna + dm * dt).max(0.0),
        (protein + dp * dt).max(0.0),
        (repressor + dr * dt).max(0.0),
    )
}

pub fn repressilator_step(
    x: &[f64; 3],
    dt: f64,
    alpha: f64,
    alpha0: f64,
    beta: f64,
    n: f64,
) -> [f64; 3] {
    let mut dx = [0.0; 3];
    for i in 0..3 {
        let repressor = x[(i + 2) % 3];
        dx[i] = -x[i] + alpha / (1.0 + repressor.powf(n)) + alpha0;
    }
    [
        (x[0] + dx[0] * dt * beta).max(0.0),
        (x[1] + dx[1] * dt * beta).max(0.0),
        (x[2] + dx[2] * dt * beta).max(0.0),
    ]
}

pub fn oscillation_period(time_series: &[f64], dt: f64) -> f64 {
    if time_series.len() < 3 {
        return 0.0;
    }
    let mean: f64 = time_series.iter().sum::<f64>() / time_series.len() as f64;
    let mut crossings = Vec::new();
    for i in 1..time_series.len() {
        if (time_series[i - 1] - mean) * (time_series[i] - mean) < 0.0 {
            crossings.push(i as f64 * dt);
        }
    }
    if crossings.len() < 2 {
        return 0.0;
    }
    let mut total = 0.0;
    for i in 1..crossings.len() {
        total += crossings[i] - crossings[i - 1];
    }
    2.0 * total / (crossings.len() - 1) as f64
}

pub fn oscillation_amplitude(time_series: &[f64]) -> f64 {
    if time_series.is_empty() {
        return 0.0;
    }
    let max = time_series
        .iter()
        .cloned()
        .fold(f64::NEG_INFINITY, f64::max);
    let min = time_series.iter().cloned().fold(f64::INFINITY, f64::min);
    (max - min) / 2.0
}

pub fn phase_plane_nullcline_x(y: f64, params: (f64, f64, f64)) -> f64 {
    let (a, b, _) = params;
    a * y / (b + y)
}

pub fn fitzhugh_nagumo_step(
    v: f64,
    w: f64,
    dt: f64,
    i_ext: f64,
    a: f64,
    b: f64,
    tau: f64,
) -> (f64, f64) {
    let dv = v - v.powi(3) / 3.0 - w + i_ext;
    let dw = (v + a - b * w) / tau;
    (v + dv * dt, w + dw * dt)
}

pub fn entrainment_arnold_tongue(coupling_strength: f64, frequency_mismatch: f64) -> bool {
    coupling_strength > frequency_mismatch.abs()
}