faulhaber_root.sf 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. #!/usr/bin/ruby
  2. # Author: Trizen
  3. # Date: 30 June 2022
  4. # https://github.com/trizen
  5. # Find the n-th Faulhaber root of a real number.
  6. func faulhaber_formula(n, p) {
  7. sum(0..p, {|k|
  8. binomial(p + 1, k) * bernoulli(k) * n**(p + 1 - k)
  9. }) / (p+1)
  10. }
  11. func faulhaber_root(n,p) {
  12. return 0 if (n == 0)
  13. return 1 if (n == 1)
  14. bsearch_inverse(n.root(p+1), 2*n.root(p+1), {|k|
  15. faulhaber_formula(k,p) <=> n
  16. })
  17. }
  18. say faulhaber_root(8432017,4) #=> 33
  19. say faulhaber_root(9768353,4) #=> 34
  20. assert_eq(faulhaber_formula(faulhaber_root(3348959773123132416, 2), 2).round(-35), 3348959773123132416)
  21. assert_eq(faulhaber_formula(faulhaber_root(3348959773123132416, 3), 3).round(-35), 3348959773123132416)
  22. assert_eq(faulhaber_formula(faulhaber_root(3348959773123132416, 4), 4).round(-35), 3348959773123132416)
  23. say faulhaber_root(2, 1) #=> 1.56155281280883027491070492798703851257359961269
  24. say faulhaber_root(2, 2) #=> 1.36297120224423511045950643699380803615429836616
  25. say faulhaber_root(2, 3) #=> 1.25454470582718128060440288907801190677770307386
  26. say faulhaber_root(2, 4) #=> 1.18970494545363732855343499605107594223791805686
  27. say faulhaber_root(2, 5) #=> 1.14888255351625193295249773554136414090750638764
  28. assert_eq(faulhaber_formula(faulhaber_root(2, 4), 4).round(-30), 2)
  29. assert_eq(faulhaber_formula(faulhaber_root(2, 5), 5).round(-30), 2)
  30. assert_eq(faulhaber_formula(faulhaber_root(2, 6), 6).round(-30), 2)
  31. assert_eq(faulhaber_formula(faulhaber_root(2, 7), 7).round(-30), 2)
  32. assert_eq(faulhaber_formula(faulhaber_root(2, 8), 8).round(-30), 2)
  33. assert_eq(faulhaber_formula(faulhaber_root(2, 9), 9).round(-30), 2)