I'll try to make a basic example of my problem with $n$ being an array of elements, ex. $\{1,2,2,3,3,3\}$:
If i have a sum which needs a computed value i would like to compute it beforehand and store it in a variable (ex. $k$). When calculating the sum, $k$ is not $i_{max}$ but $\{i_1,i_2,...\}$:
f[{_}] = 2.;
f[n_] := f[n] = (
k = Union[Select[n, # > 1 &]];
f[Drop[n, 1]]
+ If[k == {}, 0.,
Sum[Count[n, i]
*f[Join[DeleteCases[n, i, 1, 1], i - 1]], {i, k}]])
f[{1, 2, 2, 3, 3, 3}]
Out=1368.
But this output is not what i intended to generate and i assume it's because a recursive step is computed every time it is encountered, overwriting $k$ every time.
The correct computation would be:
g[{_}] = 2.;
g[n_] := g[n] = (
g[Drop[n, 1]]
+ If[Union[Select[n, # > 1 &]] == {}, 0.,
Sum[Count[n, i]
*g[Join[DeleteCases[n, i, 1, 1], i - 1]], {i, Union[Select[n, # > 1 &]]}]])
g[{1, 2, 2, 3, 3, 3}]
Out=2640.
The computation of the function $f$ is however much faster then $g$, so i'm wondering if it's possible to first gather all recursions needed before computing them, so computing $k$ once in each recursion would be enough.
Edit: I decided to upload my original code as it is not too complex. The goal is to compute a theoretical distribution for Runs-up-and-down:
edit[r_, del_, add_] := edit[r, del, add] =
If[Min[Count[r, #1] - #2 & @@@ Tally[del]] < 0, {},
Sort[Join[Fold[DeleteCases[##, 1, 1] &, r, del], add]]]
h[{}] = 0.;
h[{_}] = 2.;
h[r_] := h[r] = (
2*h[edit[r, {1}, {}]]
+ If[Union[Select[r, # > 1 &]] == {}, 0.,
Sum[(Count[r, i - 1] + 1)*h[edit[r, {i}, {i - 1}]], {i,
Union[Select[r, # > 1 &]]}]]
+ Sum[(Count[r, i + j] + 1)*h[edit[r, {1, i, j}, {i + j}]], {i,
Union[r]}, {j, Union[r]}])
n = 31;
dist = Flatten[
List /@ Plus @@@
Map[h, GatherBy[Sort /@ IntegerPartitions[n - 1],
Length], {2}]]/n! // AbsoluteTiming
The computation takes about 25 seconds on my (slow) Notebook. By storing Union[Select[r, # > 1 &]]
and Union[r]
into variables, the computation only took 17 seconds but delivered wrong results.