Пример #1
0
    def __new__(cls, partition, integer=None):
        """
        Generates a new IntegerPartition object from a list or dictionary.

        The partition can be given as a list of positive integers or a
        dictionary of (integer, multiplicity) items. If the partition is
        preceeded by an integer an error will be raised if the partition
        does not sum to that given integer.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import IntegerPartition
        >>> a = IntegerPartition([5, 4, 3, 1, 1])
        >>> a
        IntegerPartition(14, (5, 4, 3, 1, 1))
        >>> print a
        [5, 4, 3, 1, 1]
        >>> IntegerPartition({1:3, 2:1})
        IntegerPartition(5, (2, 1, 1, 1))

        If the value that the partion should sum to is given first, a check
        will be made to see n error will be raised if there is a discrepancy:
        >>> IntegerPartition(10, [5, 4, 3, 1])
        Traceback (most recent call last):
        ...
        ValueError: The partition is not valid

        """
        from sympy.ntheory.residue_ntheory import int_tested

        if integer is not None:
            integer, partition = partition, integer
        if isinstance(partition, (dict, Dict)):
            _ = []
            for k, v in sorted(partition.items(), reverse=True):
                if not v:
                    continue
                k, v = int_tested(k, v)
                _.extend([k] * v)
            partition = tuple(_)
        else:
            partition = tuple(sorted(int_tested(partition), reverse=True))
        sum_ok = False
        if integer is None:
            integer = sum(partition)
            sum_ok = True
        else:
            integer = int_tested(integer)

        if not sum_ok and sum(partition) != integer:
            raise ValueError("Partition did not add to %s" % integer)
        if any(i < 1 for i in partition):
            raise ValueError("The summands must all be positive.")

        obj = Basic.__new__(cls, integer, partition)
        obj.partition = list(partition)
        obj.integer = integer
        return obj
Пример #2
0
    def __new__(cls, partition, integer=None):
        """
        Generates a new IntegerPartition object from a list or dictionary.

        The partition can be given as a list of positive integers or a
        dictionary of (integer, multiplicity) items. If the partition is
        preceeded by an integer an error will be raised if the partition
        does not sum to that given integer.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import IntegerPartition
        >>> a = IntegerPartition([5, 4, 3, 1, 1])
        >>> a
        IntegerPartition(14, (5, 4, 3, 1, 1))
        >>> print a
        [5, 4, 3, 1, 1]
        >>> IntegerPartition({1:3, 2:1})
        IntegerPartition(5, (2, 1, 1, 1))

        If the value that the partion should sum to is given first, a check
        will be made to see n error will be raised if there is a discrepancy:
        >>> IntegerPartition(10, [5, 4, 3, 1])
        Traceback (most recent call last):
        ...
        ValueError: The partition is not valid

        """
        from sympy.ntheory.residue_ntheory import int_tested

        if integer is not None:
            integer, partition = partition, integer
        if isinstance(partition, (dict, Dict)):
            _ = []
            for k, v in sorted(partition.items(), reverse=True):
                if not v:
                    continue
                k, v = int_tested(k, v)
                _.extend([k]*v)
            partition = tuple(_)
        else:
            partition = tuple(sorted(int_tested(partition), reverse=True))
        sum_ok = False
        if integer is None:
            integer = sum(partition)
            sum_ok = True
        else:
            integer = int_tested(integer)

        if not sum_ok and sum(partition) != integer:
            raise ValueError("Partition did not add to %s" % integer)
        if any(i < 1 for i in partition):
            raise ValueError("The summands must all be positive.")

        obj = Basic.__new__(cls, integer, partition)
        obj.partition = list(partition)
        obj.integer = integer
        return obj
Пример #3
0
def prevprime(n):
    """ Return the largest prime smaller than n.

        Potential primes are located at 6*j +/- 1.

        >>> from sympy import prevprime
        >>> [(i, prevprime(i)) for i in range(10, 15)]
        [(10, 7), (11, 7), (12, 11), (13, 11), (14, 13)]

        See Also
        ========

        nextprime : Return the ith prime greater than n
        primerange : Generates all primes in a given range
    """
    n = int_tested(n, strict=False)
    if n < 3:
        raise ValueError("no preceding primes")
    if n < 8:
        return {3: 2, 4: 3, 5: 3, 6: 5, 7: 5}[n]
    nn = 6 * (n // 6)
    if n - nn <= 1:
        n = nn - 1
        if isprime(n):
            return n
        n -= 4
    else:
        n = nn + 1
    while 1:
        if isprime(n):
            return n
        n -= 2
        if isprime(n):
            return n
        n -= 4
Пример #4
0
def real_root(arg, n=None):
    """Return the real nth-root of arg if possible. If n is omitted then
    all instances of -1**(1/odd) will be changed to -1.

    Examples
    ========

    >>> from sympy import root, real_root, Rational
    >>> from sympy.abc import x, n

    >>> real_root(-8, 3)
    -2
    >>> root(-8, 3)
    2*(-1)**(1/3)
    >>> real_root(_)
    -2

    See Also
    ========

    sympy.polys.rootoftools.RootOf
    sympy.core.power.integer_nthroot
    root, sqrt
    """
    if n is not None:
        n = int_tested(n)
        rv = C.Pow(arg, Rational(1, n))
        if n % 2 == 0:
            return rv
    else:
        rv = sympify(arg)
    n1pow = Transform(
        lambda x: S.NegativeOne, lambda x: x.is_Pow and x.base is S.NegativeOne
        and x.exp.is_Rational and x.exp.p == 1 and x.exp.q % 2)
    return rv.xreplace(n1pow)
Пример #5
0
def primepi(n):
    """ Return the value of the prime counting function pi(n) = the number
        of prime numbers less than or equal to n. The number n need not
        necessarily be an integer.

        Examples
        ========

        >>> from sympy import primepi
        >>> primepi(25)
        9

        See Also
        ========

        sympy.ntheory.primetest.isprime : Test if n is prime
        primerange : Generate all primes in a given range
        prime : Return the nth prime
    """
    n = int_tested(n, strict=False)
    if n < 2:
        return 0
    else:
        n = int(n)
        return sieve.search(n)[0]
Пример #6
0
def prime(nth):
    """ Return the nth prime, with the primes indexed as prime(1) = 2,
        prime(2) = 3, etc.... The nth prime is approximately n*log(n) and
        can never be larger than 2**n.

        References
        ==========

        - http://primes.utm.edu/glossary/xpage/BertrandsPostulate.html

        Examples
        ========

        >>> from sympy import prime
        >>> prime(10)
        29
        >>> prime(1)
        2

        See Also
        ========

        sympy.ntheory.primetest.isprime : Test if n is prime
        primerange : Generate all primes in a given range
        primepi : Return the number of primes less than or equal to n
    """
    n = int_tested(nth)
    if n < 1:
        raise ValueError("nth must be a positive integer; prime(1) == 2")
    return sieve[n]
Пример #7
0
def primepi(n):
    """ Return the value of the prime counting function pi(n) = the number
        of prime numbers less than or equal to n. The number n need not
        necessarily be an integer.

        Examples
        ========

        >>> from sympy import primepi
        >>> primepi(25)
        9

        See Also
        ========

        sympy.ntheory.primetest.isprime : Test if n is prime
        primerange : Generate all primes in a given range
        prime : Return the nth prime
    """
    n = int_tested(n, strict=False)
    if n < 2:
        return 0
    else:
        n = int(n)
        return sieve.search(n)[0]
Пример #8
0
def prevprime(n):
    """ Return the largest prime smaller than n.

        Potential primes are located at 6*j +/- 1.

        >>> from sympy import prevprime
        >>> [(i, prevprime(i)) for i in range(10, 15)]
        [(10, 7), (11, 7), (12, 11), (13, 11), (14, 13)]

        See Also
        ========

        nextprime : Return the ith prime greater than n
        primerange : Generates all primes in a given range
    """
    n = int_tested(n, strict=False)
    if n < 3:
        raise ValueError("no preceding primes")
    if n < 8:
        return {3: 2, 4: 3, 5: 3, 6: 5, 7: 5}[n]
    nn = 6*(n//6)
    if n - nn <= 1:
        n = nn - 1
        if isprime(n):
            return n
        n -= 4
    else:
        n = nn + 1
    while 1:
        if isprime(n):
            return n
        n -= 2
        if isprime(n):
            return n
        n -= 4
Пример #9
0
def real_root(arg, n=None):
    """Return the real nth-root of arg if possible. If n is omitted then
    all instances of -1**(1/odd) will be changed to -1.

    Examples
    ========

    >>> from sympy import root, real_root, Rational
    >>> from sympy.abc import x, n

    >>> real_root(-8, 3)
    -2
    >>> root(-8, 3)
    2*(-1)**(1/3)
    >>> real_root(_)
    -2


    See Also
    ========
    L{sqrt}, L{RootOf}, L{root}, L{integer_nthroot}

    """
    if n is not None:
        n = int_tested(n)
        rv = C.Pow(arg, Rational(1, n))
        if n % 2 == 0:
            return rv
    else:
        rv = sympify(arg)
    n1pow = Transform(
        lambda x: S.NegativeOne,
        lambda x: x.is_Pow and x.base is S.NegativeOne and x.exp.is_Rational and x.exp.p == 1 and x.exp.q % 2
    )
    return rv.xreplace(n1pow)
Пример #10
0
def nextprime(n, ith=1):
    """ Return the ith prime greater than n.

        i must be an integer.

        Notes
        =====

        Potential primes are located at 6*j +/- 1. This
        property is used during searching.

        >>> from sympy import nextprime
        >>> [(i, nextprime(i)) for i in range(10, 15)]
        [(10, 11), (11, 13), (12, 13), (13, 17), (14, 17)]
        >>> nextprime(2, ith=2) # the 2nd prime after 2
        5

        See Also
        ========

        prevprime : Return the largest prime smaller than n
        primerange : Generate all primes in a given range

    """
    n = int(n)
    i = int_tested(ith)
    if i > 1:
        pr = n
        j = 1
        while 1:
            pr = nextprime(pr)
            j += 1
            if j > i:
                break
        return pr

    if n < 2:
        return 2
    if n < 7:
        return {2: 3, 3: 5, 4: 5, 5: 7, 6: 7}[n]
    nn = 6 * (n // 6)
    if nn == n:
        n += 1
        if isprime(n):
            return n
        n += 4
    elif n - nn == 5:
        n += 2
        if isprime(n):
            return n
        n += 4
    else:
        n = nn + 5
    while 1:
        if isprime(n):
            return n
        n += 2
        if isprime(n):
            return n
        n += 4
Пример #11
0
def nextprime(n, ith=1):
    """ Return the ith prime greater than n.

        i must be an integer.

        Notes
        =====

        Potential primes are located at 6*j +/- 1. This
        property is used during searching.

        >>> from sympy import nextprime
        >>> [(i, nextprime(i)) for i in range(10, 15)]
        [(10, 11), (11, 13), (12, 13), (13, 17), (14, 17)]
        >>> nextprime(2, ith=2) # the 2nd prime after 2
        5

        See Also
        ========

        prevprime : Return the largest prime smaller than n
        primerange : Generate all primes in a given range

    """
    n = int(n)
    i = int_tested(ith)
    if i > 1:
        pr = n
        j = 1
        while 1:
            pr = nextprime(pr)
            j += 1
            if j > i:
                break
        return pr

    if n < 2:
        return 2
    if n < 7:
        return {2: 3, 3: 5, 4: 5, 5: 7, 6: 7}[n]
    nn = 6 * (n // 6)
    if nn == n:
        n += 1
        if isprime(n):
            return n
        n += 4
    elif n - nn == 5:
        n += 2
        if isprime(n):
            return n
        n += 4
    else:
        n = nn + 5
    while 1:
        if isprime(n):
            return n
        n += 2
        if isprime(n):
            return n
        n += 4
Пример #12
0
def prime(nth):
    """ Return the nth prime, with the primes indexed as prime(1) = 2,
        prime(2) = 3, etc.... The nth prime is approximately n*log(n) and
        can never be larger than 2**n.

        References
        ==========

        - http://primes.utm.edu/glossary/xpage/BertrandsPostulate.html

        Examples
        ========

        >>> from sympy import prime
        >>> prime(10)
        29
        >>> prime(1)
        2

        See Also
        ========

        sympy.ntheory.primetest.isprime : Test if n is prime
        primerange : Generate all primes in a given range
        primepi : Return the number of primes less than or equal to n
    """
    n = int_tested(nth)
    if n < 1:
        raise ValueError("nth must be a positive integer; prime(1) == 2")
    return sieve[n]
Пример #13
0
    def unrank(self, rank, n):
        """Finds the unranked Prufer sequence.

        Examples
        ========
        >>> from sympy.combinatorics.prufer import Prufer
        >>> Prufer.unrank(0, 4)
        Prufer([0, 0])

        """
        n = int_tested(n)
        rank = int_tested(rank)
        L = defaultdict(int)
        for i in xrange(n - 3, -1, -1):
            L[i] = rank % n
            rank = (rank - L[i]) // n
        return Prufer([L[i] for i in xrange(len(L))])
Пример #14
0
    def unrank(self, rank, n):
        """Finds the unranked Prufer sequence.

        Examples
        ========
        >>> from sympy.combinatorics.prufer import Prufer
        >>> Prufer.unrank(0, 4)
        Prufer([0, 0])

        """
        n = int_tested(n)
        rank = int_tested(rank)
        L = defaultdict(int)
        for i in xrange(n - 3, -1, -1):
            L[i] = rank % n
            rank = (rank - L[i])//n
        return Prufer([L[i] for i in xrange(len(L))])
Пример #15
0
 def __contains__(self, n):
     try:
         n = int_tested(n)
         assert n >= 2
     except (ValueError, AssertionError):
         return False
     if n % 2 == 0:
         return n == 2
     a, b = self.search(n)
     return a == b
Пример #16
0
 def __contains__(self, n):
     try:
         n = int_tested(n)
         assert n >= 2
     except (ValueError, AssertionError):
         return False
     if n % 2 == 0:
         return n == 2
     a, b = self.search(n)
     return a == b
Пример #17
0
    def extend_to_no(self, n):
        """Extend to include (at least) the nth prime numbers

        Examples
        ========

        >>> from sympy import sieve
        >>> sieve.extend_to_no(9)
        >>> sieve[10] == 29
        True
        """
        n = int_tested(n, strict=False)
        while len(self._list) < n:
            self.extend(int(self._list[-1] * 1.5))
Пример #18
0
    def extend_to_no(self, n):
        """Extend to include (at least) the nth prime numbers

        Examples
        ========

        >>> from sympy import sieve
        >>> sieve.extend_to_no(9)
        >>> sieve[10] == 29
        True
        """
        n = int_tested(n, strict=False)
        while len(self._list) < n:
            self.extend(int(self._list[-1] * 1.5))
Пример #19
0
 def give(a, b, seq=seed):
     from sympy.ntheory.residue_ntheory import int_tested
     a, b = int_tested(a, b)
     w = b - a
     if w < 0:
         raise ValueError('_randint got empty range')
     try:
         x = seq.pop()
     except AttributeError:
         raise ValueError('_randint expects a list-like sequence')
     except IndexError:
         raise ValueError('_randint sequence was too short')
     if a <= x <= b:
         return x
     else:
         return give(a, b, seq)
Пример #20
0
 def give(a, b, seq=seed):
     from sympy.ntheory.residue_ntheory import int_tested
     a, b = int_tested(a, b)
     w = b - a
     if w < 0:
         raise ValueError('_randint got empty range')
     try:
         x = seq.pop()
     except AttributeError:
         raise ValueError('_randint expects a list-like sequence')
     except IndexError:
         raise ValueError('_randint sequence was too short')
     if a <= x <= b:
         return x
     else:
         return give(a, b, seq)
Пример #21
0
def primorial(n, nth=True):
    """
    Returns the product of either 1. the first n primes (default) or
    2. the primes less than or equal to n (when ``nth=False``).

    >>> from sympy.ntheory.generate import primorial, randprime, primerange
    >>> from sympy import factorint, Mul, primefactors
    >>> primorial(4) # the first 4 primes are 2, 3, 5, 7
    210
    >>> primorial(4, nth=0) # primes <= 4 are 2 and 3
    6
    >>> primorial(1)
    2
    >>> primorial(1, nth=0)
    1

    One can argue that the primes are infinite since if you take
    a set of primes and multiply them together (e.g. the primorial) and
    then add or subtract 1, the result cannot be divided by any of the
    original factors, hence either 1 or more primes must divide this
    product of primes.

    >>> factorint(primorial(4) + 1)
    {211: 1}
    >>> factorint(primorial(4) - 1)
    {11: 1, 19: 1}
    >>> p = list(primerange(10, 20))
    >>> sorted(set(primefactors(Mul(*p) + 1)).difference(set(p)))
    [2, 5, 31, 149]

    See Also
    ========

    primerange : Generate all primes in a given range

    """
    n = int_tested(n, strict=False)
    if n < 1:
        raise ValueError("primorial argument must be >= 1")
    p = 1
    if nth:
        for i in range(1, n + 1):
            p *= prime(i)
    else:
        for i in primerange(2, n + 1):
            p *= i
    return p
Пример #22
0
def primorial(n, nth=True):
    """
    Returns the product of either 1. the first n primes (default) or
    2. the primes less than or equal to n (when ``nth=False``).

    >>> from sympy.ntheory.generate import primorial, randprime, primerange
    >>> from sympy import factorint, Mul, primefactors
    >>> primorial(4) # the first 4 primes are 2, 3, 5, 7
    210
    >>> primorial(4, nth=0) # primes <= 4 are 2 and 3
    6
    >>> primorial(1)
    2
    >>> primorial(1, nth=0)
    1

    One can argue that the primes are infinite since if you take
    a set of primes and multiply them together (e.g. the primorial) and
    then add or subtract 1, the result cannot be divided by any of the
    original factors, hence either 1 or more primes must divide this
    product of primes.

    >>> factorint(primorial(4) + 1)
    {211: 1}
    >>> factorint(primorial(4) - 1)
    {11: 1, 19: 1}
    >>> p = list(primerange(10, 20))
    >>> sorted(set(primefactors(Mul(*p) + 1)).difference(set(p)))
    [2, 5, 31, 149]

    See Also
    ========

    primerange : Generate all primes in a given range

    """
    n = int_tested(n, strict=False)
    if n < 1:
        raise ValueError("primorial argument must be >= 1")
    p = 1
    if nth:
        for i in range(1, n + 1):
            p *= prime(i)
    else:
        for i in primerange(2, n + 1):
            p *= i
    return p
Пример #23
0
    def __new__(cls, *args):
        # expand range
        slc = slice(*args)
        start, stop, step = slc.start or 0, slc.stop, slc.step or 1
        try:
            start, stop, step = [S(int_tested(w)) for w in (start, stop, step)]
        except ValueError:
            raise ValueError("Inputs to Range must be Integer Valued\n"+
                    "Use TransformationSets of Ranges for other cases")
        n = ceiling((stop - start)/step)
        if n <= 0:
            return S.EmptySet

        # normalize args: regardless of how they are entered they will show
        # canonically as Range(inf, sup, step) with step > 0
        start, stop = sorted((start, start + (n - 1)*step))
        step = abs(step)

        return Basic.__new__(cls, start, stop + step, step)
Пример #24
0
    def __new__(cls, *args):
        # expand range
        slc = slice(*args)
        start, stop, step = slc.start or 0, slc.stop, slc.step or 1
        try:
            start, stop, step = [S(int_tested(w)) for w in (start, stop, step)]
        except ValueError:
            raise ValueError(
                "Inputs to Range must be Integer Valued\n" +
                "Use TransformationSets of Ranges for other cases")
        n = ceiling((stop - start) / step)
        if n <= 0:
            return S.EmptySet

        # normalize args: regardless of how they are entered they will show
        # canonically as Range(inf, sup, step) with step > 0
        start, stop = sorted((start, start + (n - 1) * step))
        step = abs(step)

        return Basic.__new__(cls, start, stop + step, step)
Пример #25
0
    def __add__(self, other):
        """
        Return permutation whose rank is ``other`` greater than current rank,
        (mod the maximum rank for the set).

        Examples
        ========

        >>> from sympy.combinatorics.partitions import Partition
        >>> a = Partition([[1, 2], [3]])
        >>> a.rank
        1
        >>> (a + 1).rank
        2
        >>> (a + 100).rank
        1
        """
        other = int_tested(other)
        offset = self.rank + other
        result = RGS_unrank((offset) % RGS_enum(self.size), self.size)
        return Partition.from_rgs(result, self.members)
Пример #26
0
    def search(self, n):
        """For n >= 2, return the tightest a, b such that
        self[a] <= n <= self[b]

        Examples
        ========

        >>> from sympy import sieve
        >>> sieve.search(25)
        (9, 10)
        """
        n = int_tested(n, strict=False)
        if n < 2:
            raise ValueError("n must be greater than 1")
        if n > self._list[-1]:
            self.extend(n)
        b = bisect(self._list, n)
        if self._list[b-1] == n:
            return b, b
        else:
            return b, b+1
Пример #27
0
    def search(self, n):
        """For n >= 2, return the tightest a, b such that
        self[a] <= n <= self[b]

        Examples
        ========

        >>> from sympy import sieve
        >>> sieve.search(25)
        (9, 10)
        """
        n = int_tested(n, strict=False)
        if n < 2:
            raise ValueError("n must be greater than 1")
        if n > self._list[-1]:
            self.extend(n)
        b = bisect(self._list, n)
        if self._list[b - 1] == n:
            return b, b
        else:
            return b, b + 1
Пример #28
0
    def extend_to_no(self, i):
        """Extend to include the ith prime number.

        i must be an integer.

        The list is extended by 50% if it is too short, so it is
        likely that it will be longer than requested.

        Examples
        ========

        >>> from sympy import sieve
        >>> from array import array # this line and next for doctest only
        >>> sieve._list = array('l', [2, 3, 5, 7, 11, 13])

        >>> sieve.extend_to_no(9)
        >>> sieve._list
        array('l', [2, 3, 5, 7, 11, 13, 17, 19, 23])
        """
        i = int_tested(i)
        while len(self._list) < i:
            self.extend(int(self._list[-1] * 1.5))
Пример #29
0
    def __add__(self, other):
        """
        Return permutation whose rank is ``other`` greater than current rank,
        (mod the maximum rank for the set).

        Examples
        ========
        >>> from sympy.combinatorics.partitions import Partition
        >>> a = Partition([[1, 2], [3]])
        >>> a.rank
        1
        >>> (a + 1).rank
        2
        >>> (a + 100).rank
        1
        """
        other = int_tested(other)
        offset = self.rank + other
        result = RGS_unrank((offset) %
                            RGS_enum(self.size),
                            self.size)
        return Partition.from_rgs(result, self.members)
Пример #30
0
    def extend_to_no(self, i):
        """Extend to include the ith prime number.

        i must be an integer.

        The list is extended by 50% if it is too short, so it is
        likely that it will be longer than requested.

        Examples
        ========

        >>> from sympy import sieve
        >>> from array import array # this line and next for doctest only
        >>> sieve._list = array('l', [2, 3, 5, 7, 11, 13])

        >>> sieve.extend_to_no(9)
        >>> sieve._list
        array('l', [2, 3, 5, 7, 11, 13, 17, 19, 23])
        """
        i = int_tested(i)
        while len(self._list) < i:
            self.extend(int(self._list[-1] * 1.5))
Пример #31
0
def random_integer_partition(n, seed=None):
    """
    Generates a random integer partition summing to ``n`` as a list
    of reverse-sorted integers.

    Examples
    ========

    >>> from sympy.combinatorics.partitions import random_integer_partition

    For the following, a seed is given so a known value can be shown; in
    practice, the seed would not be given.

    >>> random_integer_partition(100, seed=[1, 1, 12, 1, 2, 1, 85, 1])
    [85, 12, 2, 1]
    >>> random_integer_partition(10, seed=[1, 2, 3, 1, 5, 1])
    [5, 3, 1, 1]
    >>> random_integer_partition(1)
    [1]
    """
    from sympy.utilities.randtest import _randint

    n = int_tested(n)
    if n < 1:
        raise ValueError('n must be a positive integer')

    randint = _randint(seed)

    partition = []
    while (n > 0):
        k = randint(1, n)
        mult = randint(1, n // k)
        partition.append((k, mult))
        n -= k * mult
    partition.sort(reverse=True)
    partition = flatten([[k] * m for k, m in partition])
    return partition
Пример #32
0
def random_integer_partition(n, seed=None):
    """
    Generates a random integer partition summing to ``n`` as a list
    of reverse-sorted integers.

    Examples
    ========

    >>> from sympy.combinatorics.partitions import random_integer_partition

    For the following, a seed is given so a known value can be shown; in
    practice, the seed would not be given.

    >>> random_integer_partition(100, seed=[1, 1, 12, 1, 2, 1, 85, 1])
    [85, 12, 2, 1]
    >>> random_integer_partition(10, seed=[1, 2, 3, 1, 5, 1])
    [5, 3, 1, 1]
    >>> random_integer_partition(1)
    [1]
    """
    from sympy.utilities.randtest import _randint

    n = int_tested(n)
    if n < 1:
        raise ValueError('n must be a positive integer')

    randint = _randint(seed)

    partition = []
    while (n > 0):
        k = randint(1, n)
        mult = randint(1, n//k)
        partition.append((k, mult))
        n -= k*mult
    partition.sort(reverse=True)
    partition = flatten([[k]*m for k, m in partition])
    return partition
Пример #33
0
def partitions(n, m=None, k=None):
    """Generate all partitions of integer n (>= 0).

    'm' limits the number of parts in the partition, e.g. if m=2 then
        partitions will contain no more than 2 numbers, while
    'k' limits the numbers which may appear in the partition, e.g. k=2 will
        return partitions with no element greater than 2.

    Each partition is represented as a dictionary, mapping an integer
    to the number of copies of that integer in the partition.  For example,
    the first partition of 4 returned is {4: 1}: a single 4.

    >>> from sympy.utilities.iterables import partitions

    Maximum key (number in partition) limited with k (in this case, 2):

    >>> for p in partitions(6, k=2):
    ...     print p
    {2: 3}
    {1: 2, 2: 2}
    {1: 4, 2: 1}
    {1: 6}

    Maximum number of parts in partion limited with m (in this case, 2):

    >>> for p in partitions(6, m=2):
    ...     print p
    ...
    {6: 1}
    {1: 1, 5: 1}
    {2: 1, 4: 1}
    {3: 2}

    Note that the _same_ dictionary object is returned each time.
    This is for speed:  generating each partition goes quickly,
    taking constant time independent of n.

    >>> [p for p in partitions(6, k=2)]
    [{1: 6}, {1: 6}, {1: 6}, {1: 6}]

    If you want to build a list of the returned dictionaries then
    make a copy of them:

    >>> [p.copy() for p in partitions(6, k=2)]
    [{2: 3}, {1: 2, 2: 2}, {1: 4, 2: 1}, {1: 6}]

    Reference:
        modified from Tim Peter's version to allow for k and m values:
        code.activestate.com/recipes/218332-generator-for-integer-partitions/

    See Also
    ========
    sympy.combinatorics.partitions.Partition
    sympy.combinatorics.partitions.IntegerPartition
    """
    from sympy.ntheory.residue_ntheory import int_tested

    if n < 0:
        raise ValueError("n must be >= 0")
    if m == 0:
        raise ValueError("m must be > 0")
    m = min(m or n, n)
    if m < 1:
        raise ValueError("maximum numbers in partition, m, must be > 0")
    k = min(k or n, n)
    if k < 1:
        raise ValueError("maximum value in partition, k, must be > 0")

    if m * k < n:
        return

    n, m, k = int_tested(n, m, k)
    q, r = divmod(n, k)
    ms = {k: q}
    keys = [k]  # ms.keys(), from largest to smallest
    if r:
        ms[r] = 1
        keys.append(r)
    room = m - q - bool(r)
    yield ms

    while keys != [1]:
        # Reuse any 1's.
        if keys[-1] == 1:
            del keys[-1]
            reuse = ms.pop(1)
            room += reuse
        else:
            reuse = 0

        while 1:
            # Let i be the smallest key larger than 1.  Reuse one
            # instance of i.
            i = keys[-1]
            newcount = ms[i] = ms[i] - 1
            reuse += i
            if newcount == 0:
                del keys[-1], ms[i]
            room += 1

            # Break the remainder into pieces of size i-1.
            i -= 1
            q, r = divmod(reuse, i)
            need = q + bool(r)
            if need > room:
                if not keys:
                    return
                continue

            ms[i] = q
            keys.append(i)
            if r:
                ms[r] = 1
                keys.append(r)
            break
        room -= need
        yield ms
Пример #34
0
 def __getitem__(self, n):
     """Return the nth prime number"""
     n = int_tested(n)
     self.extend_to_no(n)
     return self._list[n - 1]
Пример #35
0
def partitions(n, m=None, k=None):
    """Generate all partitions of integer n (>= 0).

    'm' limits the number of parts in the partition, e.g. if m=2 then
        partitions will contain no more than 2 numbers, while
    'k' limits the numbers which may appear in the partition, e.g. k=2 will
        return partitions with no element greater than 2.

    Each partition is represented as a dictionary, mapping an integer
    to the number of copies of that integer in the partition.  For example,
    the first partition of 4 returned is {4: 1}: a single 4.

    >>> from sympy.utilities.iterables import partitions

    Maximum key (number in partition) limited with k (in this case, 2):

    >>> for p in partitions(6, k=2):
    ...     print p
    {2: 3}
    {1: 2, 2: 2}
    {1: 4, 2: 1}
    {1: 6}

    Maximum number of parts in partion limited with m (in this case, 2):

    >>> for p in partitions(6, m=2):
    ...     print p
    ...
    {6: 1}
    {1: 1, 5: 1}
    {2: 1, 4: 1}
    {3: 2}

    Note that the _same_ dictionary object is returned each time.
    This is for speed:  generating each partition goes quickly,
    taking constant time independent of n.

    >>> [p for p in partitions(6, k=2)]
    [{1: 6}, {1: 6}, {1: 6}, {1: 6}]

    If you want to build a list of the returned dictionaries then
    make a copy of them:

    >>> [p.copy() for p in partitions(6, k=2)]
    [{2: 3}, {1: 2, 2: 2}, {1: 4, 2: 1}, {1: 6}]

    Reference:
        modified from Tim Peter's version to allow for k and m values:
        code.activestate.com/recipes/218332-generator-for-integer-partitions/

    See Also
    ========
    sympy.combinatorics.partitions.Partition
    sympy.combinatorics.partitions.IntegerPartition
    """
    from sympy.ntheory.residue_ntheory import int_tested

    if n < 0:
        raise ValueError("n must be >= 0")
    if m == 0:
        raise ValueError("m must be > 0")
    m = min(m or n, n)
    if m < 1:
        raise ValueError("maximum numbers in partition, m, must be > 0")
    k = min(k or n, n)
    if k < 1:
        raise ValueError("maximum value in partition, k, must be > 0")

    if m*k < n:
        return

    n, m, k = int_tested(n, m, k)
    q, r = divmod(n, k)
    ms = {k: q}
    keys = [k]  # ms.keys(), from largest to smallest
    if r:
        ms[r] = 1
        keys.append(r)
    room = m - q - bool(r)
    yield ms

    while keys != [1]:
        # Reuse any 1's.
        if keys[-1] == 1:
            del keys[-1]
            reuse = ms.pop(1)
            room += reuse
        else:
            reuse = 0

        while 1:
            # Let i be the smallest key larger than 1.  Reuse one
            # instance of i.
            i = keys[-1]
            newcount = ms[i] = ms[i] - 1
            reuse += i
            if newcount == 0:
                del keys[-1], ms[i]
            room += 1


            # Break the remainder into pieces of size i-1.
            i -= 1
            q, r = divmod(reuse, i)
            need = q + bool(r)
            if need > room:
                if not keys:
                    return
                continue

            ms[i] = q
            keys.append(i)
            if r:
                ms[r] = 1
                keys.append(r)
            break
        room -= need
        yield ms
Пример #36
0
 def __getitem__(self, n):
     """Return the nth prime number"""
     n = int_tested(n)
     self.extend_to_no(n)
     return self._list[n - 1]
Пример #37
0
def solve_congruence(*remainder_modulus_pairs, **hint):
    """Compute the integer ``n`` that has the residual ``ai`` when it is
    divided by ``mi`` where the ``ai`` and ``mi`` are given as pairs to
    this function: ((a1, m1), (a2, m2), ...). If there is no solution,
    return None. Otherwise return ``n`` and its modulus.

    The ``mi`` values need not be co-prime. If it is known that the moduli are
    not co-prime then the hint ``check`` can be set to False (default=True) and
    the check for a quicker solution via crt() (valid when the moduli are
    co-prime) will be skipped.

    If the hint ``symmetric`` is True (default is False), the value of ``n``
    will be within 1/2 of the modulus, possibly negative.

    Examples
    ========

    >>> from sympy.ntheory.modular import solve_congruence

    What number is 2 mod 3, 3 mod 5 and 2 mod 7?

    >>> solve_congruence((2, 3), (3, 5), (2, 7))
    (23, 105)
    >>> [23 % m for m in [3, 5, 7]]
    [2, 3, 2]

    If you prefer to work with all remainder in one list and
    all moduli in another, send the arguments like this:

    >>> solve_congruence(*zip((2, 3, 2), (3, 5, 7)))
    (23, 105)

    The moduli need not be co-prime; in this case there may or
    may not be a solution:

    >>> solve_congruence((2, 3), (4, 6)) is None
    True

    >>> solve_congruence((2, 3), (5, 6))
    (5, 6)

    The symmetric flag will make the result be within 1/2 of the modulus:

    >>> solve_congruence((2, 3), (5, 6), symmetric=True)
    (-1, 6)

    See also: crt and sympy.polys.galoistools.gf_crt
    """
    def combine(c1, c2):
        """Return the tuple (a, m) which satisfies the requirement
        that n = a + i*m satisfy n = a1 + j*m1 and n = a2 = k*m2.

        References
        ==========
        - http://en.wikipedia.org/wiki/Method_of_successive_substitution
        """
        from sympy.core.numbers import igcdex
        a1, m1 = c1
        a2, m2 = c2
        a, b, c = m1, a2 - a1, m2
        g = reduce(igcd, [a, b, c])
        a, b, c = [i // g for i in [a, b, c]]
        if a != 1:
            inv_a, _, g = igcdex(a, c)
            if g != 1:
                return None
            b *= inv_a
        a, m = a1 + m1 * b, m1 * c
        return a, m

    rm = remainder_modulus_pairs
    symmetric = hint.get('symmetric', False)

    if hint.get('check', True):
        rm = [int_tested(*pair) for pair in rm]

        # ignore redundant pairs but raise an error otherwise; also
        # make sure that a unique set of bases is sent to gf_crt if
        # they are all prime.
        #
        # The routine will work out less-trivial violations and
        # return None, e.g. for the pairs (1,3) and (14,42) there
        # is no answer because 14 mod 42 (having a gcd of 14) implies
        # (14/2) mod (42/2), (14/7) mod (42/7) and (14/14) mod (42/14)
        # which, being 0 mod 3, is inconsistent with 1 mod 3. But to
        # preprocess the input beyond checking of another pair with 42
        # or 3 as the modulus (for this example) is not necessary.
        uniq = {}
        for r, m in rm:
            r %= m
            if m in uniq:
                if r != uniq[m]:
                    return None
                continue
            uniq[m] = r
        rm = [(r, m) for m, r in uniq.iteritems()]
        del uniq

        # if the moduli are co-prime, the crt will be significantly faster;
        # checking all pairs for being co-prime gets to be slow but a prime
        # test is a good trade-off
        if all(isprime(m) for r, m in rm):
            r, m = zip(*rm)
            return crt(m, r, symmetric=symmetric, check=False)

    rv = (0, 1)
    for rmi in rm:
        rv = combine(rv, rmi)
        if rv is None:
            break
        n, m = rv
        n = n % m
    else:
        if symmetric:
            return symmetric_residue(n, m), m
        return n, m
Пример #38
0
def crt(m, v, symmetric=False, check=True):
    r"""Chinese Remainder Theorem.

    The moduli in m are assumed to be pairwise coprime.  The output
    is then an integer f, such that f = v_i mod m_i for each pair out
    of v and m. If ``symmetric`` is False a positive integer will be
    returned, else \|f\| will be less than or equal to the LCM of the
    moduli, and thus f may be negative.

    If the moduli are not co-prime the correct result will be returned
    if/when the test of the result is found to be incorrect. This result
    will be None if there is no solution.

    The keyword ``check`` can be set to False if it is known that the moduli
    are coprime.

    As an example consider a set of residues ``U = [49, 76, 65]``
    and a set of moduli ``M = [99, 97, 95]``. Then we have::

       >>> from sympy.ntheory.modular import crt, solve_congruence

       >>> crt([99, 97, 95], [49, 76, 65])
       (639985, 912285)

    This is the correct result because::

       >>> [639985 % m for m in [99, 97, 95]]
       [49, 76, 65]

    If the moduli are not co-prime, you may receive an incorrect result
    if you use ``check=False``:

       >>> crt([12, 6, 17], [3, 4, 2], check=False)
       (954, 1224)
       >>> [954 % m for m in [12, 6, 17]]
       [6, 0, 2]
       >>> crt([12, 6, 17], [3, 4, 2]) is None
       True
       >>> crt([3, 6], [2, 5])
       (5, 6)

    Note: the order of gf_crt's arguments is reversed relative to crt,
    and that solve_congruence takes residue, modulus pairs.

    Programmer's note: rather than checking that all pairs of moduli share
    no GCD (an O(n**2) test) and rather than factoring all moduli and seeing
    that there is no factor in common, a check that the result gives the
    indicated residuals is performed -- an O(n) operation.
    """
    if check:
        m = int_tested(*m)
        v = int_tested(*v)

    result = gf_crt(v, m, ZZ)
    mm = prod(m)

    if check:
        if not all(v % m == result % m for v, m in zip(v, m)):
            result = solve_congruence(*zip(v, m),
                                      **dict(check=False, symmetric=symmetric))
            if result is None:
                return result
            result, mm = result

    if symmetric:
        return symmetric_residue(result, mm), mm
    return result, mm
Пример #39
0
def crt(m, v, symmetric=False, check=True):
    """Chinese Remainder Theorem.

    The moduli in m are assumed to be pairwise coprime.  The output
    is then an integer f, such that f = v_i mod m_i for each pair out
    of v and m. If ``symmetric`` is False a positive integer will be
    returned, else |f| will be less than or equal to the LCM of the
    moduli, and thus f may be negative.

    If the moduli are not co-prime the correct result will be returned
    if/when the test of the result is found to be incorrect. This result
    will be None if there is no solution.

    The keyword ``check`` can be set to False if it is known that the moduli
    are coprime.

    As an example consider a set of residues ``U = [49, 76, 65]``
    and a set of moduli ``M = [99, 97, 95]``. Then we have::

       >>> from sympy.ntheory.modular import crt, solve_congruence

       >>> crt([99, 97, 95], [49, 76, 65])
       (639985, 912285)

    This is the correct result because::

       >>> [639985 % m for m in [99, 97, 95]]
       [49, 76, 65]

    If the moduli are not co-prime, you may receive an incorrect result
    if you use ``check=False``:

       >>> crt([12, 6, 17], [3, 4, 2], check=False)
       (954, 1224)
       >>> [954 % m for m in [12, 6, 17]]
       [6, 0, 2]
       >>> crt([12, 6, 17], [3, 4, 2]) is None
       True
       >>> crt([3, 6], [2, 5])
       (5, 6)

    Note: the order of gf_crt's arguments is reversed relative to crt,
    and that solve_congruence takes residue, modulus pairs.

    Programmer's note: rather than checking that all pairs of moduli share
    no GCD (an O(n**2) test) and rather than factoring all moduli and seeing
    that there is no factor in common, a check that the result gives the
    indicated residuals is performed -- an O(n) operation.
    """
    if check:
        m = int_tested(*m)
        v = int_tested(*v)

    result = gf_crt(v, m, ZZ)
    mm = prod(m)

    if check:
        if not all(v % m == result % m for v, m in zip(v, m)):
            result = solve_congruence(*zip(v, m),
                                      **dict(check=False,
                                             symmetric=symmetric))
            if result is None:
                return result
            result, mm = result

    if symmetric:
        return symmetric_residue(result, mm), mm
    return result, mm
Пример #40
0
def solve_congruence(*remainder_modulus_pairs, **hint):
    """Compute the integer ``n`` that has the residual ``ai`` when it is
    divided by ``mi`` where the ``ai`` and ``mi`` are given as pairs to
    this function: ((a1, m1), (a2, m2), ...). If there is no solution,
    return None. Otherwise return ``n`` and its modulus.

    The ``mi`` values need not be co-prime. If it is known that the moduli are
    not co-prime then the hint ``check`` can be set to False (default=True) and
    the check for a quicker solution via crt() (valid when the moduli are
    co-prime) will be skipped.

    If the hint ``symmetric`` is True (default is False), the value of ``n``
    will be within 1/2 of the modulus, possibly negative.

    Examples::
    >>> from sympy.ntheory.modular import solve_congruence

    What number is 2 mod 3, 3 mod 5 and 2 mod 7?
    >>> solve_congruence((2, 3), (3, 5), (2, 7))
    (23, 105)
    >>> [23 % m for m in [3, 5, 7]]
    [2, 3, 2]

    If you prefer to work with all remainder in one list and
    all moduli in another, send the arguments like this:
    >>> solve_congruence(*zip((2, 3, 2), (3, 5, 7)))
    (23, 105)

    The moduli need not be co-prime; in this case there may or
    may not be a solution:
    >>> solve_congruence((2, 3), (4, 6)) is None
    True
    >>> solve_congruence((2, 3), (5, 6))
    (5, 6)

    The symmetric flag will make the result be within 1/2 of the modulus:
    >>> solve_congruence((2, 3), (5, 6), symmetric=True)
    (-1, 6)

    See also: crt and sympy.polys.galoistools.gf_crt
    """
    def combine(c1, c2):
        """Return the tuple (a, m) which satisfies the requirement
        that n = a + i*m satisfy n = a1 + j*m1 and n = a2 = k*m2.

        Reference:
           http://en.wikipedia.org/wiki/Method_of_successive_substitution
        """
        from sympy.core.numbers import igcdex
        a1, m1 = c1
        a2, m2 = c2
        a, b, c = m1, a2 - a1, m2
        g = reduce(igcd, [a, b, c])
        a, b, c = [i//g for i in [a, b, c]]
        if a != 1:
            inv_a, _, g = igcdex(a, c)
            if g != 1:
                return None
            b *= inv_a
        a, m = a1 + m1*b, m1*c
        return a, m

    rm = remainder_modulus_pairs
    symmetric = hint.get('symmetric', False)

    if hint.get('check', True):
        rm = [int_tested(*pair) for pair in rm]

        # ignore redundant pairs but raise an error otherwise; also
        # make sure that a unique set of bases is sent to gf_crt if
        # they are all prime.
        #
        # The routine will work out less-trivial violations and
        # return None, e.g. for the pairs (1,3) and (14,42) there
        # is no answer because 14 mod 42 (having a gcd of 14) implies
        # (14/2) mod (42/2), (14/7) mod (42/7) and (14/14) mod (42/14)
        # which, being 0 mod 3, is inconsistent with 1 mod 3. But to
        # preprocess the input beyond checking of another pair with 42
        # or 3 as the modulus (for this example) is not necessary.
        uniq = {}
        for r, m in rm:
            r %= m
            if m in uniq:
                if r != uniq[m]:
                    return None
                continue
            uniq[m] = r
        rm = [(r, m) for m, r in uniq.iteritems()]
        del uniq

        # if the moduli are co-prime, the crt will be significantly faster;
        # checking all pairs for being co-prime gets to be slow but a prime
        # test is a good trade-off
        if all(isprime(m) for r, m in rm):
            r, m = zip(*rm)
            return crt(m, r, symmetric=symmetric, check=False)

    rv = (0, 1)
    for rmi in rm:
        rv = combine(rv, rmi)
        if rv is None:
            break
        n, m = rv
        n = n % m
    else:
        if symmetric:
            return symmetric_residue(n, m), m
        return n, m