Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get this raku Muller Recurrence One-Liner to work?

Tags:

math

raku

In a reply to my recent blog post, Markus H. replied with a very succinct code alternative, namely:

dd $_ for (4, 4.25, 108 – (815 – 1500 / * ) / * … *)[^30].kv

Sadly I cannot get this to work "out of the box" and get this error:

Confused
at /Users/stephenroe/Dropbox/RakuStuff/mullerrec/./mullerrec3.raku:27
------> dd $_ for (4, 4.25, 108⏏ – (815 – 1500 / * ) / * … *)[^30].kv
    expecting any of:
        infix
        infix stopper
        statement end
        statement modifier
        statement modifier loop

How can I fix this?

Here's the code that I can get to work (yes, my style is a bit different, but that's ok):

sub f(\y,\z) { 
    108 - ( (815 - 1500/z ) / y ) 
}
dd $_ for (4, 4.25, -> \z,\y {f(y,z)}  … ∞)[^30].kv;

As a follow up, I think I need to swap the params to f, but Markus has not done that, who is right? I am keen to know if that is a gotcha and, then the question is "how can I reverse the order by which whatever stars are consumed"?

Or maybe something like:

dd $_ for (4, 4.25, f(^z,^y) … ∞)[^30].kv;   #not legal
like image 573
p6steve Avatar asked Apr 03 '21 15:04

p6steve


1 Answers

TL;DR Cut/paste in the era of non-Unicode character sets was hopelessly fraught and getting worse – but at least it was typically loudly fraught so one got mojibake, making it obvious things had gone wrong. In the Unicode era it's a new ballgame. You need to s/–/-/.

Making that change, but also making some other changes to switch to a hopefully more insightful display, and switching to FatRat calculation so the results are 100% accurate with unlimited precision:

say sprintf "%-2s: %-24s %s / %s", .key, .value, |.value.nude

for (4.FatRat, 4.25, 108 - (815 - 1500 / * ) / * … *)[^30].pairs

0 : 4                        4 / 1
1 : 4.25                     17 / 4
2 : 4.470588                 76 / 17
3 : 4.644737                 353 / 76
4 : 4.770538                 1684 / 353
5 : 4.855701                 8177 / 1684
6 : 4.910847                 40156 / 8177
7 : 4.945537                 198593 / 40156
8 : 4.96696258               986404 / 198593
9 : 4.9800457                4912337 / 986404
10: 4.987979448              24502636 / 4912337
11: 4.9927702881             122336033 / 24502636
12: 4.99565589151            611148724 / 122336033
13: 4.99739126838            3054149297 / 611148724
14: 4.998433943945           15265963516 / 3054149297
15: 4.9990600719709          76315468673 / 15265963516
16: 4.9994359371468          381534296644 / 76315468673
17: 4.99966152410377         1907542343057 / 381534296644
18: 4.999796900713418        9537324294796 / 1907542343057
19: 4.999878135477931        47685459212513 / 9537324294796
20: 4.9999268795045999       238423809278164 / 47685459212513
21: 4.99995612706115774      1192108586037617 / 238423809278164
22: 4.999973676005712445     5960511549128476 / 1192108586037617
23: 4.999984205520272708     29802463602463553 / 5960511549128476
24: 4.9999905232822276594    149012035582781284 / 29802463602463553
25: 4.99999431395855959365   745059330625296977 / 149012035582781284
26: 4.99999658837125602371   3725294111260656556 / 745059330625296977
27: 4.999997953021356907988  18626462930705797793 / 3725294111260656556
28: 4.9999987718123113299994 93132291776736534004 / 18626462930705797793
29: 4.9999992630872057845553 465661390253305305137 / 93132291776736534004

Muller's Recurrence is an approximation. But the accuracy/precision of a given iteration is determined by the accuracy/precision of prior iterations. These are in turn affected by the accuracy/precision of the numeric type(s) and operations used:

  • Using floating point numbers / operations yields useless results after the 12th or so iteration.

  • Using fixed point numbers / operations yields accurate results as long as numbers remain within their precision, and then quickly thereafter yields useless results.

  • In my variant of @Holli's code I've used Raku's FatRat number type and operations. This maintains 100% accuracy with unlimited precision. Even cheap hardware will easily do in the order of a 1,000 iterations, with 100% accuracy, in less than a second.

The Muller's Recurrence formula mathematically involves only rational numbers and operations ("rational" includes integers). Numeric operations in Raku conveniently follow rules of "infection" such that if:

  • At least one of the numbers in each iteration is a FatRat;

  • None of the numbers is a Num (floating point);

  • No operation introduces a Num (floating point);

then each iteration will produce another 100% accurate FatRat.

This is true when Muller's Recurrence formula is used as is in Raku provided one of the numbers is coerced to a FatRat.

like image 153
raiph Avatar answered Oct 08 '22 19:10

raiph