Is there a way to simplify the following term:
sum(binom(m, i)*binom(n, i)*factorial(i), i = 1..min(n,m))
where binom is the binominal coefficient.
Thanks!
Is there a way to simplify the following term:
sum(binom(m, i)*binom(n, i)*factorial(i), i = 1..min(n,m))
where binom is the binominal coefficient.
Thanks!
Since this is stackoverflow and not math.stackexchange, it is only reasonable to assume that you plan to actually implement a program to compute this sum. With that in mind, I'll be doing a few "simplifications" that you normally wouldn't do in a purely mathematical / hypothetical setting.
First, know that
binom(n, i) => factorial(n) / (factorial(i) * factorial(n - i))
Plugging this into your equation, we can cancel out two factorial(i)
terms.
factorial(n) * factorial(m) / ((factorial(i) * factorial(n - i) * factorial(m - i))
Now, if we make a function product(a, b)
which takes the product of all numbers [a, b]
inclusive, we can split apart these factorials into ranges which cancel out. To make the following snippet more concise, I abbreviate factorial as fac
and product as prod
.
fac(n)*fac(m) / (fac(i) * fac(n-i) * fac(m-i))
=> prod(m+1, n) * fac(m)**2 / (fac(i) * fac(n-i) * fac(m-i))
=> prod(m+1, n) * fac(m)**2 / (fac(i) * prod(m-i+1,n-i) * fac(m-i)**2)
=> prod(m+1, n) * prod(m-i+1,m)**2 / (fac(i) * prod(m-i+1,n-i))
=> prod(m+1, n) * prod(m-i+1,m) / (fac(i) * prod(m+1,n-i))
=> prod(n-i+1, n) * prod(m-i+1,m) / fac(i)
So at the end, we have
product(n-i+1, n) * product(m-i+1,m) / factorial(i)
-which requires significantly fewer multiplications. Now of course, the ideal way to compute this is not to evaluate the functions I have described above- the intermediate values will still be quite large.
The first option would be to start multiplying the values in each product()
, and attempt to divide out smaller factors from factorial()
. This may be time consuming however, since you will waste many more cycles checking for divisibility than actually reducing the number.
Another option would be to construct three sets, representing the numbers to be multiplied in each function call. Then take the intersection of one of the product
sets with the factorial
set, and subtract these elements from each of the original sets. Then repeat this process with the other product
set and the new factorial
set. Then multiply out the values in each set as before.
A smarter option yet would be to obtain the prime factorization of each number multiplied in product()
and factorial()
(maybe via lookup table), and then simply sum up the counts of each factor in product()
and subtract away factorial()
. Then you can just multiply by powers of each prime factor, which themselves can be computed faster via exponentiation by squaring (or even lookup tables, for smaller powers & factors).