Today, I saw a problem described as below:
Sum all
primes
below $N$ million
At the beginning, I feel it is rather simple to calculate it in Mathematica enviroment. unfortuately, I failed >__< (Here, I assume $N=10$)
Trail 1
Total@(Prime /@ Range[PrimePi[10^9]])
General::nomem: The current computation was aborted because there was insufficient memory available to complete the computation.
Trail 2(Clumsy method)
PrimePi[10^9](*50847534*)
step0 = Total@(Prime /@ Range[1, 10^7]);
step1 = Total@(Prime /@ Range[10^7, 2*10^7]);
step2 = Total@(Prime /@ Range[2*10^7, 3*10^7]);
step3 = Total@(Prime /@ Range[3*10^7, 4*10^7]);
step4 = Total@(Prime /@ Range[4*10^7, 50847534]);
res=
step0 + step1 + step2 + step3 + step4 - Total@(Prime /@ {10^7, 2 10^7, 3 10^7, 4 10^7})
24739512092254535
Then I discoved a most efficient algorithm by Google
It is derived from similar algorithms for counting primes. The advantage is that there is no need to find all the primes to find their sum.
Let $S(v,p)$ be the sum of integers in the range $2$ to $v$ that remain after sieving with all primes smaller or equal than $p$. That is $S(v,p)$ is the sum of integers up to $v$ that are either prime or the product of primes larger than $p$.
$S(v, p)$ is equal to $S(v, p-1)$ if $p$ is not prime or $v$ is smaller than $p^2$. Otherwise ($p$ prime, $p^2 \leq v)\quad S(v,p)$ can be computed from $S(v,p-1)$ by finding the sum of integers that are removed while sieving with $p$. An integer is removed in this step if it is the product of $p$ with another integer that has no divisor smaller than $p$. This can be expressed as
$S(v,p) = S(v, p-1) - p (S(\lfloor v/p \rfloor, p-1) - S(p-1,p-1))$
Here,we need to compute $S(n,\sqrt n)$
Dynamic programming
can be used to implement this.
Performance
(A implementation can be found here)
Question
- Is it possible to implement this algorithm in Mathematica by
Dynamic programming
? - It is my first time to hear
Dynamic programming
, so I'd like to know what's isDynamic programming
?
Total[Prime /@ Range[PrimePi[10^9]]]
evaluates to24739512092254535
— i.e. the same as your trial 2 result. The computation took a few minutes, and the peak kernel memory usage was about 4.7GB. $\endgroup$n
:sumP = #*RiemannR[#] - (NIntegrate[RiemannR[x], {x, 2, #}]) &
. It takes about0.15
sec. on all (those) inputs. $\endgroup$