lib_ts_chainalign 2.1.2

A chaining-based sequence-to-sequence aligner that accounts for template switches
Documentation
use generic_a_star::cost::{AStarCost, U32Cost};
use ndarray::Array2;

use crate::{chaining_lower_bounds::gap_affine::GapAffineLowerBounds, costs::GapAffineCosts};

#[test]
fn test_max_match_run_0() {
    let cost_table = GapAffineCosts {
        substitution: U32Cost::from(2u8),
        gap_open: U32Cost::from(3u8),
        gap_extend: U32Cost::from(1u8),
    };
    let max_n = 2;
    let lower_bounds = GapAffineLowerBounds::new(max_n, 0, &cost_table);

    #[rustfmt::skip]
    let exepcted_lower_bounds = Array2::from_shape_vec(
        (max_n+1, max_n+1),
        vec![
            u32::MAX, 3, 4,
                   3, 2, 5,
                   4, 5, 4,
        ],
    )
    .unwrap();

    for a in 0..=max_n {
        for b in 0..=max_n {
            assert_eq!(
                lower_bounds.lower_bound(a, b).as_primitive(),
                exepcted_lower_bounds[[a, b]],
                "lower bound({}, {})",
                a,
                b
            );
        }
    }
}

#[test]
fn test_max_match_run_1() {
    let cost_table = GapAffineCosts {
        substitution: U32Cost::from(2u8),
        gap_open: U32Cost::from(3u8),
        gap_extend: U32Cost::from(1u8),
    };
    let max_n = 4;
    let lower_bounds = GapAffineLowerBounds::new(max_n, 1, &cost_table);

    #[rustfmt::skip]
    let exepcted_lower_bounds = Array2::from_shape_vec(
        (max_n+1, max_n+1),
        vec![
            u32::MAX, 3, 4, 5, 6,
                   3, 2, 3, 4, 5,
                   4, 3, 2, 3, 4,
                   5, 4, 3, 2, 5,
                   6, 5, 4, 5, 4,
        ],
    )
    .unwrap();

    for a in 0..=max_n {
        for b in 0..=max_n {
            assert_eq!(
                lower_bounds.lower_bound(a, b).as_primitive(),
                exepcted_lower_bounds[[a, b]],
                "lower bound({}, {})",
                a,
                b
            );
        }
    }
}

#[test]
fn test_max_match_run_2() {
    let cost_table = GapAffineCosts {
        substitution: U32Cost::from(2u8),
        gap_open: U32Cost::from(3u8),
        gap_extend: U32Cost::from(1u8),
    };
    let max_n = 6;
    let lower_bounds = GapAffineLowerBounds::new(max_n, 2, &cost_table);

    #[rustfmt::skip]
    let exepcted_lower_bounds = Array2::from_shape_vec(
        (max_n+1, max_n+1),
        vec![
            u32::MAX, 3, 4, 5, 6, 7, 8,
                   3, 2, 3, 4, 5, 6, 7,
                   4, 3, 2, 3, 4, 5, 6,
                   5, 4, 3, 2, 3, 4, 5,
                   6, 5, 4, 3, 2, 3, 4,
                   7, 6, 5, 4, 3, 2, 5,
                   8, 7, 6, 5, 4, 5, 4,
        ],
    )
    .unwrap();

    for a in 0..=max_n {
        for b in 0..=max_n {
            assert_eq!(
                lower_bounds.lower_bound(a, b).as_primitive(),
                exepcted_lower_bounds[[a, b]],
                "lower bound({}, {})",
                a,
                b
            );
        }
    }
}

#[test]
fn test_max_match_run_0_allow_all_matches() {
    let cost_table = GapAffineCosts {
        substitution: U32Cost::from(2u8),
        gap_open: U32Cost::from(3u8),
        gap_extend: U32Cost::from(1u8),
    };
    let max_n = 2;
    let lower_bounds = GapAffineLowerBounds::new_allow_all_matches(max_n, 0, &cost_table);

    #[rustfmt::skip]
    let exepcted_lower_bounds = Array2::from_shape_vec(
        (max_n+1, max_n+1),
        vec![
            0u32, 3, 4,
               3, 2, 5,
               4, 5, 4,
        ],
    )
    .unwrap();

    for a in 0..=max_n {
        for b in 0..=max_n {
            assert_eq!(
                lower_bounds.lower_bound(a, b).as_primitive(),
                exepcted_lower_bounds[[a, b]],
                "lower bound({}, {})",
                a,
                b
            );
        }
    }
}

#[test]
fn test_max_match_run_1_allow_all_matches() {
    let cost_table = GapAffineCosts {
        substitution: U32Cost::from(2u8),
        gap_open: U32Cost::from(3u8),
        gap_extend: U32Cost::from(1u8),
    };
    let max_n = 4;
    let lower_bounds = GapAffineLowerBounds::new_allow_all_matches(max_n, 1, &cost_table);

    #[rustfmt::skip]
    let exepcted_lower_bounds = Array2::from_shape_vec(
        (max_n+1, max_n+1),
        vec![
            0u32, 3, 4, 5, 6,
               3, 0, 3, 4, 5,
               4, 3, 2, 3, 4,
               5, 4, 3, 2, 5,
               6, 5, 4, 5, 4,
        ],
    )
    .unwrap();

    for a in 0..=max_n {
        for b in 0..=max_n {
            assert_eq!(
                lower_bounds.lower_bound(a, b).as_primitive(),
                exepcted_lower_bounds[[a, b]],
                "lower bound({}, {})",
                a,
                b
            );
        }
    }
}

#[test]
fn test_max_match_run_2_allow_all_matches() {
    let cost_table = GapAffineCosts {
        substitution: U32Cost::from(2u8),
        gap_open: U32Cost::from(3u8),
        gap_extend: U32Cost::from(1u8),
    };
    let max_n = 6;
    let lower_bounds = GapAffineLowerBounds::new_allow_all_matches(max_n, 2, &cost_table);

    #[rustfmt::skip]
    let exepcted_lower_bounds = Array2::from_shape_vec(
        (max_n+1, max_n+1),
        vec![
            0u32, 3, 4, 5, 6, 7, 8,
               3, 0, 3, 4, 5, 6, 7,
               4, 3, 0, 3, 4, 5, 6,
               5, 4, 3, 2, 3, 4, 5,
               6, 5, 4, 3, 2, 3, 4,
               7, 6, 5, 4, 3, 2, 5,
               8, 7, 6, 5, 4, 5, 4,
        ],
    )
    .unwrap();

    for a in 0..=max_n {
        for b in 0..=max_n {
            assert_eq!(
                lower_bounds.lower_bound(a, b).as_primitive(),
                exepcted_lower_bounds[[a, b]],
                "lower bound({}, {})",
                a,
                b
            );
        }
    }
}