Firstly I wanted to find all the non-negative integer solutions for the following equation given the value of $k_{max}$
$$ k_1 +k_2 +k_3+k_4 = k_{max} $$
For this I use the following code:-
findAll[kmax_]:=Partition[
Flatten[Permutations /@ IntegerPartitions[kmax, {4}, Range[0,
kmax]]], 4]
Secondly I want to do in some sense the inverse of the above problem which is to find the position of the $k_i$ state given a set of $\{k_1,k_2,k_3,k_4\}$ and $k_{max}$.
For this part I use the code below.
findIndex[kmax_, state_] := Position[Partition[
Flatten[Permutations /@ IntegerPartitions[kmax, {4}, Range[0, kmax]]],
4], val_ /; val == state]
findIndex[4, {0, 1, 1, 2}]
(*{{34}}*)
I really don't like this method for the second part.
Can this be achieved without going over all the permutations?
Answer
I think you'll find this considerably more efficient than the accepted answer:
f= With[{s = Accumulate@Reverse@# + 1, r = Range[Length@# - 1]},
Tr[(Pochhammer[Rest@s, r] - Pochhammer[Most@s, r])/r!] + 1] &;
Example:
test={77620, 58215, 38810, 19405};
f@test // RepeatedTiming
Block[{$RecursionLimit = 100000}, index[Tr@test, Most@test] // RepeatedTiming]
{0.000017, 954814548275041}
{0.7, 954814548275041}
About 4 orders of magnitude faster.
Additionally, no need to mess with $RecursionLimit
for larger cases (which even with it, can crash kernel using index
, at least this happens on my machine).
Comments
Post a Comment