Skip to main content

list manipulation - Sum of Multinomial Coefficients


Basically, I want to write a function to compute the following sum


$f(m,L):=\sum_{0\leq k_1,\cdots, k_n\leq m} \binom{m}{k_1,k_2,\cdots k_n}$ and $\mathrm{supp}(k)=L \subseteq \left \{ 1,...,n \right \}$


I wrote the following function but it doesn't work:


L = {1, 2, 4, 5};
f[m, L] := Return[For[i = 1, i <= m, i++, Total[Multinomial@@Take[L, i]]]];
f[3, L]
(*f[3, {1, 2, 4, 5}]*)


What am I missing? Thank you


EDIT: I added a condition to the indices $k$, which I forgot to mention earlier. $\mathrm{supp}(k)=L$ means that $L$ is the set of indices such that the components of the vector $k=(k_1,...,k_n)$ are nonzero.



Answer



The sum is a little strange, because the multinomial coefficient makes sense only when $k_1+k_2+\ldots+k_n=m$. I will assume this restriction is (implicitly) intended and that $n$ is fixed. (If not, a variation of the following solution will work.)


Notice that the set


$$\{0 \le k_1 \le k_2 \le \ldots \le k_n \le m\}$$


is in one-to-one correspondence with the $n$ differences


$$(k_1, k_2-k_1, \ldots, k_n - k_{n-1}, m-k_n).$$


The elements of the latter are non-negative integers summing to $m$. If we add $1$ to each, they will be positive and sum (obviously) to $m+n$. The set of such sequences is obtained with IntegerPartitions.



Working backwards, then, we can invoke IntegerPartitions, subtract $1$ from all elements, apply Multinomial, and Sum what we have obtained. This leads to the efficient and straightforward solution:


f[m_Integer, n_Integer] := 
Sum[Multinomial @@ k, {k, # - ConstantArray[1, n] & /@ IntegerPartitions[m + n, {n}]}]

(Including {n} as an argument to IntegerPartitions causes the number of $k_i$ to be fixed at $n$.)


For example, f[5,4] adds up all such multinomial coefficients having $n=4$ terms summing to $m=5$:


$$\eqalign{ &\sum_{0 \le k_1\le k_2\le k_3\le k_4 \le 5}\binom{5}{k_1\ k_2\ k_3\ k_4} \\ &= \binom{5}{0\ 0\ 0\ 5} + \binom{5}{0\ 0\ 1\ 4} + \binom{5}{0\ 0\ 2\ 3}+ \binom{5}{0\ 1\ 1\ 3}+ \binom{5}{0\ 1\ 2\ 2}+ \binom{5}{1\ 1\ 1\ 2} \\ &= 1 + 5 + 10 + 20 + 30 + 60 \\ & = 126. }$$




Edit


I have speculated (in comments below) that the role of L might be to limit the possible values of the $k_i$ to a set. Specifically, this interpretation asks for the calculation of



$$\sum_{k_i \in L: 0\le k_1\le \ldots \le k_n \le m} \binom{m}{k_1\ k_2\ \ldots\ k_n}$$


where $m$, $n$, and $L$ are given. When $m$ is not too large, a simple way is to modify the preceding solution to include only those index vectors $(k_i)$ whose components lie in $L$:


f[m_Integer, n_Integer, support_List] := 
With[{indexes =
Select[# - ConstantArray[1, n] & /@ IntegerPartitions[m + n, {n}],
Complement[#, support] == {} &]},
Reap[Sum[Multinomial @@ Sow[k], {k, indexes}]]]

The inclusion of Sow and Reap (which can readily be removed after testing is complete) provides a method to monitor the calculation: each set of indexes is saved by Sow and all are returned via Reap after the calculation is complete.


Examples



f[5, 4, Range[0, 5]] (* Reproduce the preceding example *)


$\{126,\{\{\{5,0,0,0\},\{4,1,0,0\},\{3,2,0,0\},\{3,1,1,0\},\{2,2,1,0\},\{2,1,1,1\}\}\}\}$



It obtains the same answer of $126$, followed by the detailed list of indexes contributing to that value.


f[8, 4, {1, 2, 4, 5}]


$\{3696,\{\{\{5,1,1,1\},\{4,2,1,1\},\{2,2,2,2\}\}\}\}$




The indexes clearly are limited to the set $\{1,2,4,5\}$ in this calculation. Without that limitation, we would invoke f[8, 4, Range[0,8]], obtaining $8143$ instead of $3696$; $15$ different index vectors contribute to this sum.


Comments

Popular posts from this blog

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...

dynamic - How can I make a clickable ArrayPlot that returns input?

I would like to create a dynamic ArrayPlot so that the rectangles, when clicked, provide the input. Can I use ArrayPlot for this? Or is there something else I should have to use? Answer ArrayPlot is much more than just a simple array like Grid : it represents a ranged 2D dataset, and its visualization can be finetuned by options like DataReversed and DataRange . These features make it quite complicated to reproduce the same layout and order with Grid . Here I offer AnnotatedArrayPlot which comes in handy when your dataset is more than just a flat 2D array. The dynamic interface allows highlighting individual cells and possibly interacting with them. AnnotatedArrayPlot works the same way as ArrayPlot and accepts the same options plus Enabled , HighlightCoordinates , HighlightStyle and HighlightElementFunction . data = {{Missing["HasSomeMoreData"], GrayLevel[ 1], {RGBColor[0, 1, 1], RGBColor[0, 0, 1], GrayLevel[1]}, RGBColor[0, 1, 0]}, {GrayLevel[0], GrayLevel...

list manipulation - Selecting multiple columns from a matrix?

Sample data: data = { {{2013, 1, 1}, 24.13, 167.67, 231.82}, {{2013, 1, 2}, 32.15, 170.92, 225.99}, {{2013, 1, 3}, 35.43, 172.68, 221.67}, {{2013, 1, 4}, 36.73, 173.05, 218.32}, {{2013, 1, 5}, 58.19, 165.96, 197.05}, {{2013, 1, 6}, 69.99, 163.50, 187.52}, {{2013, 1, 7}, 71.37, 154.21, 175.58}, {{2013, 1, 8}, 72.51, 149.66, 163.25}}; I want a DateListPlot with three graphs, so for a matrix formed by columns 1 and 2, one for columns 1 and 3, and 1 for columns 1 and 4. At the moment I'm using this code: data2 = Transpose[{data[[All, 1]], data[[All, 2]]}]; data3 = Transpose[{data[[All, 1]], data[[All, 3]]}]; data4 = Transpose[{data[[All, 1]], data[[All, 4]]}]; DateListPlot[{data2, data3, data4}, Joined -> True, Filling -> {3 -> {1}}] but I have a hunch that this can be done more efficiently. I don't like the Transpose s in particular. Any ideas? edit (for extra credit) What if I need to multiply the second column by 2, which in my solution is simp...