Does Python have a function which computes multinomial coefficients? Does Python have a function which computes multinomial coefficients? python python

Does Python have a function which computes multinomial coefficients?


To partially answer my own question, here is my simple and fairly efficient implementation of the multinomial function:

def multinomial(lst):    res, i = 1, 1    for a in lst:        for j in range(1,a+1):            res *= i            res //= j            i += 1    return res

It seems from the comments so far that no efficient implementation of the function exists in any of the standard libraries.

Update (January 2020). As Don Hatch has pointed out in the comments, this can be further improved by looking for the largest argument (especially for the case that it dominates all others):

def multinomial(lst):    res, i = 1, sum(lst)    i0 = lst.index(max(lst))    for a in lst[:i0] + lst[i0+1:]:        for j in range(1,a+1):            res *= i            res //= j            i -= 1    return res


No, there is not a built-in multinomial library or function in Python.

Anyway this time math could help you. In fact a simple method for calculating the multinomial

keeping an eye on the performance is to rewrite it by using the characterization of the multinomial coefficient as a product of binomial coefficients:

where of course

Thanks to scipy.special.binom and the magic of recursion you can solve the problem like this:

from scipy.special import binomdef multinomial(params):    if len(params) == 1:        return 1    return binom(sum(params), params[-1]) * multinomial(params[:-1])

where params = [n1, n2, ..., nk].

Note: Splitting the multinomial as a product of binomial is also good to prevent overflow in general.


You wrote "sympy.ntheory.multinomial.multinomial_coefficients returns a dictionary related to multinomial coefficients", but it is not clear from that comment if you know how to extract the specific coefficients from that dictionary. Using the notation from the wikipedia link, the SymPy function gives you all the multinomial coefficients for the given m and n. If you only want a specific coefficient, just pull it out of the dictionary:

In [39]: from sympy import ntheoryIn [40]: def sympy_multinomial(params):    ...:     m = len(params)    ...:     n = sum(params)    ...:     return ntheory.multinomial_coefficients(m, n)[tuple(params)]    ...: In [41]: sympy_multinomial([1, 2, 3])Out[41]: 60In [42]: sympy_multinomial([10, 20, 30])Out[42]: 3553261127084984957001360

Busy Beaver gave an answer written in terms of scipy.special.binom. A potential problem with that implementation is that binom(n, k) returns a floating point value. If the coefficient is large enough, it will not be exact, so it would probably not help you with a Project Euler problem. Instead of binom, you can use scipy.special.comb, with the argument exact=True. This is Busy Beaver's function, modified to use comb:

In [46]: from scipy.special import combIn [47]: def scipy_multinomial(params):    ...:     if len(params) == 1:    ...:         return 1    ...:     coeff = (comb(sum(params), params[-1], exact=True) *    ...:              scipy_multinomial(params[:-1]))    ...:     return coeff    ...: In [48]: scipy_multinomial([1, 2, 3])Out[48]: 60In [49]: scipy_multinomial([10, 20, 30])Out[49]: 3553261127084984957001360