I have a complicated recursive module which I have memoized. I realised that certain isomorphs of inputs to this function will give the same output. Therefore I decided to memoize all such input-output pairs, each time the function is called with a representative of a new such equivalence class. Here is a much simpler, analogous module:
First without sneakiness:
determinant[m_] := determinant[m] = Module[{localvars},
If[Length[m] == 1, Return[m[[1, 1]]]];
Sum[Power[-1, j + 1] m[[1, j]] determinant[
m[[Complement[Range[Length[m]], {1}],
Complement[Range[Length[m]], {j}]]]], {j, 1, Length[m]}]
];
And now with sneakiness:
sneakydeterminant[m_] := sneakydeterminant[m] = Module[{answer},
If[Length[m] == 1, Return[m[[1, 1]]]];
answer =
Sum[Power[-1, j + 1] m[[1, j]] sneakydeterminant[
m[[Complement[Range[Length[m]], {1}],
Complement[Range[Length[m]], {j}]]]], {j, 1, Length[m]}];
sneakydeterminant[Transpose[m]] = answer;
answer
];
Inspecting the DownValues for each function after calling them seems to indicate that I have succeeded in assigning input-output pairs to the sneakydeterminant
function, even while inside its own code.
My question is, whether this is allowed and safe, or have I got away with it just by luck ?
The reason I ask is that this doesn't seem to work in my real example (which I refrained from posting because it is many lines of code long).
Thank you !
sneakydeterminant[m_] := sneakydeterminant[m] = sneakydeterminant[Transpose[m]] = ....
more clear $\endgroup$