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.
with. Maybe i should post my original code as it isn't too complicated. – kon Mar 25 '15 at 11:58edit, so optimizinghis unlikely to be of much help unless it can be made to calleditless. Since you got the wrong output I suggest that the apparent improvement you saw was not due to greater efficiency but simply fewer calls toedit. I shall continue to play with this but I shall focus onedit. – Mr.Wizard Mar 25 '15 at 13:45{0}on a malformed removal will take some additional thought but since it was added as an afterthought in a comment I feel the [duplicate] is appropriate. – Mr.Wizard Mar 25 '15 at 13:58unsortedComplementto handle the malformed removal without losing speed but I haven't achieved it yet. Incidentally are you using Mathematica 10? – Mr.Wizard Mar 25 '15 at 14:20@notification for that person is redundant and the system automatically removes it. I'll try to return to this problem later but I've got other things to work on now. – Mr.Wizard Mar 25 '15 at 15:03