continued_fractions_convergents_fast.sf 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. #!/usr/bin/ruby
  2. # Author: Trizen
  3. # Date: 13 February 2024
  4. # https://github.com/trizen
  5. # A fast algorithm to compute the continued fraction convergents for a given real value.
  6. func num2cfrac(n, r) {
  7. gather {
  8. r.times {
  9. n = 1/((n - take(n.floor.int)) || break)
  10. }
  11. }
  12. }
  13. func convergents(x, n) {
  14. var cfrac = num2cfrac(x, n)
  15. var(n1, n2) = (0, 1)
  16. var(d1, d2) = (1, 0)
  17. gather {
  18. cfrac.each {|z|
  19. (n1, n2) = (n2, n2*z + n1)
  20. (d1, d2) = (d2, d2*z + d1)
  21. take(n2/d2)
  22. }
  23. }
  24. }
  25. var tests = ["415/93", 415/93, "649/200", 649/200, "sqrt(2)", sqrt(2),
  26. "sqrt(5)", sqrt(5), "golden ratio", (sqrt(5) + 1) / 2 ]
  27. var terms = 8
  28. say "The continued fraction convergents for the following (maximum #{terms} terms) are:"
  29. tests.each_slice(2, {|s,x|
  30. printf("%15s = %s\n", s, convergents(x, terms).map { .as_frac }.join(' '))
  31. })
  32. __END__
  33. The continued fraction convergents for the following (maximum 8 terms) are:
  34. 415/93 = 4/1 9/2 58/13 415/93
  35. 649/200 = 3/1 13/4 159/49 649/200
  36. sqrt(2) = 1/1 3/2 7/5 17/12 41/29 99/70 239/169 577/408
  37. sqrt(5) = 2/1 9/4 38/17 161/72 682/305 2889/1292 12238/5473 51841/23184
  38. golden ratio = 1/1 2/1 3/2 5/3 8/5 13/8 21/13 34/21