partial_sums_of_dedekind_psi_function.pl 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # Date: 22 November 2018
  4. # https://github.com/trizen
  5. # A new algorithm for computing the partial-sums of the Dedekind psi function `ψ_m(k)`, for `1 <= k <= n`:
  6. #
  7. # Sum_{k=1..n} ψ_m(k)
  8. #
  9. # for any fixed integer m >= 1.
  10. # Based on the formula:
  11. # Sum_{k=1..n} ψ_m(k) = Sum_{k=1..n} moebius(k)^2 * F(m, floor(n/k))
  12. #
  13. # where F(n,x) is Faulhaber's formula for `Sum_{k=1..x} k^n`, defined in terms of Bernoulli polynomials as:
  14. # F(n, x) = (Bernoulli(n+1, x+1) - Bernoulli(n+1, 1)) / (n+1)
  15. # Example for a(n) = Sum_{k=1..n} ψ_2(k):
  16. # a(10^1) = 462
  17. # a(10^2) = 400576
  18. # a(10^3) = 394504950
  19. # a(10^4) = 393921912410
  20. # a(10^5) = 393861539651230
  21. # a(10^6) = 393855661025817568
  22. # a(10^7) = 393855049001462029696
  23. # a(10^8) = 393854989687473892017612
  24. # a(10^9) = 393854983651633712634417940
  25. # a(10^10) = 393854983070527507612754907046
  26. # For m=1..3, we have the following asymptotic formulas:
  27. # Sum_{k=1..n} ψ_1(k) ~ n^2 * zeta(2) / (2*zeta(4))
  28. # Sum_{k=1..n} ψ_2(k) ~ n^3 * zeta(3) / (3*zeta(6))
  29. # Sum_{k=1..n} ψ_3(k) ~ n^4 * zeta(4) / (4*zeta(8))
  30. # In general, for m>=1, we have:
  31. # Sum_{k=1..n} ψ_m(k) ~ n^(m+1) * zeta(m+1) / ((m+1) * zeta(2*(m+1)))
  32. # See also:
  33. # https://oeis.org/A173290
  34. # https://en.wikipedia.org/wiki/M%C3%B6bius_function
  35. # https://en.wikipedia.org/wiki/Dedekind_psi_function
  36. # https://trizenx.blogspot.com/2018/11/partial-sums-of-arithmetical-functions.html
  37. use 5.020;
  38. use strict;
  39. use warnings;
  40. use experimental qw(signatures);
  41. use Math::AnyNum qw(ipow faulhaber_sum);
  42. use ntheory qw(jordan_totient moebius vecsum sqrtint forsquarefree is_square_free);
  43. sub squarefree_count {
  44. my ($n) = @_;
  45. my $k = 0;
  46. my $count = 0;
  47. foreach my $m (moebius(1, sqrtint($n))) {
  48. ++$k; $count += $m * int($n / $k / $k);
  49. }
  50. return $count;
  51. }
  52. sub dedekind_psi_partial_sum ($n, $m) { # O(sqrt(n)) complexity
  53. my $total = 0;
  54. my $s = sqrtint($n);
  55. my $u = int($n / ($s + 1));
  56. my $prev = squarefree_count($n);
  57. for my $k (1 .. $s) {
  58. my $curr = squarefree_count(int($n / ($k + 1)));
  59. $total += ($prev - $curr) * faulhaber_sum($k, $m);
  60. $prev = $curr;
  61. }
  62. forsquarefree {
  63. $total += faulhaber_sum(int($n / $_), $m);
  64. } $u;
  65. return $total;
  66. }
  67. sub dedekind_psi_partial_sum_2 ($n, $m) { # O(sqrt(n)) complexity
  68. my $total = 0;
  69. my $s = sqrtint($n);
  70. for my $k (1 .. $s) {
  71. $total += ipow($k, $m) * squarefree_count(int($n/$k));
  72. $total += faulhaber_sum(int($n/$k), $m) if is_square_free($k);
  73. }
  74. $total -= squarefree_count($s) * faulhaber_sum($s, $m);
  75. return $total;
  76. }
  77. sub dedekind_psi_partial_sum_test ($n, $m) { # just for testing
  78. vecsum(map { jordan_totient(2*$m, $_) / jordan_totient($m, $_) } 1 .. $n);
  79. }
  80. for my $m (1 .. 10) {
  81. my $n = int rand 1000;
  82. my $t1 = dedekind_psi_partial_sum($n, $m);
  83. my $t2 = dedekind_psi_partial_sum_2($n, $m);
  84. my $t3 = dedekind_psi_partial_sum_test($n, $m);
  85. die "error: $t1 != $t2" if ($t1 != $t2);
  86. die "error: $t1 != $t3" if ($t1 != $t3);
  87. say "Sum_{k=1..$n} psi_$m(k) = $t1";
  88. }
  89. __END__
  90. Sum_{k=1..626} psi_1(k) = 298020
  91. Sum_{k=1..203} psi_2(k) = 3314412
  92. Sum_{k=1..527} psi_3(k) = 20858324486
  93. Sum_{k=1..912} psi_4(k) = 131086192304600
  94. Sum_{k=1..221} psi_5(k) = 20014030184914
  95. Sum_{k=1..980} psi_6(k) = 125495875567427222916
  96. Sum_{k=1..892} psi_7(k) = 50529225624273249380976
  97. Sum_{k=1..831} psi_8(k) = 21153451972416324344508126
  98. Sum_{k=1..384} psi_9(k) = 7069511971715257063270976
  99. Sum_{k=1..434} psi_10(k) = 9477667039001209551910807864