Check Machin-like formulas

The coercion to FatRat provides for exact computation for all input.

sub taneval ($coef, $f) {
  return 0 if $coef == 0;
  return $f if $coef == 1;
  return -taneval(-$coef, $f) if $coef < 0;

  my $a = taneval($coef+>1, $f);
  my $b = taneval($coef - $coef+>1, $f);
  ($a+$b)/(1-$a*$b);
}

sub tans (@xs) {
  return taneval(@xs[0;0], @xs[0;1].FatRat) if @xs == 1;

  my $a = tans(@xs[0 .. (-1+@xs+>1)]);
  my $b = tans(@xs[(-1+@xs+>1)+1 .. -1+@xs]);
  ($a+$b)/(1-$a*$b);
}

sub verify (@eqn) {
  printf "%5s (%s)\n", (tans(@eqn) == 1) ?? "OK" !! "Error",
    (map { "[{.[0]} {.[1].nude.join('/')}]" }, @eqn).join(' ');
}

verify($_) for
   ([[1,1/2], [1,1/3]],
    [[2,1/3], [1,1/7]],
    [[4,1/5], [-1,1/239]],
    [[5,1/7], [2,3/79]],
    [[5,29/278], [7,3/79]],
    [[1,1/2], [1,1/5], [1,1/8]],
    [[4,1/5], [-1,1/70], [1,1/99]],
    [[5,1/7], [4,1/53], [2,1/4443]],
    [[6,1/8], [2,1/57], [1,1/239]],
    [[8,1/10], [-1,1/239], [-4,1/515]],
    [[12,1/18], [8,1/57], [-5,1/239]],
    [[16,1/21], [3,1/239], [4,3/1042]],
    [[22,1/28], [2,1/443], [-5,1/1393], [-10,1/11018]],
    [[22,1/38], [17,7/601], [10,7/8149]],
    [[44,1/57], [7,1/239], [-12,1/682], [24,1/12943]],
    [[88,1/172], [51,1/239], [32,1/682], [44,1/5357], [68,1/12943]],
    [[88,1/172], [51,1/239], [32,1/682], [44,1/5357], [68,1/21944]]
    );

Output:

Last updated

Was this helpful?