Coverage for local/lib/python2.7/site-packages/sage/functions/prime_pi.pyx : 80%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Counting Primes
AUTHORS:
- \R. Andrew Ohana (2009): initial version of efficient prime_pi
- William Stein (2009): fix plot method
- \R. Andrew Ohana (2011): complete rewrite, ~5x speedup
EXAMPLES::
sage: z = sage.functions.prime_pi.PrimePi() sage: loads(dumps(z)) prime_pi sage: loads(dumps(z)) == z True """
#***************************************************************************** # Copyright (C) 2009,2011 R. Andrew Ohana <andrew.ohana@gmail.com> # Copyright (C) 2009 William Stein <wstein@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import absolute_import
from cypari2.paridecl cimport * from cysignals.signals cimport * from cysignals.memory cimport sig_malloc, sig_realloc, sig_free
from libc.stdint cimport int_fast8_t, uint_fast16_t, uint8_t, uint32_t, uint64_t from sage.rings.integer cimport Integer from sage.libs.pari.all import pari from sage.symbolic.function cimport BuiltinFunction from sage.libs.gmp.mpz cimport *
cdef uint64_t arg_to_uint64(x, str s1, str s2) except -1: import warnings warnings.warn("computation of %s for large x can take minutes, "%s1 + "hours, or days depending on the size of %s"%s2) if mpz_sizeinbase((<Integer>x).value, 2) > 50: warnings.warn("computation of %s for x >= 2^50 has not "%s1 + "been as thoroughly tested as for smaller values")
cdef class PrimePi(BuiltinFunction): def __init__(self): r""" The prime counting function, which counts the number of primes less than or equal to a given value.
INPUT:
- ``x`` - a real number - ``prime_bound`` - (default 0) a real number < 2^32, ``prime_pi`` will make sure to use all the primes up to ``prime_bound`` (although, possibly more) in computing ``prime_pi``, this can potentially speedup the time of computation, at a cost to memory usage.
OUTPUT:
integer -- the number of primes :math:`\leq` ``x``
EXAMPLES:
These examples test common inputs::
sage: prime_pi(7) 4 sage: prime_pi(100) 25 sage: prime_pi(1000) 168 sage: prime_pi(100000) 9592 sage: prime_pi(500509) 41581
These examples test a variety of odd inputs::
sage: prime_pi(3.5) 2 sage: prime_pi(sqrt(2357)) 15 sage: prime_pi(mod(30957, 9750979)) Traceback (most recent call last): ... TypeError: cannot coerce arguments: positive characteristic not allowed in symbolic computations
We test non-trivial ``prime_bound`` values::
sage: prime_pi(100000, 10000) 9592 sage: prime_pi(500509, 50051) 41581
The following test is to verify that :trac:`4670` has been essentially resolved::
sage: prime_pi(10^10) 455052511
The ``prime_pi`` function also has a special plotting method, so it plots quickly and perfectly as a step function::
sage: P = plot(prime_pi, 50, 100)
NOTES:
Uses a recursive implementation, using the optimizations described in [Oha2011]_.
AUTHOR:
- \R. Andrew Ohana (2011) """ 'sympy':'primepi'})
cdef uint32_t *__primes cdef uint32_t __numPrimes, __maxSieve, __primeBound cdef int_fast8_t *__tabS cdef uint_fast16_t *__smallPi cdef byteptr __pariPrimePtr
def __dealloc__(self): sig_free(self.__smallPi) sig_free(self.__tabS)
cdef void _init_tables(self): 0x10000u * sizeof(uint_fast16_t))
- (i+7u)/14u + (i+21u)/42u + (i+35u)/70u - (i+105u)/210u - (i+11u)/22u + (i+33u)/66u + (i+55u)/110u + (i+77u)/154u - (i+165u)/330u - (i+231u)/462u - (i+385u)/770u + (i+1155u)/2310u - ((i/77u)<<4u))
def __call__(self, *args, coerce=True, hold=False): r""" EXAMPLES::
sage: prime_pi.__call__(756) 133 sage: prime_pi.__call__(6574, 577) 850 sage: f(x) = prime_pi.__call__(x^2); f(x) prime_pi(x^2) sage: f(5) 9 sage: prime_pi.__call__(1, 2, 3) Traceback (most recent call last): ... TypeError: Symbolic function prime_pi takes 1 or 2 arguments (3 given) """ else:
def _eval_(self, x): r""" EXAMPLES::
sage: prime_pi._eval_(7) 4 sage: prime_pi._eval_(100) 25 sage: prime_pi._eval_(1000) 168 sage: prime_pi._eval_(100000) 9592 sage: prime_pi._eval_(500509) 41581 sage: prime_pi._eval_(3.5) 2 sage: prime_pi._eval_(sqrt(2357)) 15 sage: prime_pi._eval_(str(-2^100)) 0 sage: prime_pi._eval_(mod(30957, 9750979)) 3337
Make sure we actually compute correct results for 64-bit entries::
sage: for i in (32..42): prime_pi(2^i) # long time (13s on sage.math, 2011) 203280221 393615806 762939111 1480206279 2874398515 5586502348 10866266172 21151907950 41203088796 80316571436 156661034233
This implementation uses unsigned 64-bit ints and does not support :math:`x \geq 2^63`::
sage: prime_pi(2^63) Traceback (most recent call last): ... NotImplementedError: computation of prime_pi for x >= 2^63 is not implemented """ cdef uint64_t z
cdef uint64_t _pi(self, uint64_t x, uint64_t b) except -1: r""" Returns pi(x) under the assumption that 0 <= x < 2^64 """ b = x self._clean_cache() cython_check_exception()
cdef uint32_t _cached_count(self, uint32_t p): r""" For p < 65536, returns the value stored in ``self.__smallPi[p]``. For p <= ``self.__maxSieve``, uses a binary seach on ``self.__primes`` to compute pi(p). """ # inspired by Yann Laigle-Chapuy's suggestion # Use the expected density of primes for expected inputs to make an # educated guess size = p>>3u # deal with edge case separately return self.__numPrimes cdef uint32_t prime
cdef void _clean_cache(self):
cdef uint64_t _init_primes(self, uint32_t b) except -1: """ Populates ``self.__primes`` with all primes < b """ cdef uint32_t *prime cdef uint32_t newNumPrimes, i newNumPrimes * sizeof(uint32_t)) else: self.__numPrimes = newNumPrimes self._clean_cache() cython_check_exception() raise RuntimeError("not enough memory, maybe try with a smaller " + "prime_bound?")
cdef uint64_t _phi(self, uint64_t x, uint64_t i): r""" Legendre's formula: returns the number of primes :math:`\leq` ``x`` that are not divisible by the first ``i`` primes """ # explicitly compute for small i (x+105ull)/210ull) (x+77ull)/154ull + (x+165ull)/330ull + (x+231ull)/462ull + (x+385ull)/770ull - (x+1155ull)/2310ull) # switch to 32-bit as quickly as possible s -= self._phi(y, j) j += 1ull if j == i: return s prime += 1 y = x/(<uint64_t>prime[0]) # get y <= maxSieve so we can use a binary search with our table of # primes # get p^2 > y so that we can use the identity phi(x,a)=pi(x)-a+1 # use the identity phi(x,a) = pi(x)-a+1 and compute pi using a binary # search
cdef uint32_t _phi32(self, uint32_t x, uint32_t i): """ Same as _phi except specialized for 32-bit ints """ # table method for explicit computation was suggested by Yann # Laigle-Chapuy
def plot(self, xmin=0, xmax=100, vertical_lines=True, **kwds): """ Draw a plot of the prime counting function from ``xmin`` to ``xmax``. All additional arguments are passed on to the line command.
WARNING: we draw the plot of ``prime_pi`` as a stairstep function with explicitly drawn vertical lines where the function jumps. Technically there should not be any vertical lines, but they make the graph look much better, so we include them. Use the option ``vertical_lines=False`` to turn these off.
EXAMPLES::
sage: plot(prime_pi, 1, 100) Graphics object consisting of 1 graphics primitive sage: prime_pi.plot(-2, sqrt(2501), thickness=2, vertical_lines=False) Graphics object consisting of 16 graphics primitives """ return plot_step_function([], **kwds) return plot_step_function([(xmin,0),(xmax,0)], **kwds)
######## prime_pi = PrimePi()
cpdef Integer legendre_phi(x, a): r""" Legendre's formula, also known as the partial sieve function, is a useful combinatorial function for computing the prime counting function (the ``prime_pi`` method in Sage). It counts the number of positive integers :math:`\leq` ``x`` that are not divisible by the first ``a`` primes.
INPUT:
- ``x`` -- a real number
- ``a`` -- a non-negative integer
OUTPUT:
integer -- the number of positive integers :math:`\leq` ``x`` that are not divisible by the first ``a`` primes
EXAMPLES::
sage: legendre_phi(100, 0) 100 sage: legendre_phi(29375, 1) 14688 sage: legendre_phi(91753, 5973) 2893 sage: legendre_phi(7.5, 2) 3 sage: legendre_phi(str(-2^100), 92372) 0 sage: legendre_phi(4215701455, 6450023226) 1
NOTES:
Uses a recursive implementation, using the optimizations described in [Oha2011]_.
AUTHOR:
- \R. Andrew Ohana (2011) """ a = Integer(a) raise ValueError("a (=%s) must be non-negative"%a)
# legendre_phi(x, a) = 0 when x <= 0
# legendre_phi(x, 0) = x
# Use knowledge about the density of primes to quickly compute for many # cases where a is unusually large
# If a > prime_pi(2^32), we compute phi(x,a) = max(pi(x)-a+1,1) ret = prime_pi(x)-a+Integer(1) if ret < Integer(1): return Integer(1) return ret
# Deal with the general case (<PrimePi>prime_pi)._init_tables() (<PrimePi>prime_pi)._clean_cache() cython_check_exception()
partial_sieve_function = legendre_phi |