Function nekolib::math::stern_brocot

source ·
pub fn stern_brocot(
    n: i128,
    large: impl FnMut(i128, i128) -> bool,
    ok: impl FnMut(i128, i128) -> bool
) -> Result<(i128, i128), ((i128, i128), (i128, i128))>
Expand description

Stern–Brocot tree

a/b=0/1=0a/b = 0/1=0c/d=1/0=c/d = 1/0=\infty で初期化し、その mediant x/y=(a+b)/(c+d)x/y = (a+b)/(c+d) を探索する。

x/yx/y が所望の条件 ok を満たすならそれを Ok として返す。 条件 large を満たすなら c/dx/yc/d\gets x/y、そうでなければ a/bx/ya/b\gets x/y として探索を進める。 分母が nn を超えても ok を満たさなければ、((a,b),(c,d))((a, b), (c, d))Err として返す。

Examples

use nekolib::math::stern_brocot;

let (num, den) =
    stern_brocot(10_i128.pow(18), |n, d| n * n > 3 * d * d, |_, _| false)
    .err().unwrap().0;

let sqrt3 = num as f64 / den as f64;
assert!((sqrt3 - 3.0_f64.sqrt()).abs() < 1.0e-16);
assert_eq!((num, den), (734231055024833855, 423908497265970753));