sciforge 0.0.3

A comprehensive scientific computing library in pure Rust with zero dependencies
Documentation
pub fn recombination_frequency(recombinants: f64, total_offspring: f64) -> f64 {
    recombinants / total_offspring.max(1e-30)
}

pub fn map_distance_kosambi(recombination_freq: f64) -> f64 {
    0.25 * ((1.0 + 2.0 * recombination_freq) / (1.0 - 2.0 * recombination_freq).max(1e-30)).ln()
}

pub fn map_distance_haldane(recombination_freq: f64) -> f64 {
    -0.5 * (1.0 - 2.0 * recombination_freq).max(1e-30).ln()
}

pub fn haldane_to_recombination(map_distance: f64) -> f64 {
    0.5 * (1.0 - (-2.0 * map_distance).exp())
}

pub fn lod_score(theta: f64, recombinants: usize, non_recombinants: usize) -> f64 {
    let r = recombinants as f64;
    let nr = non_recombinants as f64;
    r * theta.max(1e-30).log10() + nr * (1.0 - theta).max(1e-30).log10()
        - r * 0.5_f64.log10()
        - nr * 0.5_f64.log10()
}

pub fn three_point_cross_distance(class_counts: &[f64; 8]) -> (f64, f64, f64) {
    let total: f64 = class_counts.iter().sum();
    if total <= 0.0 {
        return (0.0, 0.0, 0.0);
    }
    let single_co1 = (class_counts[2] + class_counts[3]) / total;
    let single_co2 = (class_counts[4] + class_counts[5]) / total;
    let double_co = (class_counts[6] + class_counts[7]) / total;
    (
        single_co1 + double_co,
        single_co2 + double_co,
        double_co / (single_co1 + double_co).max(1e-30) / (single_co2 + double_co).max(1e-30),
    )
}

pub fn interference(observed_double_co: f64, expected_double_co: f64) -> f64 {
    1.0 - observed_double_co / expected_double_co.max(1e-30)
}

pub fn chiasma_frequency(recombination_freq: f64) -> f64 {
    2.0 * recombination_freq
}

pub fn synaptonemal_complex_length(chromosome_length_mb: f64, loop_size_kb: f64) -> f64 {
    chromosome_length_mb * 1000.0 / loop_size_kb.max(1e-30)
}