partial_sums_of_sigma_function_fast.sf 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #!/usr/bin/ruby
  2. # Author: Daniel "Trizen" Șuteu
  3. # Date: 08 November 2018
  4. # https://github.com/trizen
  5. # A new generalized algorithm with O(sqrt(n)) complexity for computing the partial-sums of the `sigma_j(k)` function:
  6. #
  7. # Sum_{k=1..n} sigma_j(k)
  8. #
  9. # for any j >= 0.
  10. # See also:
  11. # https://en.wikipedia.org/wiki/Divisor_function
  12. # https://en.wikipedia.org/wiki/Faulhaber%27s_formula
  13. # https://en.wikipedia.org/wiki/Bernoulli_polynomials
  14. # https://trizenx.blogspot.com/2018/08/interesting-formulas-and-exercises-in.html
  15. func fast_sigma_partial_sum(n, m) { # O(sqrt(n)) complexity
  16. var x = n.isqrt
  17. var total = 0
  18. var r = floor((n - x*x) / x)
  19. for k in (2 .. x) {
  20. total += ((k-1) * (faulhaber_sum(floor(n/(k-1)), m) - faulhaber_sum(floor(n/k), m)))
  21. }
  22. for k in (1 .. x+r) {
  23. total += (k**m * floor(n/k))
  24. }
  25. return total
  26. }
  27. func sigma_partial_sum(n, m) { # just for testing
  28. sum(1..n, {|k| k.sigma(m) })
  29. }
  30. say fast_sigma_partial_sum(64, 1) #=> 3403
  31. say fast_sigma_partial_sum(1234, 1) #=> 1252881
  32. say fast_sigma_partial_sum(10**8, 1) #=> 8224670422194237
  33. for m in (0..10) {
  34. var n = 1000.irand
  35. var t1 = sigma_partial_sum(n, m)
  36. var t2 = fast_sigma_partial_sum(n, m)
  37. assert_eq(t1, t2)
  38. say "Sum_{k=1..#{n}} sigma_#{m}(k) = #{t2}"
  39. }
  40. __END__
  41. Sum_{k=1..636} sigma_0(k) = 4207
  42. Sum_{k=1..792} sigma_1(k) = 516685
  43. Sum_{k=1..931} sigma_2(k) = 323806973
  44. Sum_{k=1..169} sigma_3(k) = 223193496
  45. Sum_{k=1..488} sigma_4(k) = 5769713450709
  46. Sum_{k=1..273} sigma_5(k) = 70956696365063
  47. Sum_{k=1..145} sigma_6(k) = 198809981088528
  48. Sum_{k=1..683} sigma_7(k) = 5978226604112758227128
  49. Sum_{k=1..526} sigma_8(k) = 346112075042681515591218
  50. Sum_{k=1..182} sigma_9(k) = 4102255527573432874448
  51. Sum_{k=1..828} sigma_10(k) = 11482542651434233742306411936154