]> Creatis software - CreaPhase.git/blob - octave_packages/m/specfun/primes.m
update packages
[CreaPhase.git] / octave_packages / m / specfun / primes.m
1 ## Copyright (C) 2000-2012 Paul Kienzle
2 ##
3 ## This file is part of Octave.
4 ##
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
9 ##
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 ## General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING.  If not, see
17 ## <http://www.gnu.org/licenses/>.
18
19 ## -*- texinfo -*-
20 ## @deftypefn {Function File} {} primes (@var{n})
21 ##
22 ## Return all primes up to @var{n}.
23 ##
24 ## The algorithm used is the Sieve of Eratosthenes.
25 ##
26 ## Note that if you need a specific number of primes you can use the
27 ## fact that the distance from one prime to the next is, on average,
28 ## proportional to the logarithm of the prime.  Integrating, one finds
29 ## that there are about @math{k} primes less than
30 ## @tex
31 ## $k \log (5 k)$.
32 ## @end tex
33 ## @ifnottex
34 ## k*log(5*k).
35 ## @end ifnottex
36 ## @seealso{list_primes, isprime}
37 ## @end deftypefn
38
39 ## Author: Paul Kienzle
40 ## Author: Francesco Potortì
41 ## Author: Dirk Laurie
42
43 function x = primes (n)
44
45   if (nargin != 1)
46     print_usage ();
47   endif
48
49   if (! isscalar (n))
50     error ("primes: N must be a scalar");
51   endif
52
53   if (n > 100000)
54     ## Optimization: 1/6 less memory, and much faster (asymptotically)
55     ## 100000 happens to be the cross-over point for Paul's machine;
56     ## below this the more direct code below is faster.  At the limit
57     ## of memory in Paul's machine, this saves .7 seconds out of 7 for
58     ## n = 3e6.  Hardly worthwhile, but Dirk reports better numbers.
59     lenm = floor ((n+1)/6);       # length of the 6n-1 sieve
60     lenp = floor ((n-1)/6);       # length of the 6n+1 sieve
61     sievem = true (1, lenm);      # assume every number of form 6n-1 is prime
62     sievep = true (1, lenp);      # assume every number of form 6n+1 is prime
63
64     for i = 1:(sqrt(n)+1)/6       # check up to sqrt(n)
65       if (sievem(i))              # if i is prime, eliminate multiples of i
66         sievem(7*i-1:6*i-1:lenm) = false;
67         sievep(5*i-1:6*i-1:lenp) = false;
68       endif                       # if i is prime, eliminate multiples of i
69       if (sievep(i))
70         sievep(7*i+1:6*i+1:lenp) = false;
71         sievem(5*i+1:6*i+1:lenm) = false;
72       endif
73     endfor
74     x = sort([2, 3, 6*find(sievem)-1, 6*find(sievep)+1]);
75   elseif (n > 352)                # nothing magical about 352; must be >2
76     len = floor ((n-1)/2);        # length of the sieve
77     sieve = true (1, len);        # assume every odd number is prime
78     for i = 1:(sqrt(n)-1)/2       # check up to sqrt(n)
79       if (sieve(i))               # if i is prime, eliminate multiples of i
80         sieve(3*i+1:2*i+1:len) = false; # do it
81       endif
82     endfor
83     x = [2, 1+2*find(sieve)];     # primes remaining after sieve
84   else
85     a = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, ...
86          53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, ...
87          109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, ...
88          173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, ...
89          233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, ...
90          293, 307, 311, 313, 317, 331, 337, 347, 349];
91     x = a(a <= n);
92   endif
93
94 endfunction
95
96 %!error primes ();
97 %!error primes (1, 2);
98
99 %!assert (size (primes (350)), [1, 70]);
100 %!assert (size (primes (350)), [1, 70]);
101
102 %!assert (primes (357)(end), 353);