partial_sums_of_prime_omega_function.pl 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # Date: 24 November 2018
  4. # https://github.com/trizen
  5. # A new algorithm for computing the partial-sums of the generalized prime omega function `ω_m(k)`, for `1 <= k <= n`:
  6. # A_m(n) = Sum_{k=1..n} ω_m(k)
  7. #
  8. # where:
  9. # ω_m(n) = n^m * Sum_{p|n} 1/p^m
  10. # Based on the formula:
  11. # Sum_{k=1..n} ω_m(k) = Sum_{p prime <= n} F_m(floor(n/p))
  12. #
  13. # where F_n(x) is Faulhaber's formula.
  14. # Example for `m=0`:
  15. # A_0(10^1) = 11
  16. # A_0(10^2) = 171
  17. # A_0(10^3) = 2126
  18. # A_0(10^4) = 24300
  19. # A_0(10^5) = 266400
  20. # A_0(10^6) = 2853708
  21. # A_0(10^7) = 30130317
  22. # A_0(10^8) = 315037281
  23. # A_0(10^9) = 3271067968
  24. # A_0(10^10) = 33787242719
  25. # A_0(10^11) = 347589015681
  26. # A_0(10^12) = 3564432632541
  27. # Example for `m=1`:
  28. # A_1(10^1) = 25
  29. # A_1(10^2) = 2298
  30. # A_1(10^3) = 226342
  31. # A_1(10^4) = 22616110
  32. # A_1(10^5) = 2261266482
  33. # A_1(10^6) = 226124236118
  34. # A_1(10^7) = 22612374197143
  35. # A_1(10^8) = 2261237139656553
  36. # A_1(10^9) = 226123710243814636
  37. # A_1(10^10) = 22612371006991736766
  38. # A_1(10^11) = 2261237100241987653515
  39. # A_1(10^12) = 226123710021083492369813
  40. # Example for `m=2`:
  41. # A_2(10^1) = 75
  42. # A_2(10^2) = 59962
  43. # A_2(10^3) = 58403906
  44. # A_2(10^4) = 58270913442
  45. # A_2(10^5) = 58255785988898
  46. # A_2(10^6) = 58254390385024132
  47. # A_2(10^7) = 58254229074894448703
  48. # A_2(10^8) = 58254214780225801032503
  49. # A_2(10^9) = 58254213248247357411667320
  50. # A_2(10^10) = 58254213116747777047390609694
  51. # A_2(10^11) = 58254213101385832019517484266265
  52. # A_2(10^12) = 58254213099991292350208499967189227
  53. # Asymptotic formulas:
  54. # A_1(n) ~ 0.4522474200410654985065... * n*(n+1)/2 (see: https://oeis.org/A085548)
  55. # A_2(n) ~ 0.1747626392994435364231... * n*(n+1)*(2*n+1)/6 (see: https://oeis.org/A085541)
  56. # For `m >= 1`, `A_m(n)` can be described asymptotically in terms of the prime zeta function:
  57. # A_m(n) ~ F_m(n) * P(m+1)
  58. #
  59. # where P(s) is defined as:
  60. # P(s) = Sum_{p prime >= 2} 1/p^s
  61. # OEIS sequences:
  62. # https://oeis.org/A013939 -- Partial sums of sequence A001221 (number of distinct primes dividing n).
  63. # https://oeis.org/A064182 -- Sum_{k <= 10^n} number of distinct primes dividing k.
  64. # See also:
  65. # https://en.wikipedia.org/wiki/Prime_omega_function
  66. # https://en.wikipedia.org/wiki/Prime-counting_function
  67. # https://trizenx.blogspot.com/2018/11/partial-sums-of-arithmetical-functions.html
  68. use 5.020;
  69. use strict;
  70. use warnings;
  71. use experimental qw(signatures);
  72. use Math::AnyNum qw(faulhaber_sum ipow);
  73. use ntheory qw(forprimes prime_count sqrtint is_prime);
  74. sub prime_omega_partial_sum ($n, $m) { # O(sqrt(n)) complexity
  75. my $total = 0;
  76. my $s = sqrtint($n);
  77. my $u = int($n / ($s + 1));
  78. for my $k (1 .. $s) {
  79. $total += faulhaber_sum($k, $m) * prime_count(int($n/($k+1))+1, int($n/$k));
  80. }
  81. forprimes {
  82. $total += faulhaber_sum(int($n/$_), $m);
  83. } $u;
  84. return $total;
  85. }
  86. sub prime_omega_partial_sum_2 ($n, $m) { # O(sqrt(n)) complexity
  87. my $total = 0;
  88. my $s = sqrtint($n);
  89. for my $k (1 .. $s) {
  90. $total += ipow($k, $m) * prime_count(int($n/$k));
  91. $total += faulhaber_sum(int($n/$k), $m) if is_prime($k);
  92. }
  93. $total -= faulhaber_sum($s, $m) * prime_count($s);
  94. return $total;
  95. }
  96. sub prime_omega_partial_sum_test ($n, $m) { # just for testing
  97. my $total = 0;
  98. forprimes {
  99. $total += faulhaber_sum(int($n/$_), $m);
  100. } $n;
  101. return $total;
  102. }
  103. for my $m (0 .. 10) {
  104. my $n = int rand 100000;
  105. my $t1 = prime_omega_partial_sum($n, $m);
  106. my $t2 = prime_omega_partial_sum_2($n, $m);
  107. my $t3 = prime_omega_partial_sum_test($n, $m);
  108. die "error: $t1 != $t2" if ($t1 != $t2);
  109. die "error: $t1 != $t3" if ($t1 != $t3);
  110. say "Sum_{k=1..$n} omega_$m(k) = $t1";
  111. }
  112. __END__
  113. Sum_{k=1..93178} omega_0(k) = 247630
  114. Sum_{k=1..60545} omega_1(k) = 828906439
  115. Sum_{k=1..61222} omega_2(k) = 13368082621946
  116. Sum_{k=1..58175} omega_3(k) = 220463446471253532
  117. Sum_{k=1..26576} omega_4(k) = 94816277435320229002
  118. Sum_{k=1..17978} omega_5(k) = 96085844643312478233603
  119. Sum_{k=1..99336} omega_6(k) = 112956550182103434253591001302255
  120. Sum_{k=1..15217} omega_7(k) = 1459563487599016502195229269710
  121. Sum_{k=1..62565} omega_8(k) = 3271462737352430519765722633491562894793
  122. Sum_{k=1..91318} omega_9(k) = 4007044838270388920307792726568428120477189405
  123. Sum_{k=1..28834} omega_10(k) = 514524955177931497535073881648700561462698676