7
$\begingroup$

Recall that the primorial of a positive integer $n$ is the product of the prime numbers smaller than $n$. One can define a primorial function in Mathematica quite easily:

primorial[n_?Positive] := Product[Prime[i], {i, 1, n}];

primorial[10]
(* 6469693230 *)

I am interested in calculating primorial[i] for $2<i<10^8$ in an efficient manner. Obviously, I can't just do a

Table[primorial[i],{i,2,10^8}]

which would be quite the opposite of efficient. On the other hand, I could use a running product of the first $k$ primes in a loop, and multiply with the next prime at each new iteration. But that does not feel to me like the ''Mathematica way'' to do things.

What would be an efficient way of achieving what I've described?

$\endgroup$
3
  • 1
    $\begingroup$ A benchmark comparison of all solutions provided would be desirable. Both memory use and time. $\endgroup$
    – rhermans
    Jan 3, 2023 at 15:14
  • $\begingroup$ If you are interested on avoiding recomputing the same list many times, something similar to memoization, see this other Q&A $\endgroup$
    – rhermans
    Jan 4, 2023 at 11:06
  • 3
    $\begingroup$ For those not familiar with primorials: it's actually not the product of the "prime numbers smaller than n" as stated in the question but the product of the 1st to the n-th prime numbers. So primorial[10] is the product of the first 10 prime numbers. Not just 2x3x5x7. $\endgroup$
    – noox
    Jan 4, 2023 at 14:33

3 Answers 3

11
$\begingroup$

Mathematica code is already provided in the The On-Line Encyclopedia of Integer Sequences, here http://oeis.org/A002110

oeis Sol 1

primorial1[n_] := FoldList[Times, 1, Prime[Range[n]]]

oeis Sol 2

primorial2[n_] := Array[Product[Prime[i], {i, #}]&, n] (* José María Grau Ribas, Feb 15 2010 *)

oeis Sol 3

 primorial3[n_] := Join[{1}, Denominator[Accumulate[1/Prime[Range[n]]]]] (* Harvey P. Dale, Apr 11 2012 *)

You didn't ask for it, but one may want to have a solution using memoization . See this other answer here.

$\endgroup$
2
  • 1
    $\begingroup$ The first solution is quite elegant, and should suffice. $\endgroup$ Jan 4, 2023 at 2:00
  • $\begingroup$ @DavidG.Stork agree, but I wanted to put all the solutions listed on OEIS. I would have wanted also to do some clever Memoization that stored only the largest pre-computed list primorial3[m], and evaluated to Take[primorial3[m],n] for $n<m$ and updated the definitions of primorial3 with FoldList[Times, 1, Prime[Range[m,n]]] for $n>m$. But the OP didn't need that. And my first attempt looked ugly. $\endgroup$
    – rhermans
    Jan 4, 2023 at 9:10
7
$\begingroup$

Luckily Prime is Listable and we can make an elegant solution with FoldList:

FoldList[Times, Prime[Range[5]]]

(* Out: {2, 6, 30, 210, 2310} *)

Replace 5 with any number you want.

$\endgroup$
0
5
$\begingroup$

Not sure if the following is considered a good way, but at least it gave results in realistic time frames and did not crash anything.

Create the list of primes and then multiply the elements of the list with a trick from the answer of Andrew Moylan in this post

Consider

list = Table[Prime[ii], {ii, 1, 10^8}]

this takes a little bit, but managed to give a result

res0

Then, you perform

Exp[Total[Log[N[list]]]]

to get

res2

Checking against the known result

(Exp[Total[Log[N[list[[1 ;; 10]]]]]])/
 Times @@ list[[1 ;; 10]]

1

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.