Ticket #13516: 13516_primepowers.2.patch

File 13516_primepowers.2.patch, 4.3 KB (added by ppurka, 9 years ago)

apply only this to devel/sage

  • sage/rings/arith.py

    # HG changeset patch
    # User Kevin Halasz <Khalasz@pugetsound.edu>
    # Date 1350535667 25200
    # Node ID 617a663e3033a9eb26b7418699c30cf6eea2b3a1
    # Parent  bd3a259433979a0ea68e03041604b0c9f2a04c23
    13516: Rehaul prime_powers function
    * * *
    small change to TypeError
    
    diff --git a/sage/rings/arith.py b/sage/rings/arith.py
    a b  
    704704
    705705def prime_powers(start, stop=None):
    706706    r"""
    707     List of all positive primes powers between start and stop-1,
    708     inclusive. If the second argument is omitted, returns the primes up
    709     to the first argument.
    710    
     707    List of all positive primes powers between ``start`` and
     708    ``stop``-1, inclusive. If the second argument is omitted, returns
     709    the prime powers up to the first argument.
     710
     711    INPUT:
     712
     713    - ``start`` - an integer. If two inputs are given, a lower bound
     714      for the returned set of prime powers. If this is the only input,
     715      then it is an upper bound.
     716
     717    - ``stop`` - an integer (default: ``None``) An upper bound for the
     718      returned set of prime powers.
     719
     720    OUTPUT:
     721
     722    The set of all prime powers between ``start`` and ``stop`` or, if
     723    only one argument is passed, the set of all prime powers between 1
     724    and ``start``. Note that we will here say that the number `n` is a
     725    prime power if `n=p^k`, where `p` is a prime number and `k` is a
     726    nonnegative integer. Thus, `1` is a prime power, as `1 = 2^0`.
     727
    711728    EXAMPLES::
    712    
     729
    713730        sage: prime_powers(20)
    714731        [1, 2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19]
    715732        sage: len(prime_powers(1000))
     
    728745        [97, 101, 103, 107, 109, 113, 121, 125, 127, 128]
    729746        sage: a == b
    730747        True
    731    
     748        sage: prime_powers(10,7)
     749        []
     750        sage: prime_powers(-5)
     751        []
     752        sage: prime_powers(-1,2)
     753        [1]
     754
    732755    TESTS::
    733    
    734         sage: v = prime_powers(10) 
     756
     757        sage: v = prime_powers(10)
    735758        sage: type(v[0])      # trac #922
    736759        <type 'sage.rings.integer.Integer'>
     760
     761        sage: prime_powers("foo")
     762        Traceback (most recent call last):
     763        ...
     764        TypeError: start must be an integer, foo is not an integer
     765
     766        sage: prime_powers(6, "bar")
     767        Traceback (most recent call last):
     768        ...
     769        TypeError: stop must be an integer, bar is not an integer
     770
    737771    """
     772    from sage.rings.integer import Integer
     773    # check to ensure that both inputs are positive integers
     774    if not isinstance(start, (int, Integer)):
     775        raise TypeError("start must be an integer, {} is not an integer".format(start))
     776    if not (isinstance(stop, (int, Integer)) or stop is None):
     777        raise TypeError("stop must be an integer, {} is not an integer".format(stop))
     778
     779    # coerce inputs that are ints into Integers for efficiency
     780    start = Integer(start)
     781    if(stop is not None):
     782        stop = Integer(stop)
     783
     784    # deal with the case in which only one input is given
    738785    if stop is None:
    739         start, stop = 1, integer.Integer(start)
    740     from math import log
    741     from bisect import bisect
    742     v = fast_arith.prime_range(stop)
    743     i = bisect(v, start)
    744     if start > 2:
    745         if v[i] == start:
    746             i -= 1
    747         w = list(v[i:])
    748     else:
    749         w = list(v)
     786        start, stop = 1, Integer(start)
     787
     788    # inserted to prevent an error from occurring
     789    if stop < 1:
     790        return [];
     791
     792    # find all the primes in the given range
     793    from fast_arith import prime_range
     794    temp = prime_range(stop)
     795    output = [p for p in temp if p>=start]
     796
    750797    if start <= 1:
    751         w.insert(0, integer.Integer(1))
    752     log_stop = log(stop)
    753     for p in v:
     798        output.append(Integer(1))
     799
     800    s = stop.sqrt()
     801    for p in temp:
     802        # if p > the square root of stop, p^2 will be outside the given
     803        # range
     804        if p > s:
     805            break
    754806        q = p*p
    755         n = int(log(stop)/log(p))
    756         if n <= 1:
    757             break
    758         for i in xrange(1,n):
    759             if q >= start:
    760                 w.append(q)
     807        # check if each power of p falls within the given range
     808        while q < stop:
     809            if start <= q:
     810                output.append(q)
    761811            q *= p
    762     w.sort()
    763     return w
    764    
     812
     813    output.sort()
     814    return output
    765815
    766816def primes_first_n(n, leave_pari=False):
    767817    r"""