Combinatorial functions - Combinatorics

Skip to content
Back to top
View this page
Edit this page

# Combinatorial functions

This module implements some combinatorial functions, as listed below. For a more detailed description, see the relevant docstrings.

Numbers:

- Bell numbers `bell_number()`

- Catalan numbers `catalan_number()`

- Narayana numbers `narayana_number()`

- Euler numbers `euler_number()`

- Eulerian numbers `eulerian_number()`

- Fibonacci numbers `fibonacci()`

- Lucas numbers `lucas_number1()`, `lucas_number2()`

- Stirling numbers `stirling_number1()`, `stirling_number2()`

- Polygonal numbers `polygonal_number()`

Polynomials

- Eulerian polynomial `eulerian_polynomial()`

- Bernoulli polynomials `bernoulli_polynomial()`

Sets:

- Tuples of a multiset `tuples()`, `number_of_tuples()`

- Unordered tuples of a set `unordered_tuples()`, `number_of_unordered_tuples()`

Combinatorial functions from other modules:

- Binomial coefficient `sage.arith.misc.binomial()`

- Factorial `sage.arith.misc.factorial()`

- Falling power `sage.arith.misc.falling_factorial()`

- Rising power `sage.arith.misc.rising_factorial()`

- Number of partitions `sage.combinat.partition.number_of_partitions()`

- Gaussian binomial coefficient `sage.combinat.q_analogues.gaussian_binomial()`

Todo

Add GUAVA commands:

- VandermondeMat

- GrayMat returns a list of all different vectors of length n over the field F, using Gray ordering.

Add commands not in GAP:

- Rencontres numbers (Wikipedia article Rencontres_number)

REFERENCES:

- Wikipedia article Twelvefold_way

AUTHORS:

- David Joyner (2006-07): initial implementation

- William Stein (2006-07): editing of docs and code; many optimizations, refinements, and bug fixes in corner cases

- Jon Hanke (2006-08): added `tuples`

- David Joyner (2006-09): bug fix for combinations, added permutations_iterator, combinations_iterator from Python Cookbook, edited docs.

- David Joyner (2007-11): changed permutations, added hadamard_matrix

- Blair Sutton (2009-01-26): added `bell_polynomial`

- Florent Hivert (2009-02): combinatorial class cleanup

- Bobby Moretti (2009-02): added `fibonacci_sequence` and `fibonacci_xrange`

- Fredrik Johansson (2010-07): fast implementation of `stirling_number2`

- Robert Gerbicz (2010-10): added Bell numbers

- Punarbasu Purkayastha (2012-12): deprecate arrangements, combinations, combinations_iterator, and clean up very old deprecated methods.

- Jeroen Demeyer (2014-10): improved implementation of Dobinski formula for Bell numbers with more accurate error estimates (Issue #17157)

- Thierry Monteil (2015-09-29): the result of `bell_polynomial` must always be a polynomial

- Kei Beauduin (2024-04-06): when univariate, the Bell polynomial is in variable `x0`; extended to complete exponential, partial ordinary and complete ordinary Bell polynomials.

- Kwankyu Lee (2025-01): added Lah numbers

class sage.combinat.combinat.CombinatorialElement(parent, *args, **kwds)

  Bases: `CombinatorialObject`, `Element`

  `CombinatorialElement` is both a `CombinatorialObject` and an `Element`. So it represents a list which is an element of some parent.

  A `CombinatorialElement` subclass also automatically supports the `__classcall__` mechanism.

  Warning

  This class is slowly being deprecated. Use `ClonableList` instead.

  INPUT:

  - `parent` – the `Parent` class for this element

  - `lst` – list or any object that can be converted to a list by calling `list()`

  EXAMPLES:

  Sage

      sage: # needs sage.combinat
      sage: from sage.combinat.combinat import CombinatorialElement
      sage: e = CombinatorialElement(Partitions(6), [3,2,1])
      sage: e == loads(dumps(e))
      True
      sage: parent(e)
      Partitions of the integer 6
      sage: list(e)
      [3, 2, 1]

  Python

      >>> from sage.all import *
      >>> # needs sage.combinat
      >>> from sage.combinat.combinat import CombinatorialElement
      >>> e = CombinatorialElement(Partitions(Integer(6)), [Integer(3),Integer(2),Integer(1)])
      >>> e == loads(dumps(e))
      True
      >>> parent(e)
      Partitions of the integer 6
      >>> list(e)
      [3, 2, 1]

  Check classcalls:

  Sage

      sage: class Foo(CombinatorialElement):                                          # needs sage.combinat
      ....:     @staticmethod
      ....:     def __classcall__(cls, x):
      ....:         return x
      sage: Foo(17)                                                                   # needs sage.combinat
      17

  [Python]

      >>> from sage.all import *
      >>> class Foo(CombinatorialElement):                                          # needs sage.combinat
      ...     @staticmethod
      ...     def __classcall__(cls, x):
      ...         return x
      >>> Foo(Integer(17))                                                                   # needs sage.combinat
      17

class sage.combinat.combinat.CombinatorialObject(l, copy=True)

  Bases: `SageObject`

  CombinatorialObject provides a thin wrapper around a list. The main differences are that __setitem__ is disabled so that CombinatorialObjects are shallowly immutable, and the intention is that they are semantically immutable.

  Because of this, CombinatorialObjects provide a __hash__ function which computes the hash of the string representation of a list and the hash of its parent’s class. Thus, each CombinatorialObject should have a unique string representation.

  See also

  `CombinatorialElement` if you want a combinatorial object which is an element of a parent.

  Warning

  This class is slowly being deprecated. Use `ClonableList` instead.

  INPUT:

  - `l` – list or any object that can be converted to a list by calling `list()`

  - `copy` – boolean (default: `True`); if `False`, then `l` must be a `list`, which is assigned to `self._list` without copying

  EXAMPLES:

  Sage

      sage: c = CombinatorialObject([1,2,3])
      sage: c == loads(dumps(c))
      True
      sage: c._list
      [1, 2, 3]
      sage: c._hash is None
      True

  Python

      >>> from sage.all import *
      >>> c = CombinatorialObject([Integer(1),Integer(2),Integer(3)])
      >>> c == loads(dumps(c))
      True
      >>> c._list
      [1, 2, 3]
      >>> c._hash is None
      True

  For efficiency, you can specify `copy=False` if you know what you are doing:

  Sage

      sage: from sage.combinat.combinat import CombinatorialObject
      sage: x = [3, 2, 1]
      sage: C = CombinatorialObject(x, copy=False)
      sage: C
      [3, 2, 1]
      sage: x[0] = 5
      sage: C
      [5, 2, 1]

  [Python]

      >>> from sage.all import *
      >>> from sage.combinat.combinat import CombinatorialObject
      >>> x = [Integer(3), Integer(2), Integer(1)]
      >>> C = CombinatorialObject(x, copy=False)
      >>> C
      [3, 2, 1]
      >>> x[Integer(0)] = Integer(5)
      >>> C
      [5, 2, 1]

  index(key)

    EXAMPLES:

    Sage

        sage: c = CombinatorialObject([1,2,3])
        sage: c.index(1)
        0
        sage: c.index(3)
        2

    Python

        >>> from sage.all import *
        >>> c = CombinatorialObject([Integer(1),Integer(2),Integer(3)])
        >>> c.index(Integer(1))
        0
        >>> c.index(Integer(3))
        2

sage.combinat.combinat.bell_number(n, algorithm='flint', **options)

  Return the \(n\)-th Bell number.

  This is the number of ways to partition a set of \(n\) elements into pairwise disjoint nonempty subsets.

  INPUT:

  - `n` – positive integer

  - `algorithm` – (default: `'flint'`) any one of the following:

    - `'dobinski'` – use Dobinski’s formula

    - `'flint'` – wrap FLINT’s `arith_bell_number`

    - `'gap'` – wrap GAP’s `Bell`

    - `'mpmath'` – wrap mpmath’s `bell`

  Warning

  When using the mpmath algorithm to compute Bell numbers and you specify `prec`, it can return incorrect results due to low precision. See the examples section.

  EXAMPLES:

  Sage

      sage: # needs sage.libs.flint
      sage: bell_number(10)
      115975
      sage: bell_number(2)
      2
      sage: bell_number(-10)
      Traceback (most recent call last):
      ...
      ArithmeticError: Bell numbers not defined for negative indices
      sage: bell_number(1)
      1
      sage: bell_number(1/3)
      Traceback (most recent call last):
      ...
      TypeError: no conversion of this rational to integer

  Python

      >>> from sage.all import *
      >>> # needs sage.libs.flint
      >>> bell_number(Integer(10))
      115975
      >>> bell_number(Integer(2))
      2
      >>> bell_number(-Integer(10))
      Traceback (most recent call last):
      ...
      ArithmeticError: Bell numbers not defined for negative indices
      >>> bell_number(Integer(1))
      1
      >>> bell_number(Integer(1)/Integer(3))
      Traceback (most recent call last):
      ...
      TypeError: no conversion of this rational to integer

  When using the mpmath algorithm, we are required have mpmath’s precision set to at least \(\log_2(B_n)\) bits. If upon computing the Bell number the first time, we deem the precision too low, we use our guess to (temporarily) raise mpmath’s precision and the Bell number is recomputed.

  Sage

      sage: k = bell_number(30, 'mpmath'); k                                          # needs mpmath
      846749014511809332450147
      sage: k == bell_number(30)                                                      # needs mpmath sage.libs.flint
      True

  [Python]

      >>> from sage.all import *
      >>> k = bell_number(Integer(30), 'mpmath'); k                                          # needs mpmath
      846749014511809332450147
      >>> k == bell_number(Integer(30))                                                      # needs mpmath sage.libs.flint
      True

  If you knows what precision is necessary before computing the Bell number, you can use the `prec` option:

  Sage

      sage: k2 = bell_number(30, 'mpmath', prec=30); k2                               # needs mpmath
      846749014511809332450147
      sage: k == k2                                                                   # needs mpmath
      True

  Python

      >>> from sage.all import *
      >>> k2 = bell_number(Integer(30), 'mpmath', prec=Integer(30)); k2                               # needs mpmath
      846749014511809332450147
      >>> k == k2                                                                   # needs mpmath
      True

  Warning

  Running mpmath with the precision set too low can result in incorrect results:

  Sage

      sage: k = bell_number(30, 'mpmath', prec=15); k                         # needs mpmath
      846749014511809388871680
      sage: k == bell_number(30)                                              # needs mpmath sage.libs.flint
      False

  Python

      >>> from sage.all import *
      >>> k = bell_number(Integer(30), 'mpmath', prec=Integer(15)); k                         # needs mpmath
      846749014511809388871680
      >>> k == bell_number(Integer(30))                                              # needs mpmath sage.libs.flint
      False

  Note

  Let \(B_n\) denote the \(n\)-th Bell number. Dobinski’s formula is:

  \[B_n = e^{-1} \sum_{k=0}^{\infty} \frac{k^n}{k!}.\]

  To show our implementation of Dobinski’s method works, suppose that \(n \geq 5\) and let \(k_0\) be the smallest positive integer such that \(\frac{k_0^n}{k_0!} < 1\). Note that \(k_0 > n\) and \(k_0 \leq 2n\) because we can prove that \(\frac{(2n)^n}{(2n)!} < 1\) by Stirling.

  If \(k > k_0\), then we have \(\frac{k^n}{k!} < \frac{1}{2^{k-k_0}}\). We show this by induction: let \(c_k = \frac{k^n}{k!}\), if \(k > n\) then

  \[\frac{c_{k+1}}{c_k} = \frac{(1+k^{-1})^n}{k+1} < \frac{(1+n^{-1})^n}{n} < \frac{1}{2}.\]

  The last inequality can easily be checked numerically for \(n \geq 5\).

  Using this, we can see that \(\frac{c_k}{c_{k_0}} < \frac{1}{2^{k-k_0}}\) for \(k > k_0 > n\). So summing this it gives that \(\sum_{k=k_0+1}^{\infty} \frac{k^n}{k!} < 1\), and hence

  \[B_n = e^{-1} \left( \sum_{k=0}^{k_0} \frac{k^n}{k!} + E_1 \right) = e^{-1} \sum_{k=0}^{k_0} \frac{k^n}{k!} + E_2,\]

  where \(0 < E_1 < 1\) and \(0 < E_2 < e^{-1}\). Next we have for any \(q > 0\)

  \[\sum_{k=0}^{k_0} \frac{k^n}{k!} = \frac{1}{q} \sum_{k=0}^{k_0} \left\lfloor \frac{q k^n}{k!} \right\rfloor + \frac{E_3}{q}\]

  where \(0 \leq E_3 \leq k_0 + 1 \leq 2n + 1\). Let \(E_4 = \frac{E_3}{q}\) and let \(q = 2n + 1\). We find \(0 \leq E_4 \leq 1\). These two bounds give:

  \[\begin{split}\begin{aligned} B_n & = \frac{e^{-1}}{q} \sum_{k=0}^{k_0} \left\lfloor \frac{q k^n}{k!} \right\rfloor + e^{-1} E_4 + E_2 \\ & = \frac{e^{-1}}{q} \sum_{k=0}^{k_0} \left\lfloor \frac{q k^n}{k!} \right\rfloor + E_5 \end{aligned}\end{split}\]

  where

  \[0 < E_5 = e^{-1} E_4 + E_2 \leq e^{-1} + e^{-1} < \frac{3}{4}.\]

  It follows that

  \[B_n = \left\lceil \frac{e^{-1}}{q} \sum_{k=0}^{k_0} \left\lfloor \frac{q k^n}{k!} \right\rfloor \right\rceil.\]

  Now define

  \[b = \sum_{k=0}^{k_0} \left\lfloor \frac{q k^n}{k!} \right\rfloor.\]

  This \(b\) can be computed exactly using integer arithmetic. To avoid the costly integer division by \(k!\), we collect more terms and do only one division, for example with 3 terms:

  \[\frac{k^n}{k!} + \frac{(k+1)^n}{(k+1)!} + \frac{(k+2)^n}{(k+2)!} = \frac{k^n (k+1)(k+2) + (k+1)^n (k+2) + (k+2)^n}{(k+2)!}\]

  In the implementation, we collect \(\sqrt{n}/2\) terms.

  To actually compute \(B_n\) from \(b\), we let \(p = \lfloor \log_2(b) \rfloor + 1\) such that \(b < 2^p\) and we compute with \(p\) bits of precision. This implies that \(b\) (and \(q < b\)) can be represented exactly.

  We compute \(\frac{e^{-1}}{q} b\), rounding down, and we must have an absolute error of at most \(1/4\) (given that \(E_5 < 3/4\)). This means that we need a relative error of at most

  \[\frac{e q}{4 b} > \frac{(e q)/4}{2^p} > \frac{7}{2^p}\]

  (assuming \(n \geq 5\)). With a precision of \(p\) bits and rounding down, every rounding has a relative error of at most \(2^{1-p} = 2/2^p\). Since we do 3 roundings (\(b\) and \(q\) do not require rounding), we get a relative error of at most \(6/2^p\). All this implies that the precision of \(p\) bits is sufficient.

  REFERENCES:

  - Wikipedia article Bell_number

  - http://fredrik-j.blogspot.com/2009/03/computing-generalized-bell-numbers.html

  - http://mathworld.wolfram.com/DobinskisFormula.html

sage.combinat.combinat.bell_polynomial(n, k=None, ordinary=False)

  Return the partial (or complete) exponential (or ordinary) Bell polynomial.

  The partial exponential Bell polynomial is defined by the formula

  \[\begin{split}B_{n,k}(x_0, x_1, \ldots, x_{n-k}) = \sum_{\substack{j_0 + \ldots + j_{n-k} = k \\ 1 j_0 + \ldots + (n-k+1) j_{n-k} = n}} \frac{n!}{j_0!j_1!\cdots j_{n-k}!} \left(\frac{x_0}{(0+1)!}\right)^{j_0} \left(\frac{x_1}{(1+1)!}\right)^{j_1} \cdots \left(\frac{x_{n-k}}{(n-k+1)!}\right)^{j_{n-k}}.\end{split}\]

  The complete exponential Bell Polynomial is defined as

  \[B_n(x_0, x_1, \ldots, x_{n-k}) = \sum_{k=0}^n B_{n,k}(x_0, x_1, \ldots, x_{n-k}).\]

  The ordinary variant of the partial Bell polynomial is defined by

  \[\begin{split}\hat B_{n,k}(x_0, x_1, \ldots, x_{n-k}) = \sum_{\substack{j_0 + \ldots + j_{n-k} = k \\ 1 j_0 + \ldots + (n-k+1) j_{n-k} = n}} \binom{k}{j_0, j_1, \ldots, j_{n-k}} x_0^{j_0} x_1^{j_1} \cdots x_{n-k}^{j_{n-k}},\end{split}\]

  where we have used the multinomial coefficient. The complete version has the same definition as its exponential counterpart.

  If we define \(f(z) = \sum_{n=1}^\infty x_{n-1} z^n/n!\) then these are alternative definitions for exponential Bell polynomials

  \[\begin{split}\begin{aligned} \exp(f(z)) & = \sum_{n=0}^\infty B_n(x_0, \ldots, x_{n-1}) \frac{z^n}{n!}, \\ \frac{f(z)^k}{k!} & = \sum_{n=k}^\infty B_{n, k}(x_0, \ldots, x_{n-k}) \frac{z^n}{n!}. \end{aligned}\end{split}\]

  Defining \(g(z) = \sum_{n=1}^\infty x_{n-1} z^n\), we have the analogous alternative definitions

  \[\begin{split}\begin{aligned} \frac1{1-f(z)} & = \sum_{n=0}^\infty \hat B_n(x_0, \ldots, x_{n-1}) z^n, \\ f(z)^k & = \sum_{n=k}^\infty \hat B_{n, k}(x_0, \ldots, x_{n-k}) z^n. \end{aligned}\end{split}\]

  INPUT:

  - `k` – (optional) if specified, returns the partial Bell polynomial, otherwise returns the complete Bell polynomial

  - `ordinary` – boolean (default: `False`); if `True`, returns the (partial) ordinary Bell polynomial, otherwise returns the (partial) exponential Bell polynomial

  EXAMPLES:

  The complete and partial Bell polynomials:

  Sage

      sage: # needs sage.combinat
      sage: bell_polynomial(3)
      x0^3 + 3*x0*x1 + x2
      sage: bell_polynomial(4)
      x0^4 + 6*x0^2*x1 + 3*x1^2 + 4*x0*x2 + x3
      sage: bell_polynomial(6, 3)
      15*x1^3 + 60*x0*x1*x2 + 15*x0^2*x3
      sage: bell_polynomial(6, 6)
      x0^6

  Python

      >>> from sage.all import *
      >>> # needs sage.combinat
      >>> bell_polynomial(Integer(3))
      x0^3 + 3*x0*x1 + x2
      >>> bell_polynomial(Integer(4))
      x0^4 + 6*x0^2*x1 + 3*x1^2 + 4*x0*x2 + x3
      >>> bell_polynomial(Integer(6), Integer(3))
      15*x1^3 + 60*x0*x1*x2 + 15*x0^2*x3
      >>> bell_polynomial(Integer(6), Integer(6))
      x0^6

  The ordinary variants are:

  Sage

      sage: # needs sage.combinat sage.arith
      sage: bell_polynomial(3, ordinary=True)
      x0^3 + 2*x0*x1 + x2
      sage: bell_polynomial(4, ordinary=True)
      x0^4 + 3*x0^2*x1 + x1^2 + 2*x0*x2 + x3
      sage: bell_polynomial(6, 3, True)
      x1^3 + 6*x0*x1*x2 + 3*x0^2*x3
      sage: bell_polynomial(6, 6, True)
      x0^6

  [Python]

      >>> from sage.all import *
      >>> # needs sage.combinat sage.arith
      >>> bell_polynomial(Integer(3), ordinary=True)
      x0^3 + 2*x0*x1 + x2
      >>> bell_polynomial(Integer(4), ordinary=True)
      x0^4 + 3*x0^2*x1 + x1^2 + 2*x0*x2 + x3
      >>> bell_polynomial(Integer(6), Integer(3), True)
      x1^3 + 6*x0*x1*x2 + 3*x0^2*x3
      >>> bell_polynomial(Integer(6), Integer(6), True)
      x0^6

  We verify the alternative definition of the different Bell polynomials using the functions \(f\) and \(g\) given above:

  Sage

      sage: # needs sage.combinat sage.arith
      sage: n = 6 # positive integer
      sage: k = 4 # positive integer
      sage: R.<x> = InfinitePolynomialRing(QQ)
      sage: PR = PolynomialRing(QQ, 'x', n)
      sage: d = {x[i]: PR.gen(i) for i in range(n)}  # substitution dictionary
      sage: L.<z> = LazyPowerSeriesRing(R)
      sage: f = L(lambda i: x[i-1]/factorial(i), valuation=1)
      sage: all(exp(f)[i].subs(d) * factorial(i) == bell_polynomial(i) for i in range(n+1))
      True
      sage: all((f^k/factorial(k))[i].subs(d) * factorial(i) == bell_polynomial(i, k) for i in range(k, n+k))
      True
      sage: g = L(lambda i: x[i-1], valuation=1)
      sage: all((1/(1-g))[i].subs(d) == bell_polynomial(i, ordinary=True) for i in range(n+1))
      True
      sage: all((g^k)[i].subs(d) == bell_polynomial(i, k, True) for i in range(k, n+k))
      True

  Python

      >>> from sage.all import *
      >>> # needs sage.combinat sage.arith
      >>> n = Integer(6) # positive integer
      >>> k = Integer(4) # positive integer
      >>> R = InfinitePolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
      >>> PR = PolynomialRing(QQ, 'x', n)
      >>> d = {x[i]: PR.gen(i) for i in range(n)}  # substitution dictionary
      >>> L = LazyPowerSeriesRing(R, names=('z',)); (z,) = L._first_ngens(1)
      >>> f = L(lambda i: x[i-Integer(1)]/factorial(i), valuation=Integer(1))
      >>> all(exp(f)[i].subs(d) * factorial(i) == bell_polynomial(i) for i in range(n+Integer(1)))
      True
      >>> all((f**k/factorial(k))[i].subs(d) * factorial(i) == bell_polynomial(i, k) for i in range(k, n+k))
      True
      >>> g = L(lambda i: x[i-Integer(1)], valuation=Integer(1))
      >>> all((Integer(1)/(Integer(1)-g))[i].subs(d) == bell_polynomial(i, ordinary=True) for i in range(n+Integer(1)))
      True
      >>> all((g**k)[i].subs(d) == bell_polynomial(i, k, True) for i in range(k, n+k))
      True

  REFERENCES:

  - [Bel1927]

  - [Com1974]

sage.combinat.combinat.bernoulli_polynomial(x, n)

  Return the `n`-th Bernoulli polynomial evaluated at `x`.

  The generating function for the Bernoulli polynomials is

  \[\frac{t e^{xt}}{e^t-1}= \sum_{n=0}^\infty B_n(x) \frac{t^n}{n!},\]

  and they are given directly by

  \[B_n(x) = \sum_{i=0}^n \binom{n}{i}B_{n-i}x^i.\]

  One has \(B_n(x) = - n\zeta(1 - n,x)\), where \(\zeta(s,x)\) is the Hurwitz zeta function. Thus, in a certain sense, the Hurwitz zeta function generalizes the Bernoulli polynomials to non-integer values of \(n\).

  EXAMPLES:

  Sage

      sage: # needs sage.libs.flint
      sage: y = QQ['y'].0
      sage: bernoulli_polynomial(y, 5)
      y^5 - 5/2*y^4 + 5/3*y^3 - 1/6*y
      sage: bernoulli_polynomial(y, 5)(12)
      199870
      sage: bernoulli_polynomial(12, 5)
      199870
      sage: bernoulli_polynomial(y^2 + 1, 5)
      y^10 + 5/2*y^8 + 5/3*y^6 - 1/6*y^2
      sage: P.<t> = ZZ[]
      sage: p = bernoulli_polynomial(t, 6)
      sage: p.parent()
      Univariate Polynomial Ring in t over Rational Field

  Python

      >>> from sage.all import *
      >>> # needs sage.libs.flint
      >>> y = QQ['y'].gen(0)
      >>> bernoulli_polynomial(y, Integer(5))
      y^5 - 5/2*y^4 + 5/3*y^3 - 1/6*y
      >>> bernoulli_polynomial(y, Integer(5))(Integer(12))
      199870
      >>> bernoulli_polynomial(Integer(12), Integer(5))
      199870
      >>> bernoulli_polynomial(y**Integer(2) + Integer(1), Integer(5))
      y^10 + 5/2*y^8 + 5/3*y^6 - 1/6*y^2
      >>> P = ZZ['t']; (t,) = P._first_ngens(1)
      >>> p = bernoulli_polynomial(t, Integer(6))
      >>> p.parent()
      Univariate Polynomial Ring in t over Rational Field

  We verify an instance of the formula which is the origin of the Bernoulli polynomials (and numbers):

  Sage

      sage: power_sum = sum(k^4 for k in range(10))
      sage: 5*power_sum == bernoulli_polynomial(10, 5) - bernoulli(5)                 # needs sage.libs.flint
      True

  [Python]

      >>> from sage.all import *
      >>> power_sum = sum(k**Integer(4) for k in range(Integer(10)))
      >>> Integer(5)*power_sum == bernoulli_polynomial(Integer(10), Integer(5)) - bernoulli(Integer(5))                 # needs sage.libs.flint
      True

  REFERENCES:

  - Wikipedia article Bernoulli_polynomials

sage.combinat.combinat.catalan_number(n)

  Return the \(n\)-th Catalan number.

  The \(n\)-th Catalan number is given directly in terms of binomial coefficients by

  \[C_n = \frac{1}{n+1}\binom{2n}{n} = \frac{(2n)!}{(n+1)!\,n!} \qquad\mbox{ for }\quad n\ge 0.\]

  Consider the set \(S = \{ 1, ..., n \}\). A noncrossing partition of \(S\) is a partition in which no two blocks “cross” each other, i.e., if \(a\) and \(b\) belong to one block and \(x\) and \(y\) to another, they are not arranged in the order \(axby\). \(C_n\) is the number of noncrossing partitions of the set \(S\). There are many other interpretations (see REFERENCES).

  When \(n=-1\), this function returns the limit value \(-1/2\). For other \(n<0\) it returns \(0\).

  INPUT:

  - `n` – integer

  OUTPUT: integer

  EXAMPLES:

  Sage

      sage: [catalan_number(i) for i in range(7)]
      [1, 1, 2, 5, 14, 42, 132]
      sage: x = (QQ[['x']].0).O(8)
      sage: (-1/2)*sqrt(1 - 4*x)
      -1/2 + x + x^2 + 2*x^3 + 5*x^4 + 14*x^5 + 42*x^6 + 132*x^7 + O(x^8)
      sage: [catalan_number(i) for i in range(-7,7)]
      [0, 0, 0, 0, 0, 0, -1/2, 1, 1, 2, 5, 14, 42, 132]
      sage: [catalan_number(n).mod(2) for n in range(16)]
      [1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1]

  Python

      >>> from sage.all import *
      >>> [catalan_number(i) for i in range(Integer(7))]
      [1, 1, 2, 5, 14, 42, 132]
      >>> x = (QQ[['x']].gen(0)).O(Integer(8))
      >>> (-Integer(1)/Integer(2))*sqrt(Integer(1) - Integer(4)*x)
      -1/2 + x + x^2 + 2*x^3 + 5*x^4 + 14*x^5 + 42*x^6 + 132*x^7 + O(x^8)
      >>> [catalan_number(i) for i in range(-Integer(7),Integer(7))]
      [0, 0, 0, 0, 0, 0, -1/2, 1, 1, 2, 5, 14, 42, 132]
      >>> [catalan_number(n).mod(Integer(2)) for n in range(Integer(16))]
      [1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1]

  REFERENCES:

  - Wikipedia article Catalan_number

  - http://www-history.mcs.st-andrews.ac.uk/~history/Miscellaneous/CatalanNumbers/catalan.html

sage.combinat.combinat.euler_number(n, algorithm='flint')

  Return the \(n\)-th Euler number.

  INPUT:

  - `n` – positive integer

  - `algorithm` – (default: `'flint'`) any one of the following:

    - `'maxima'` – wraps Maxima’s `euler`

    - `'flint'` – wrap FLINT’s `arith_euler_number`

  EXAMPLES:

  Sage

      sage: [euler_number(i) for i in range(10)]                                      # needs sage.libs.flint
      [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0]
      sage: x = PowerSeriesRing(QQ, 'x').gen().O(10)
      sage: 2/(exp(x)+exp(-x))
      1 - 1/2*x^2 + 5/24*x^4 - 61/720*x^6 + 277/8064*x^8 + O(x^10)
      sage: [euler_number(i)/factorial(i) for i in range(11)]                         # needs sage.libs.flint
      [1, 0, -1/2, 0, 5/24, 0, -61/720, 0, 277/8064, 0, -50521/3628800]
      sage: euler_number(-1)
      Traceback (most recent call last):
      ...
      ValueError: n (=-1) must be a nonnegative integer

  Python

      >>> from sage.all import *
      >>> [euler_number(i) for i in range(Integer(10))]                                      # needs sage.libs.flint
      [1, 0, -1, 0, 5, 0, -61, 0, 1385, 0]
      >>> x = PowerSeriesRing(QQ, 'x').gen().O(Integer(10))
      >>> Integer(2)/(exp(x)+exp(-x))
      1 - 1/2*x^2 + 5/24*x^4 - 61/720*x^6 + 277/8064*x^8 + O(x^10)
      >>> [euler_number(i)/factorial(i) for i in range(Integer(11))]                         # needs sage.libs.flint
      [1, 0, -1/2, 0, 5/24, 0, -61/720, 0, 277/8064, 0, -50521/3628800]
      >>> euler_number(-Integer(1))
      Traceback (most recent call last):
      ...
      ValueError: n (=-1) must be a nonnegative integer

  REFERENCES:

  - Wikipedia article Euler_number

sage.combinat.combinat.eulerian_number(k, algorithm='recursive')

  Return the Eulerian number of index `(n, k)`.

  This is the coefficient of \(t^k\) in the Eulerian polynomial \(A_n(t)\).

  INPUT:

  - `n` – integer

  - `k` – integer between `0` and `n - 1`

  - `algorithm` – `'recursive'` (default) or `'formula'`

  OUTPUT: integer

  See also

  `eulerian_polynomial()`

  EXAMPLES:

  Sage

      sage: from sage.combinat.combinat import eulerian_number
      sage: [eulerian_number(5,i) for i in range(5)]
      [1, 26, 66, 26, 1]

  Python

      >>> from sage.all import *
      >>> from sage.combinat.combinat import eulerian_number
      >>> [eulerian_number(Integer(5),i) for i in range(Integer(5))]
      [1, 26, 66, 26, 1]

sage.combinat.combinat.eulerian_polynomial(algorithm='derivative')

  Return the Eulerian polynomial of index `n`.

  This is the generating polynomial counting permutations in the symmetric group \(S_n\) according to their number of descents.

  INPUT:

  - `n` – integer

  - `algorithm` – `'derivative'` (default) or `'coeffs'`

  OUTPUT: polynomial in one variable `t`

  See also

  `eulerian_number()`

  EXAMPLES:

  Sage

      sage: from sage.combinat.combinat import eulerian_polynomial
      sage: eulerian_polynomial(5)
      t^4 + 26*t^3 + 66*t^2 + 26*t + 1

  Python

      >>> from sage.all import *
      >>> from sage.combinat.combinat import eulerian_polynomial
      >>> eulerian_polynomial(Integer(5))
      t^4 + 26*t^3 + 66*t^2 + 26*t + 1

  REFERENCES:

  - Wikipedia article Eulerian_number

sage.combinat.combinat.fibonacci(n, algorithm='pari')

  Return the \(n\)-th Fibonacci number.

  The Fibonacci sequence \(F_n\) is defined by the initial conditions \(F_1 = F_2 = 1\) and the recurrence relation \(F_{n+2} = F_{n+1} + F_n\). For negative \(n\) we define \(F_n = (-1)^{n+1}F_{-n}\), which is consistent with the recurrence relation.

  INPUT:

  - `algorithm` – string; one of

    - `'pari'` – (default) use the PARI C library’s pari:fibo function

    - `'gap'` – use GAP’s Fibonacci function

  Note

  PARI is tens to hundreds of times faster than GAP here. Moreover, PARI works for every large input whereas GAP does not.

  EXAMPLES:

  Sage

      sage: fibonacci(10)                                                             # needs sage.libs.pari
      55
      sage: fibonacci(10, algorithm='gap')                                            # needs sage.libs.gap
      55

  Python

      >>> from sage.all import *
      >>> fibonacci(Integer(10))                                                             # needs sage.libs.pari
      55
      >>> fibonacci(Integer(10), algorithm='gap')                                            # needs sage.libs.gap
      55

  Sage

      sage: fibonacci(-100)                                                           # needs sage.libs.pari
      -354224848179261915075
      sage: fibonacci(100)                                                            # needs sage.libs.pari
      354224848179261915075

  [Python]

      >>> from sage.all import *
      >>> fibonacci(-Integer(100))                                                           # needs sage.libs.pari
      -354224848179261915075
      >>> fibonacci(Integer(100))                                                            # needs sage.libs.pari
      354224848179261915075

  Sage

      sage: fibonacci(0)                                                              # needs sage.libs.pari
      0
      sage: fibonacci(1/2)
      Traceback (most recent call last):
      ...
      TypeError: no conversion of this rational to integer

  Python

      >>> from sage.all import *
      >>> fibonacci(Integer(0))                                                              # needs sage.libs.pari
      0
      >>> fibonacci(Integer(1)/Integer(2))
      Traceback (most recent call last):
      ...
      TypeError: no conversion of this rational to integer

sage.combinat.combinat.fibonacci_sequence(start, stop=None, algorithm=None)

  Return an iterator over the Fibonacci sequence, for all fibonacci numbers \(f_n\) from `n = start` up to (but not including) `n = stop`

  INPUT:

  - `start` – starting value

  - `stop` – stopping value

  - `algorithm` – (default: `None`) passed on to fibonacci function (or not passed on if `None`, i.e., use the default)

  EXAMPLES:

  Sage

      sage: fibs = [i for i in fibonacci_sequence(10, 20)]; fibs                      # needs sage.libs.pari
      [55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]

  Python

      >>> from sage.all import *
      >>> fibs = [i for i in fibonacci_sequence(Integer(10), Integer(20))]; fibs                      # needs sage.libs.pari
      [55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]

  Sage

      sage: sum([i for i in fibonacci_sequence(100, 110)])                            # needs sage.libs.pari
      69919376923075308730013

  [Python]

      >>> from sage.all import *
      >>> sum([i for i in fibonacci_sequence(Integer(100), Integer(110))])                            # needs sage.libs.pari
      69919376923075308730013

  See also

  `fibonacci_xrange()`

sage.combinat.combinat.fibonacci_xrange(start, stop=None, algorithm='pari')

  Return an iterator over all of the Fibonacci numbers in the given range, including `f_n = start` up to, but not including, `f_n = stop`.

  EXAMPLES:

  Sage

      sage: fibs_in_some_range = [i for i in fibonacci_xrange(10^7, 10^8)]            # needs sage.libs.pari
      sage: len(fibs_in_some_range)                                                   # needs sage.libs.pari
      4
      sage: fibs_in_some_range                                                        # needs sage.libs.pari
      [14930352, 24157817, 39088169, 63245986]

  Python

      >>> from sage.all import *
      >>> fibs_in_some_range = [i for i in fibonacci_xrange(Integer(10)**Integer(7), Integer(10)**Integer(8))]            # needs sage.libs.pari
      >>> len(fibs_in_some_range)                                                   # needs sage.libs.pari
      4
      >>> fibs_in_some_range                                                        # needs sage.libs.pari
      [14930352, 24157817, 39088169, 63245986]

  Sage

      sage: fibs = [i for i in fibonacci_xrange(10, 100)]; fibs                       # needs sage.libs.pari
      [13, 21, 34, 55, 89]

  [Python]

      >>> from sage.all import *
      >>> fibs = [i for i in fibonacci_xrange(Integer(10), Integer(100))]; fibs                       # needs sage.libs.pari
      [13, 21, 34, 55, 89]

  Sage

      sage: list(fibonacci_xrange(13, 34))                                            # needs sage.libs.pari
      [13, 21]

  Python

      >>> from sage.all import *
      >>> list(fibonacci_xrange(Integer(13), Integer(34)))                                            # needs sage.libs.pari
      [13, 21]

  A solution to the second Project Euler problem:

  Sage

      sage: sum([i for i in fibonacci_xrange(10^6) if is_even(i)])                    # needs sage.libs.pari
      1089154

  [Python]

      >>> from sage.all import *
      >>> sum([i for i in fibonacci_xrange(Integer(10)**Integer(6)) if is_even(i)])                    # needs sage.libs.pari
      1089154

  See also

  `fibonacci_sequence()`

sage.combinat.combinat.lah_number(n, k)

  Return the Lah number \(L(n,k)\)

  This is the number of ways to partition a set of \(n\) elements into \(k\) pairwise disjoint nonempty linearly-ordered subsets.

  This is also called the Stirling number of the third kind.

  See Wikipedia article Lah_number.

  INPUT:

  - `n` – nonnegative integer

  - `k` – nonnegative integer

  EXAMPLES:

  Sage

      sage: from sage.combinat.combinat import lah_number
      sage: lah_number(50, 30)
      3242322638238907670866645288893161825894400000

  Python

      >>> from sage.all import *
      >>> from sage.combinat.combinat import lah_number
      >>> lah_number(Integer(50), Integer(30))
      3242322638238907670866645288893161825894400000

  We verify a well-known identity:

  Sage

      sage: S1 = stirling_number1; S2 = stirling_number2
      sage: all(lah_number(n, k) == sum(S1(n, j) * S2(j, k) for j in [k..n])
      ....:     for n in range(10) for k in range(10))
      True

  [Python]

      >>> from sage.all import *
      >>> S1 = stirling_number1; S2 = stirling_number2
      >>> all(lah_number(n, k) == sum(S1(n, j) * S2(j, k) for j in (ellipsis_range(k,Ellipsis,n)))
      ...     for n in range(Integer(10)) for k in range(Integer(10)))
      True

sage.combinat.combinat.lucas_number1(n, P, Q)

  Return the \(n\)-th Lucas number “of the first kind” (this is not standard terminology). The Lucas sequence \(L^{(1)}_n\) is defined by the initial conditions \(L^{(1)}_1 = 0\), \(L^{(1)}_2 = 1\) and the recurrence relation \(L^{(1)}_{n+2} = P \cdot L^{(1)}_{n+1} - Q \cdot L^{(1)}_n\).

  Wraps GAP’s `Lucas(...)[1]`.

  \(P=1\), \(Q=-1\) gives the Fibonacci sequence.

  INPUT:

  - `n` – integer

  - `P`, `Q` – integer or rational numbers

  OUTPUT: integer or rational number

  EXAMPLES:

  Sage

      sage: # needs sage.libs.gap
      sage: lucas_number1(5,1,-1)
      5
      sage: lucas_number1(6,1,-1)
      8
      sage: lucas_number1(7,1,-1)
      13
      sage: lucas_number1(7,1,-2)
      43
      sage: lucas_number1(5,2,3/5)
      229/25
      sage: lucas_number1(5,2,1.5)
      1/4

  Python

      >>> from sage.all import *
      >>> # needs sage.libs.gap
      >>> lucas_number1(Integer(5),Integer(1),-Integer(1))
      5
      >>> lucas_number1(Integer(6),Integer(1),-Integer(1))
      8
      >>> lucas_number1(Integer(7),Integer(1),-Integer(1))
      13
      >>> lucas_number1(Integer(7),Integer(1),-Integer(2))
      43
      >>> lucas_number1(Integer(5),Integer(2),Integer(3)/Integer(5))
      229/25
      >>> lucas_number1(Integer(5),Integer(2),RealNumber('1.5'))
      1/4

  There was a conjecture that the sequence \(L_n\) defined by \(L_{n+2} = L_{n+1} + L_n\), \(L_1=1\), \(L_2=3\), has the property that \(n\) prime implies that \(L_n\) is prime.

  Sage

      sage: def lucas(n):
      ....:     return Integer((5/2)*lucas_number1(n,1,-1) + (1/2)*lucas_number2(n,1,-1))
      sage: [[lucas(n), is_prime(lucas(n)), n+1, is_prime(n+1)] for n in range(15)]   # needs sage.libs.gap
      [[1, False, 1, False],
       [3, True, 2, True],
       [4, False, 3, True],
       [7, True, 4, False],
       [11, True, 5, True],
       [18, False, 6, False],
       [29, True, 7, True],
       [47, True, 8, False],
       [76, False, 9, False],
       [123, False, 10, False],
       [199, True, 11, True],
       [322, False, 12, False],
       [521, True, 13, True],
       [843, False, 14, False],
       [1364, False, 15, False]]

  [Python]

      >>> from sage.all import *
      >>> def lucas(n):
      ...     return Integer((Integer(5)/Integer(2))*lucas_number1(n,Integer(1),-Integer(1)) + (Integer(1)/Integer(2))*lucas_number2(n,Integer(1),-Integer(1)))
      >>> [[lucas(n), is_prime(lucas(n)), n+Integer(1), is_prime(n+Integer(1))] for n in range(Integer(15))]   # needs sage.libs.gap
      [[1, False, 1, False],
       [3, True, 2, True],
       [4, False, 3, True],
       [7, True, 4, False],
       [11, True, 5, True],
       [18, False, 6, False],
       [29, True, 7, True],
       [47, True, 8, False],
       [76, False, 9, False],
       [123, False, 10, False],
       [199, True, 11, True],
       [322, False, 12, False],
       [521, True, 13, True],
       [843, False, 14, False],
       [1364, False, 15, False]]

  Can you use Sage to find a counterexample to the conjecture?

sage.combinat.combinat.lucas_number2(n, P, Q)

  Return the \(n\)-th Lucas number “of the second kind” (this is not standard terminology). The Lucas sequence \(L^{(2)}_n\) is defined by the initial conditions \(L^{(2)}_1 = 2\), \(L^{(2)}_2 = P\) and the recurrence relation \(L^{(2)}_{n+2} = P \cdot L^{(2)}_{n+1} - Q \cdot L^{(2)}_n\).

  INPUT:

  - `n` – integer

  - `P`, `Q` – integer or rational numbers

  OUTPUT: integer or rational number

  EXAMPLES:

  Sage

      sage: [lucas_number2(i,1,-1) for i in range(10)]                                # needs sage.libs.gap
      [2, 1, 3, 4, 7, 11, 18, 29, 47, 76]
      sage: [fibonacci(i-1)+fibonacci(i+1) for i in range(10)]                        # needs sage.libs.pari
      [2, 1, 3, 4, 7, 11, 18, 29, 47, 76]

  Python

      >>> from sage.all import *
      >>> [lucas_number2(i,Integer(1),-Integer(1)) for i in range(Integer(10))]                                # needs sage.libs.gap
      [2, 1, 3, 4, 7, 11, 18, 29, 47, 76]
      >>> [fibonacci(i-Integer(1))+fibonacci(i+Integer(1)) for i in range(Integer(10))]                        # needs sage.libs.pari
      [2, 1, 3, 4, 7, 11, 18, 29, 47, 76]

  Sage

      sage: # needs sage.libs.gap
      sage: n = lucas_number2(5,2,3); n
      2
      sage: type(n)
      <class 'sage.rings.integer.Integer'>
      sage: n = lucas_number2(5,2,-3/9); n
      418/9
      sage: type(n)
      <class 'sage.rings.rational.Rational'>

  [Python]

      >>> from sage.all import *
      >>> # needs sage.libs.gap
      >>> n = lucas_number2(Integer(5),Integer(2),Integer(3)); n
      2
      >>> type(n)
      <class 'sage.rings.integer.Integer'>
      >>> n = lucas_number2(Integer(5),Integer(2),-Integer(3)/Integer(9)); n
      418/9
      >>> type(n)
      <class 'sage.rings.rational.Rational'>

  The case \(P=1\), \(Q=-1\) is the Lucas sequence in Brualdi’s Introductory Combinatorics, 4th ed., Prentice-Hall, 2004:

  Sage

      sage: [lucas_number2(n,1,-1) for n in range(10)]                                # needs sage.libs.gap
      [2, 1, 3, 4, 7, 11, 18, 29, 47, 76]

  Python

      >>> from sage.all import *
      >>> [lucas_number2(n,Integer(1),-Integer(1)) for n in range(Integer(10))]                                # needs sage.libs.gap
      [2, 1, 3, 4, 7, 11, 18, 29, 47, 76]

sage.combinat.combinat.narayana_number(n, k)

  Return the Narayana number of index `(n, k)`.

  For every integer \(n \geq 1\), the sum of Narayana numbers \(\sum_k N_{n,k}\) is the Catalan number \(C_n\).

  INPUT:

  - `n` – integer

  - `k` – integer between \(0\) and \(n - 1\)

  OUTPUT: integer

  EXAMPLES:

  Sage

      sage: from sage.combinat.combinat import narayana_number
      sage: [narayana_number(3, i) for i in range(3)]
      [1, 3, 1]
      sage: sum(narayana_number(7,i) for i in range(7)) == catalan_number(7)
      True

  Python

      >>> from sage.all import *
      >>> from sage.combinat.combinat import narayana_number
      >>> [narayana_number(Integer(3), i) for i in range(Integer(3))]
      [1, 3, 1]
      >>> sum(narayana_number(Integer(7),i) for i in range(Integer(7))) == catalan_number(Integer(7))
      True

  REFERENCES:

  - Wikipedia article Narayana_number

sage.combinat.combinat.number_of_tuples(S, k, algorithm='naive')

  Return the size of `tuples(S, k)` for a set \(S\).

  \(S\) is first converted to a set. Hence, unlike `tuples()`, this method removes redundant entries from \(S\).

  INPUT:

  - `S` – the base set

  - `k` – the length of the tuples

  - `algorithm` – can be one of the following:

    - `'naive'` – (default) use the naive counting \(|S|^k\)

    - `'gap'` – wraps GAP’s `NrTuples`

  Warning

  When using `algorithm='gap'`, `S` must be a list of objects that have string representations that can be interpreted by the GAP interpreter. If `S` consists of at all complicated Sage objects, this function might not do what you expect.

  EXAMPLES:

  Sage

      sage: S = [1,2,3,4,5]
      sage: number_of_tuples(S,2)
      25
      sage: number_of_tuples(S,2, algorithm='gap')                                    # needs sage.libs.gap
      25
      sage: S = [1,1,2,3,4,5]
      sage: number_of_tuples(S,2)
      25
      sage: number_of_tuples(S,2, algorithm='gap')                                    # needs sage.libs.gap
      25
      sage: number_of_tuples(S,0)
      1
      sage: number_of_tuples(S,0, algorithm='gap')                                    # needs sage.libs.gap
      1

  Python

      >>> from sage.all import *
      >>> S = [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]
      >>> number_of_tuples(S,Integer(2))
      25
      >>> number_of_tuples(S,Integer(2), algorithm='gap')                                    # needs sage.libs.gap
      25
      >>> S = [Integer(1),Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]
      >>> number_of_tuples(S,Integer(2))
      25
      >>> number_of_tuples(S,Integer(2), algorithm='gap')                                    # needs sage.libs.gap
      25
      >>> number_of_tuples(S,Integer(0))
      1
      >>> number_of_tuples(S,Integer(0), algorithm='gap')                                    # needs sage.libs.gap
      1

sage.combinat.combinat.number_of_unordered_tuples(S, k, algorithm='naive')

  Return the size of `unordered_tuples(S, k)` when \(S\) is a set.

  INPUT:

  - `S` – the base set

  - `k` – the length of the tuples

  - `algorithm` – can be one of the following:

    - `'naive'` – (default) use the naive counting \(\binom{|S|+k-1}{k}\)

    - `'gap'` – wraps GAP’s `NrUnorderedTuples`

  Warning

  When using `algorithm='gap'`, `S` must be a list of objects that have string representations that can be interpreted by the GAP interpreter. If `S` consists of at all complicated Sage objects, this function might not do what you expect.

  EXAMPLES:

  Sage

      sage: S = [1,2,3,4,5]
      sage: number_of_unordered_tuples(S,2)
      15
      sage: number_of_unordered_tuples(S,2, algorithm='gap')                          # needs sage.libs.gap
      15
      sage: S = [1,1,2,3,4,5]
      sage: number_of_unordered_tuples(S,2)
      15
      sage: number_of_unordered_tuples(S,2, algorithm='gap')                          # needs sage.libs.gap
      15
      sage: number_of_unordered_tuples(S,0)
      1
      sage: number_of_unordered_tuples(S,0, algorithm='gap')                          # needs sage.libs.gap
      1

  Python

      >>> from sage.all import *
      >>> S = [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]
      >>> number_of_unordered_tuples(S,Integer(2))
      15
      >>> number_of_unordered_tuples(S,Integer(2), algorithm='gap')                          # needs sage.libs.gap
      15
      >>> S = [Integer(1),Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]
      >>> number_of_unordered_tuples(S,Integer(2))
      15
      >>> number_of_unordered_tuples(S,Integer(2), algorithm='gap')                          # needs sage.libs.gap
      15
      >>> number_of_unordered_tuples(S,Integer(0))
      1
      >>> number_of_unordered_tuples(S,Integer(0), algorithm='gap')                          # needs sage.libs.gap
      1

sage.combinat.combinat.polygonal_number(s, n)

  Return the \(n\)-th \(s\)-gonal number.

  Polygonal sequences are represented by dots forming a regular polygon. Two famous sequences are the triangular numbers (3rd column of Pascal’s Triangle) and the square numbers. The \(n\)-th term in a polygonal sequence is defined by

  \[P(s, n) = \frac{n^2(s-2) - n(s-4)}{2},\]

  where \(s\) is the number of sides of the polygon.

  INPUT:

  - `s` – integer greater than 1; the number of sides of the polygon

  - `n` – integer; the index of the returned \(s\)-gonal number

  OUTPUT: integer

  EXAMPLES:

  The triangular numbers:

  Sage

      sage: [polygonal_number(3, n) for n in range(10)]
      [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

      sage: [polygonal_number(3, n) for n in range(-10, 0)]
      [45, 36, 28, 21, 15, 10, 6, 3, 1, 0]

  Python

      >>> from sage.all import *
      >>> [polygonal_number(Integer(3), n) for n in range(Integer(10))]
      [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

      >>> [polygonal_number(Integer(3), n) for n in range(-Integer(10), Integer(0))]
      [45, 36, 28, 21, 15, 10, 6, 3, 1, 0]

  The square numbers:

  Sage

      sage: [polygonal_number(4, n) for n in range(10)]
      [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

  [Python]

      >>> from sage.all import *
      >>> [polygonal_number(Integer(4), n) for n in range(Integer(10))]
      [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

  The pentagonal numbers:

  Sage

      sage: [polygonal_number(5, n) for n in range(10)]
      [0, 1, 5, 12, 22, 35, 51, 70, 92, 117]

  Python

      >>> from sage.all import *
      >>> [polygonal_number(Integer(5), n) for n in range(Integer(10))]
      [0, 1, 5, 12, 22, 35, 51, 70, 92, 117]

  The hexagonal numbers:

  Sage

      sage: [polygonal_number(6, n) for n in range(10)]
      [0, 1, 6, 15, 28, 45, 66, 91, 120, 153]

  [Python]

      >>> from sage.all import *
      >>> [polygonal_number(Integer(6), n) for n in range(Integer(10))]
      [0, 1, 6, 15, 28, 45, 66, 91, 120, 153]

  The input is converted into an integer:

  Sage

      sage: polygonal_number(3.0, 2.0)
      3

  Python

      >>> from sage.all import *
      >>> polygonal_number(RealNumber('3.0'), RealNumber('2.0'))
      3

  A non-integer input returns an error:

  Sage

      sage: polygonal_number(3.5, 1)                                                  # needs sage.rings.real_mpfr
      Traceback (most recent call last):
      ...
      TypeError: Attempt to coerce non-integral RealNumber to Integer

  [Python]

      >>> from sage.all import *
      >>> polygonal_number(RealNumber('3.5'), Integer(1))                                                  # needs sage.rings.real_mpfr
      Traceback (most recent call last):
      ...
      TypeError: Attempt to coerce non-integral RealNumber to Integer

  \(s\) must be greater than 1:

  Sage

      sage: polygonal_number(1, 4)
      Traceback (most recent call last):
      ...
      ValueError: s (=1) must be greater than 1

  Python

      >>> from sage.all import *
      >>> polygonal_number(Integer(1), Integer(4))
      Traceback (most recent call last):
      ...
      ValueError: s (=1) must be greater than 1

  REFERENCES:

  - Wikipedia article Polygonal_number

sage.combinat.combinat.stirling_number1(n, k, algorithm='gap')

  Return the \(n\)-th Stirling number \(S_1(n,k)\) of the first kind.

  This is the number of permutations of \(n\) points with \(k\) cycles.

  See Wikipedia article Stirling_numbers_of_the_first_kind.

  INPUT:

  - `n` – nonnegative machine-size integer

  - `k` – nonnegative machine-size integer

  - `algorithm`:

    - `'gap'` – default; use GAP’s `Stirling1` function

    - `'flint'` – use flint’s `arith_stirling_number_1u` function

  EXAMPLES:

  Sage

      sage: # needs sage.libs.gap
      sage: stirling_number1(3,2)
      3
      sage: stirling_number1(5,2)
      50
      sage: 9*stirling_number1(9,5) + stirling_number1(9,4)
      269325
      sage: stirling_number1(10,5)
      269325

  Python

      >>> from sage.all import *
      >>> # needs sage.libs.gap
      >>> stirling_number1(Integer(3),Integer(2))
      3
      >>> stirling_number1(Integer(5),Integer(2))
      50
      >>> Integer(9)*stirling_number1(Integer(9),Integer(5)) + stirling_number1(Integer(9),Integer(4))
      269325
      >>> stirling_number1(Integer(10),Integer(5))
      269325

  Indeed, \(S_1(n,k) = S_1(n-1,k-1) + (n-1)S_1(n-1,k)\).

sage.combinat.combinat.stirling_number2(n, k, algorithm=None)

  Return the \(n\)-th Stirling number \(S_2(n,k)\) of the second kind.

  This is the number of ways to partition a set of \(n\) elements into \(k\) pairwise disjoint nonempty subsets. The \(n\)-th Bell number is the sum of the \(S_2(n,k)\)’s, \(k=0,...,n\).

  See Wikipedia article Stirling_numbers_of_the_second_kind.

  INPUT:

  - `n` – nonnegative machine-size integer

  - `k` – nonnegative machine-size integer

  - `algorithm`:

    - `None` – default; use native implementation

    - `'flint'` – use flint’s `arith_stirling_number_2` function

    - `'gap'` – use GAP’s `Stirling2` function

    - `'maxima'` – use Maxima’s `stirling2` function

  EXAMPLES:

  Print a table of the first several Stirling numbers of the second kind:

  Sage

      sage: for n in range(10):
      ....:     for k in range(10):
      ....:         print(str(stirling_number2(n,k)).rjust(k and 6))
      1      0      0      0      0      0      0      0      0      0
      0      1      0      0      0      0      0      0      0      0
      0      1      1      0      0      0      0      0      0      0
      0      1      3      1      0      0      0      0      0      0
      0      1      7      6      1      0      0      0      0      0
      0      1     15     25     10      1      0      0      0      0
      0      1     31     90     65     15      1      0      0      0
      0      1     63    301    350    140     21      1      0      0
      0      1    127    966   1701   1050    266     28      1      0
      0      1    255   3025   7770   6951   2646    462     36      1

  Python

      >>> from sage.all import *
      >>> for n in range(Integer(10)):
      ...     for k in range(Integer(10)):
      ...         print(str(stirling_number2(n,k)).rjust(k and Integer(6)))
      1      0      0      0      0      0      0      0      0      0
      0      1      0      0      0      0      0      0      0      0
      0      1      1      0      0      0      0      0      0      0
      0      1      3      1      0      0      0      0      0      0
      0      1      7      6      1      0      0      0      0      0
      0      1     15     25     10      1      0      0      0      0
      0      1     31     90     65     15      1      0      0      0
      0      1     63    301    350    140     21      1      0      0
      0      1    127    966   1701   1050    266     28      1      0
      0      1    255   3025   7770   6951   2646    462     36      1

  Stirling numbers satisfy \(S_2(n,k) = S_2(n-1,k-1) + kS_2(n-1,k)\):

  Sage

      sage: 5*stirling_number2(9,5) + stirling_number2(9,4)
      42525
      sage: stirling_number2(10,5)
      42525

  [Python]

      >>> from sage.all import *
      >>> Integer(5)*stirling_number2(Integer(9),Integer(5)) + stirling_number2(Integer(9),Integer(4))
      42525
      >>> stirling_number2(Integer(10),Integer(5))
      42525

sage.combinat.combinat.tuples(S, k, algorithm='itertools')

  Return a list of all \(k\)-tuples of elements of a given set `S`.

  This function accepts the set `S` in the form of any iterable (list, tuple or iterator), and returns a list of \(k\)-tuples. If `S` contains duplicate entries, then you should expect the method to return tuples multiple times!

  Recall that \(k\)-tuples are ordered (in the sense that two \(k\)-tuples differing in the order of their entries count as different) and can have repeated entries (even if `S` is a list with no repetition).

  INPUT:

  - `S` – the base set

  - `k` – the length of the tuples

  - `algorithm` – can be one of the following:

    - `'itertools'` – (default) use python’s itertools

    - `'native'` – use a native Sage implementation

  Note

  The ordering of the list of tuples depends on the algorithm.

  EXAMPLES:

  Sage

      sage: S = [1,2]
      sage: tuples(S,3)
      [(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
       (2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]
      sage: mset = ["s","t","e","i","n"]
      sage: tuples(mset, 2)
      [('s', 's'), ('s', 't'), ('s', 'e'), ('s', 'i'), ('s', 'n'),
       ('t', 's'), ('t', 't'), ('t', 'e'), ('t', 'i'), ('t', 'n'),
       ('e', 's'), ('e', 't'), ('e', 'e'), ('e', 'i'), ('e', 'n'),
       ('i', 's'), ('i', 't'), ('i', 'e'), ('i', 'i'), ('i', 'n'),
       ('n', 's'), ('n', 't'), ('n', 'e'), ('n', 'i'), ('n', 'n')]

  Python

      >>> from sage.all import *
      >>> S = [Integer(1),Integer(2)]
      >>> tuples(S,Integer(3))
      [(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
       (2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]
      >>> mset = ["s","t","e","i","n"]
      >>> tuples(mset, Integer(2))
      [('s', 's'), ('s', 't'), ('s', 'e'), ('s', 'i'), ('s', 'n'),
       ('t', 's'), ('t', 't'), ('t', 'e'), ('t', 'i'), ('t', 'n'),
       ('e', 's'), ('e', 't'), ('e', 'e'), ('e', 'i'), ('e', 'n'),
       ('i', 's'), ('i', 't'), ('i', 'e'), ('i', 'i'), ('i', 'n'),
       ('n', 's'), ('n', 't'), ('n', 'e'), ('n', 'i'), ('n', 'n')]

  Sage

      sage: K.<a> = GF(4, 'a')                                                        # needs sage.rings.finite_rings
      sage: mset = [x for x in K if x != 0]                                           # needs sage.rings.finite_rings
      sage: tuples(mset, 2)                                                           # needs sage.rings.finite_rings
      [(a, a), (a, a + 1), (a, 1), (a + 1, a), (a + 1, a + 1),
       (a + 1, 1), (1, a), (1, a + 1), (1, 1)]

  [Python]

      >>> from sage.all import *
      >>> K = GF(Integer(4), 'a', names=('a',)); (a,) = K._first_ngens(1)# needs sage.rings.finite_rings
      >>> mset = [x for x in K if x != Integer(0)]                                           # needs sage.rings.finite_rings
      >>> tuples(mset, Integer(2))                                                           # needs sage.rings.finite_rings
      [(a, a), (a, a + 1), (a, 1), (a + 1, a), (a + 1, a + 1),
       (a + 1, 1), (1, a), (1, a + 1), (1, 1)]

  We check that the implementations agree (up to ordering):

  Sage

      sage: tuples(S, 3, 'native')
      [(1, 1, 1), (2, 1, 1), (1, 2, 1), (2, 2, 1),
       (1, 1, 2), (2, 1, 2), (1, 2, 2), (2, 2, 2)]

  Python

      >>> from sage.all import *
      >>> tuples(S, Integer(3), 'native')
      [(1, 1, 1), (2, 1, 1), (1, 2, 1), (2, 2, 1),
       (1, 1, 2), (2, 1, 2), (1, 2, 2), (2, 2, 2)]

  Lastly we check on a multiset:

  Sage

      sage: S = [1,1,2]
      sage: sorted(tuples(S, 3)) == sorted(tuples(S, 3, 'native'))
      True

  [Python]

      >>> from sage.all import *
      >>> S = [Integer(1),Integer(1),Integer(2)]
      >>> sorted(tuples(S, Integer(3))) == sorted(tuples(S, Integer(3), 'native'))
      True

sage.combinat.combinat.unordered_tuples(S, k, algorithm='itertools')

  Return a list of all unordered tuples of length `k` of the set `S`.

  An unordered tuple of length \(k\) of set \(S\) is a unordered selection with repetitions of \(S\) and is represented by a sorted list of length \(k\) containing elements from \(S\).

  Unlike `tuples()`, the result of this method does not depend on how often an element appears in \(S\); only the set \(S\) is being used. For example, `unordered_tuples([1, 1, 1], 2)` will return `[(1, 1)]`. If you want it to return `[(1, 1), (1, 1), (1, 1)]`, use Python’s `itertools.combinations_with_replacement` instead.

  INPUT:

  - `S` – the base set

  - `k` – the length of the tuples

  - `algorithm` – can be one of the following:

    - `'itertools'` – (default) use python’s itertools

    - `'gap'` – wraps GAP’s `UnorderedTuples`

  Warning

  When using `algorithm='gap'`, `S` must be a list of objects that have string representations that can be interpreted by the GAP interpreter. If `S` consists of at all complicated Sage objects, this function might not do what you expect.

  EXAMPLES:

  Sage

      sage: S = [1,2]
      sage: unordered_tuples(S, 3)
      [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)]

  Python

      >>> from sage.all import *
      >>> S = [Integer(1),Integer(2)]
      >>> unordered_tuples(S, Integer(3))
      [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)]

  We check that this agrees with GAP:

  Sage

      sage: unordered_tuples(S, 3, algorithm='gap')                                   # needs sage.libs.gap
      [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)]

  [Python]

      >>> from sage.all import *
      >>> unordered_tuples(S, Integer(3), algorithm='gap')                                   # needs sage.libs.gap
      [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)]

  We check the result on strings:

  Sage

      sage: S = ["a","b","c"]
      sage: unordered_tuples(S, 2)
      [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]
      sage: unordered_tuples(S, 2, algorithm='gap')                                   # needs sage.libs.gap
      [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]

  Python

      >>> from sage.all import *
      >>> S = ["a","b","c"]
      >>> unordered_tuples(S, Integer(2))
      [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]
      >>> unordered_tuples(S, Integer(2), algorithm='gap')                                   # needs sage.libs.gap
      [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]

  Lastly we check on a multiset:

  Sage

      sage: S = [1,1,2]
      sage: unordered_tuples(S, 3) == unordered_tuples(S, 3, 'gap')                   # needs sage.libs.gap
      True
      sage: unordered_tuples(S, 3)
      [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)]

  [Python]

      >>> from sage.all import *
      >>> S = [Integer(1),Integer(1),Integer(2)]
      >>> unordered_tuples(S, Integer(3)) == unordered_tuples(S, Integer(3), 'gap')                   # needs sage.libs.gap
      True
      >>> unordered_tuples(S, Integer(3))
      [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)]

sage.combinat.combinat.unshuffle_iterator(a, one=1)

  Iterate over the unshuffles of a list (or tuple) `a`, also yielding the signs of the respective permutations.

  If \(n\) and \(k\) are integers satisfying \(0 \leq k \leq n\), then a \((k, n-k)\)-unshuffle means a permutation \(\pi \in S_n\) such that \(\pi(1) < \pi(2) < \cdots < \pi(k)\) and \(\pi(k+1) < \pi(k+2) < \cdots < \pi(n)\). This method provides, for a list \(a = (a_1, a_2, \ldots, a_n)\) of length \(n\), an iterator yielding all pairs:

  \[\Bigl( \bigl( (a_{\pi(1)}, a_{\pi(2)}, \ldots, a_{\pi(k)}), (a_{\pi(k+1)}, a_{\pi(k+2)}, \ldots, a_{\pi(n)}) \bigl), (-1)^{\pi} \Bigr)\]

  for all \(k \in \{0, 1, \ldots, n\}\) and all \((k, n-k)\)-unshuffles \(\pi\). The optional variable `one` can be set to a different value which results in the \((-1)^{\pi}\) component being multiplied by said value.

  The iterator does not yield these in order of increasing \(k\).

  EXAMPLES:

  Sage

      sage: from sage.combinat.combinat import unshuffle_iterator
      sage: list(unshuffle_iterator([1, 3, 4]))
      [(((), (1, 3, 4)), 1), (((1,), (3, 4)), 1), (((3,), (1, 4)), -1),
       (((1, 3), (4,)), 1), (((4,), (1, 3)), 1), (((1, 4), (3,)), -1),
       (((3, 4), (1,)), 1), (((1, 3, 4), ()), 1)]
      sage: list(unshuffle_iterator([3, 1]))
      [(((), (3, 1)), 1), (((3,), (1,)), 1), (((1,), (3,)), -1),
       (((3, 1), ()), 1)]
      sage: list(unshuffle_iterator([8]))
      [(((), (8,)), 1), (((8,), ()), 1)]
      sage: list(unshuffle_iterator([]))
      [(((), ()), 1)]
      sage: list(unshuffle_iterator([3, 1], 3/2))
      [(((), (3, 1)), 3/2), (((3,), (1,)), 3/2), (((1,), (3,)), -3/2),
       (((3, 1), ()), 3/2)]

  Python

      >>> from sage.all import *
      >>> from sage.combinat.combinat import unshuffle_iterator
      >>> list(unshuffle_iterator([Integer(1), Integer(3), Integer(4)]))
      [(((), (1, 3, 4)), 1), (((1,), (3, 4)), 1), (((3,), (1, 4)), -1),
       (((1, 3), (4,)), 1), (((4,), (1, 3)), 1), (((1, 4), (3,)), -1),
       (((3, 4), (1,)), 1), (((1, 3, 4), ()), 1)]
      >>> list(unshuffle_iterator([Integer(3), Integer(1)]))
      [(((), (3, 1)), 1), (((3,), (1,)), 1), (((1,), (3,)), -1),
       (((3, 1), ()), 1)]
      >>> list(unshuffle_iterator([Integer(8)]))
      [(((), (8,)), 1), (((8,), ()), 1)]
      >>> list(unshuffle_iterator([]))
      [(((), ()), 1)]
      >>> list(unshuffle_iterator([Integer(3), Integer(1)], Integer(3)/Integer(2)))
      [(((), (3, 1)), 3/2), (((3,), (1,)), 3/2), (((1,), (3,)), -3/2),
       (((3, 1), ()), 3/2)]