MOS substitution: Difference between revisions

Inthar (talk | contribs)
Inthar (talk | contribs)
Line 40: Line 40:
Rust code for generating MOS substitution scales:
Rust code for generating MOS substitution scales:
<syntaxhighlight lang="rs>
<syntaxhighlight lang="rs>
/// Return the darkest mode of the MOS axby and the dark generator, using the Bresenham line algorithm.
/// We chose the darkest mode rather than the brightest because this is the mode with brightness == 0.
pub fn darkest_mos_mode_and_gen_bresenham(
    a: usize,
    b: usize,
) -> (Vec<Letter>, CountVector<Letter>) {
    let d = gcd(a as u64, b as u64) as usize;
    if d == 1 {
        let count_gen_steps = modinv(a as i64, a as i64 + b as i64)
                .expect("The dark generator is a (|L|⁻¹ mod |scale|)-step, since stacking it |L| times results in the s step (mod period).")
                as usize;
        let mut result_scale: Vec<usize> = vec![];
        // Start from the origin (0, 0)
        let (mut current_x, mut current_y) = (0usize, 0usize);
        while (current_x, current_y) != (a, b) {
            if a * (current_y) >= b * (current_x + 1) {
                // If going east (making a (1, 0) step) doesn't lead to going below the line y == b/a*x,
                current_x += 1; // append the x step and reflect the change in the plane vector.
                result_scale.push(0);
            } else {
                // Else, make a (0, 1) step.
                current_y += 1;
                result_scale.push(1);
            }
        }
        // Get the dark generator. We know how many steps and that this will give the perfect generator, not the
        // augmented one, since we just got the darkest mode.
        let result_gen = CountVector::from_slice(&result_scale[0..count_gen_steps]);
        (result_scale, result_gen)
    } else {
        let (prim_mos, gen) = darkest_mos_mode_and_gen_bresenham(a / d, b / d);
        (prim_mos.repeat(d), gen)
    }
}


/// Return the collection of all MOS substitution scales `subst n0 x (n1 y n2 z)`
/// Return the collection of all MOS substitution scales `subst n0 x (n1 y n2 z)`
Line 94: Line 128:
}
}
</syntaxhighlight>
</syntaxhighlight>
==Examples==
==Examples==
In the following tables, the interval class of the generators stacked in the generator sequence is such that the perfect generator has fewer <math>\mathbf{X}</math> steps than the imperfect counterpart.
In the following tables, the interval class of the generators stacked in the generator sequence is such that the perfect generator has fewer <math>\mathbf{X}</math> steps than the imperfect counterpart.