Is there a way to generate a counting function for prime powers - i.e. to create a similar function to PrimePi, but including prime powers. The following will, of course, generate a list of these numbers:
Select[ Range[1000000], PrimePowerQ]
Answer
A naive approach would be this:
primePower[n_] := Count[ Range @ n, _?PrimePowerQ]
This function works well however it might be very inefficient for large n. It takes a bit to evaluate e.g.
primePower[10^6]
78734
which is only a little bigger than
PrimePi[10^6]
78498
The latter is much more efficient since it uses advanced algorithms for counting primes which exploit sparse caching and sieving techniques ( in documentation pages see Some Notes on Internal Implementation, then J. C. Lagarias, V. S. Miller and A. M. Odlyzko "Computing π(x): the Meissel-Lehmer method," Math. Comp., 44 (1985) 537-560, another interesting resources The Prime Pages: Prime Number Research, Records and Results).
Therefore we proceed along a different way making use of PrimePi to count prime powers, namely we need to sum Log[ Prime[k], n] (it measure how many times appears given prime with different powers up to n, e.g. for k == 3 there are 5, 25, 125, 625, ..., 5^Floor[ Log[ Prime[3], n]]) over every prime up to PrimePi[ Sqrt[n] // Floor] :
primePowerPi[n_] := PrimePi[n] + Sum[ Floor @ Log[ Prime[k], n] - 1,
{ k, PrimePi[ Sqrt[n] // Floor]}]
This might be done as well with:
Floor @ Log[ Prime[ Range[ PrimePi[ Sqrt[n] // Floor]]], n]
e.g.
Total[ Floor @ Log[ Prime[ Range[ PrimePi[ Sqrt[10^5] // Floor]]], 10^5] - 1] ==
primePowerPi[10^5] - PrimePi[10^5]
primePowerPi[10^5] - PrimePi[10^5]
True
108
Now we can find immediately:
primePowerPi /@ { 10^6, 10^7}
{78734, 665134}
while
PrimePi[10^7]
664579
For some limitations of Prime and PrimePi domains this reference would be helpful What is so special about Prime?.
Comments
Post a Comment