예제 #1
0
 def _calc_bernoulli(n):
     s = 0
     a = int(binomial(n + 3, n - 6))
     for j in range(1, n // 6 + 1):
         s += a * bernoulli(n - 6 * j)
         # Avoid computing each binomial coefficient from scratch
         a *= _product(n - 6 - 6 * j + 1, n - 6 * j)
         a //= _product(6 * j + 4, 6 * j + 9)
     if n % 6 == 4:
         s = -Rational(n + 3, 6) - s
     else:
         s = Rational(n + 3, 3) - s
     return s / binomial(n + 3, n)
예제 #2
0
def _stirling1(n, k):
    if n == k == 0:
        return S.One
    if 0 in (n, k):
        return S.Zero
    n1 = n - 1

    # some special values
    if n == k:
        return S.One
    elif k == 1:
        return factorial(n1)
    elif k == n1:
        return binomial(n, 2)
    elif k == n - 2:
        return (3 * n - 1) * binomial(n, 3) / 4
    elif k == n - 3:
        return binomial(n, 2) * binomial(n, 4)

    # general recurrence
    return n1 * _stirling1(n1, k) + _stirling1(n1, k - 1)
예제 #3
0
    def _eval_rewrite_as_Sum(self, arg):
        from diofant import Sum
        if arg.is_even:
            k = Dummy("k", integer=True)
            j = Dummy("j", integer=True)
            n = self.args[0] / 2
            Em = (S.ImaginaryUnit * Sum(
                Sum(
                    binomial(k, j) * ((-1)**j * (k - 2 * j)**(2 * n + 1)) /
                    (2**k * S.ImaginaryUnit**k * k), (j, 0, k)),
                (k, 1, 2 * n + 1)))

            return Em
예제 #4
0
def _stirling2(n, k):
    if n == k == 0:
        return S.One
    if 0 in (n, k):
        return S.Zero
    n1 = n - 1

    # some special values
    if k == n1:
        return binomial(n, 2)
    elif k == 2:
        return 2**n1 - 1

    # general recurrence
    return k * _stirling2(n1, k) + _stirling2(n1, k - 1)
예제 #5
0
    def eval(cls, n, sym=None):
        if n.is_Number:
            if n.is_Integer and n.is_nonnegative:
                if n is S.Zero:
                    return S.One
                elif n is S.One:
                    if sym is None:
                        return -S.Half
                    else:
                        return sym - S.Half
                # Bernoulli numbers
                elif sym is None:
                    if n.is_odd:
                        return S.Zero
                    n = int(n)
                    # Use mpmath for enormous Bernoulli numbers
                    if n > 500:
                        p, q = bernfrac(n)
                        return Rational(int(p), int(q))
                    case = n % 6
                    highest_cached = cls._highest[case]
                    if n <= highest_cached:
                        return cls._cache[n]
                    # To avoid excessive recursion when, say, bernoulli(1000) is
                    # requested, calculate and cache the entire sequence ... B_988,
                    # B_994, B_1000 in increasing order
                    for i in range(highest_cached + 6, n + 6, 6):
                        b = cls._calc_bernoulli(i)
                        cls._cache[i] = b
                        cls._highest[case] = i
                    return b
                # Bernoulli polynomials
                else:
                    n, result = int(n), []
                    for k in range(n + 1):
                        result.append(binomial(n, k) * cls(k) * sym**(n - k))
                    return Add(*result)
            else:
                raise ValueError("Bernoulli numbers are defined only"
                                 " for nonnegative integer indices.")

        if sym is None:
            if n.is_odd and (n - 1).is_positive:
                return S.Zero
예제 #6
0
    def eval(cls, n, alpha, x):
        # L_{n}^{0}(x)  --->  L_{n}(x)
        if alpha == S.Zero:
            return laguerre(n, x)

        if not n.is_Number:
            # We can evaluate for some special values of x
            if x == S.Zero:
                return binomial(n + alpha, alpha)
            elif x == S.Infinity and n.is_positive:
                return S.NegativeOne**n * S.Infinity
            elif x == S.NegativeInfinity and n.is_positive:
                return S.Infinity
        else:
            # n is a given fixed integer, evaluate into polynomial
            if n.is_negative:
                raise ValueError(
                    "The index n must be nonnegative integer (got %r)" % n)
            else:
                return cls._eval_at_order(n, x, alpha)
예제 #7
0
 def _eval_rewrite_as_binomial(self, n):
     return binomial(2 * n, n) / (n + 1)
예제 #8
0
def nC(n, k=None, replacement=False):
    """Return the number of combinations of ``n`` items taken ``k`` at a time.

    Possible values for ``n``::
        integer - set of length ``n``
        sequence - converted to a multiset internally
        multiset - {element: multiplicity}

    If ``k`` is None then the total of all combinations of length 0
    through the number of items represented in ``n`` will be returned.

    If ``replacement`` is True then a given item can appear more than once
    in the ``k`` items. (For example, for 'ab' sets of 2 would include 'aa',
    'ab', and 'bb'.) The multiplicity of elements in ``n`` is ignored when
    ``replacement`` is True but the total number of elements is considered
    since no element can appear more times than the number of elements in
    ``n``.

    Examples
    ========

    >>> from diofant.functions.combinatorial.numbers import nC
    >>> from diofant.utilities.iterables import multiset_combinations
    >>> nC(3, 2)
    3
    >>> nC('abc', 2)
    3
    >>> nC('aab', 2)
    2

    When ``replacement`` is True, each item can have multiplicity
    equal to the length represented by ``n``:

    >>> nC('aabc', replacement=True)
    35
    >>> [len(list(multiset_combinations('aaaabbbbcccc', i))) for i in range(5)]
    [1, 3, 6, 10, 15]
    >>> sum(_)
    35

    If there are ``k`` items with multiplicities ``m_1, m_2, ..., m_k``
    then the total of all combinations of length 0 hrough ``k`` is the
    product, ``(m_1 + 1)*(m_2 + 1)*...*(m_k + 1)``. When the multiplicity
    of each item is 1 (i.e., k unique items) then there are 2**k
    combinations. For example, if there are 4 unique items, the total number
    of combinations is 16:

    >>> sum(nC(4, i) for i in range(5))
    16

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Combination
    .. [2] http://tinyurl.com/cep849r

    See Also
    ========

    diofant.utilities.iterables.multiset_combinations
    """
    from diofant.functions.combinatorial.factorials import binomial
    from diofant.core.mul import prod

    if isinstance(n, DIOFANT_INTS):
        if k is None:
            if not replacement:
                return 2**n
            return sum(nC(n, i, replacement) for i in range(n + 1))
        if k < 0:
            raise ValueError("k cannot be negative")
        if replacement:
            return binomial(n + k - 1, k)
        return binomial(n, k)
    if isinstance(n, _MultisetHistogram):
        N = n[_N]
        if k is None:
            if not replacement:
                return prod(m + 1 for m in n[_M])
            return sum(nC(n, i, replacement) for i in range(N + 1))
        elif replacement:
            return nC(n[_ITEMS], k, replacement)
        # assert k >= 0
        elif k in (1, N - 1):
            return n[_ITEMS]
        elif k in (0, N):
            return 1
        return _AOP_product(tuple(n[_M]))[k]
    else:
        return nC(_multiset_histogram(n), k, replacement)