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):=0k1,,knm(mk1,k2,kn) and supp(k)=L{1,...,n}


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. supp(k)=L means that L is the set of indices such that the components of the vector k=(k1,...,kn) are nonzero.



Answer



The sum is a little strange, because the multinomial coefficient makes sense only when k1+k2++kn=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


{0k1k2knm}


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


(k1,k2k1,,knkn1,mkn).


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 ki to be fixed at n.)


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


0k1k2k3k45(5k1 k2 k3 k4)=(50 0 0 5)+(50 0 1 4)+(50 0 2 3)+(50 1 1 3)+(50 1 2 2)+(51 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 ki to a set. Specifically, this interpretation asks for the calculation of



kiL:0k1knm(mk1 k2  kn)


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 (ki) 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

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

What is and isn't a valid variable specification for Manipulate?

I have an expression whose terms have arguments (representing subscripts), like this: myExpr = A[0] + V[1,T] I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.) However, Mathematica complains when I set V[1,T] as a manipulated variable: Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}] (*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *) As a workaround, if I get rid of the symbol T inside the argument, it works fine: Manipulate[ Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}] Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable? Investigations I've done so far: I tried using variableQ from this answer , but it says V[1...