partial_sums_of_inverse_moebius_transform_of_dedekind_function.sf 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 08 March 2019
  4. # https://github.com/trizen
  5. # Partial sums of the inverse Möbius transform of the Dedekind psi function (A001615).
  6. # Definition, for m >= 0:
  7. #
  8. # a(n) = Sum_{k=1..n} Sum_{d|k} ψ_m(d)
  9. # = Sum_{k=1..n} Sum_{d|k} 2^omega(k/d) * d^m
  10. # = Sum_{k=1..n} 2^omega(k) * F_m(floor(n/k))
  11. #
  12. # where `F_n(x)` are the Faulhaber polynomials.
  13. # Asymptotic formula:
  14. # Sum_{k=1..n} Sum_{d|k} ψ_m(d) ~ F_m(n) * (zeta(m+1)^2 / zeta(2*(m+1)))
  15. # ~ (n^(m+1) * zeta(m+1)^2) / ((m+1) * zeta(2*(m+1)))
  16. # For m=1, we have:
  17. # a(n) ~ (5/4) * n^2.
  18. # a(n) = Sum_{k=1..n} A060648(k).
  19. # a(n) = Sum_{k=1..n} Sum_{d|k} 2^omega(k/d) * d.
  20. # a(n) = Sum_{k=1..n} Sum_{d|k} A001615(d).
  21. # a(n) = (1/2)*Sum_{k=1..n} 2^omega(k) * floor(n/k) * floor(1 + n/k).
  22. # Partial sums of A060648.
  23. # See also:
  24. # https://oeis.org/A064608 -- Partial sums of A034444: sum of number of unitary divisors from 1 to n.
  25. # https://oeis.org/A061503 -- Sum_{k<=n} (tau(k^2)), where tau is the number of divisors function.
  26. func inverse_moebius_of_dedekind_partial_sum (n, m) {
  27. var lookup_size = (2 + 2*n.iroot(3)**2)
  28. var omega_sum_lookup = [0]
  29. for k in (1..lookup_size) {
  30. omega_sum_lookup[k] = (omega_sum_lookup[k-1] + 2**(k.omega))
  31. }
  32. var mu = moebius(0, n.isqrt)
  33. func R(n) { # A064608(n) = Sum_{k=1..n} 2^omega(k)
  34. if (n <= lookup_size) {
  35. return omega_sum_lookup[n]
  36. }
  37. var total = 0
  38. for k in (1..n.isqrt) {
  39. total += mu[k]*(
  40. 2*sum(1..floor(isqrt(n / k**2)), {|j|
  41. floor(n / (j * k**2))
  42. }) - floor(isqrt(n / k**2))**2
  43. ) if mu[k]
  44. }
  45. return total
  46. }
  47. var s = n.isqrt
  48. var total = 0
  49. for k in (1..s) {
  50. total += (2**omega(k) * faulhaber(floor(n/k), m))
  51. total += (k**m * R(floor(n/k)))
  52. }
  53. total -= R(s)*faulhaber_sum(s, m)
  54. return total
  55. }
  56. func inverse_moebius_of_dedekind_partial_sum_test_1(n, m) {
  57. sum(1..n, {|k|
  58. k.divisors.sum {|d|
  59. d.dedekind_psi(m)
  60. }
  61. })
  62. }
  63. func inverse_moebius_of_dedekind_partial_sum_test_2(n, m) {
  64. sum(1..n, {|k|
  65. k.divisors.sum {|d|
  66. 2**omega(k/d) * d**m
  67. }
  68. })
  69. }
  70. func inverse_moebius_of_dedekind_partial_sum_test_3(n, m) {
  71. sum(1..n, {|k|
  72. 2**omega(k) * faulhaber(floor(n/k), m)
  73. })
  74. }
  75. for m in (0 .. 10) {
  76. var n = 100.irand
  77. var t1 = inverse_moebius_of_dedekind_partial_sum(n, m)
  78. var t2 = inverse_moebius_of_dedekind_partial_sum_test_1(n, m)
  79. var t3 = inverse_moebius_of_dedekind_partial_sum_test_2(n, m)
  80. var t4 = inverse_moebius_of_dedekind_partial_sum_test_3(n, m)
  81. assert_eq(t1, t2)
  82. assert_eq(t1, t3)
  83. assert_eq(t1, t4)
  84. say "Sum_{k=1..#{n}} Sum_{d|k} ψ_#{m}(d) = #{t1}"
  85. }
  86. __END__
  87. Sum_{k=1..84} Sum_{d|k} ψ_0(d) = 956
  88. Sum_{k=1..87} Sum_{d|k} ψ_1(d) = 9310
  89. Sum_{k=1..61} Sum_{d|k} ψ_2(d) = 109853
  90. Sum_{k=1..35} Sum_{d|k} ψ_3(d) = 458652
  91. Sum_{k=1..47} Sum_{d|k} ψ_4(d) = 51704334
  92. Sum_{k=1..50} Sum_{d|k} ψ_5(d) = 2863258691
  93. Sum_{k=1..40} Sum_{d|k} ψ_6(d) = 25966179432
  94. Sum_{k=1..94} Sum_{d|k} ψ_7(d) = 801529887601705
  95. Sum_{k=1..61} Sum_{d|k} ψ_8(d) = 1402512018638201
  96. Sum_{k=1..78} Sum_{d|k} ψ_9(d) = 889920100633147511
  97. Sum_{k=1..63} Sum_{d|k} ψ_10(d) = 6152021324576989982