2
$\begingroup$

Lets say I define a function f with memoization. Is there some way to extract the memoized values?

For example,

f[0] = 1; f[1] = 5; f[20] = 42

Is there some way to get a list similar to {0 -> 1, 1 -> 5, 20 -> 42}?

Note, FullDefinition is close, but I dont know how to handle its output.

$\endgroup$
2
  • 1
    $\begingroup$ You may want to start by taking a look at the docs for DownValues[] $\endgroup$ Jun 14, 2014 at 20:58
  • $\begingroup$ Ah, yes, of course! I feel silly now. $\endgroup$ Jun 14, 2014 at 21:07

3 Answers 3

4
$\begingroup$

This will work more generally for memoized functions taking one integer argument.

Clear[f];
f[0] = 1;
f[x_Integer] := f[x] = f[x - 1] + 1/x
f /@ Range[3];
Cases[DownValues[f], f[i_Integer] :> Rule[i, f[i]], Infinity]
{0 -> 1, 1 -> 2, 2 -> 5/2, 3 -> 17/6}
$\endgroup$
1
$\begingroup$
f[0] = 1; f[1] = 5; f[20] = 42;

Rule @@@
 Partition[
  Cases[DownValues[f], _Integer, Infinity],
  2]

{0 -> 1, 1 -> 5, 20 -> 42}

$\endgroup$
3
  • $\begingroup$ extremely nice ! $\endgroup$
    – eldo
    Jun 14, 2014 at 21:41
  • $\begingroup$ @eldo Thanks. In your approach, use Identity rather than Sequence. $\endgroup$
    – Bob Hanlon
    Jun 14, 2014 at 21:56
  • $\begingroup$ I like this, but there is a problem with it. Although it works for the OP's example date, it won't work for a memoized function like f[0] = 1; f[x_Integer] := f[x] = f[x - 1] + 1/x. $\endgroup$
    – m_goldberg
    Jun 14, 2014 at 22:13
1
$\begingroup$

For this particular situation the following is an alternative and since no Pattern matching is being done here, it is slightly faster than the Cases solutions provided.

makeFRule[func_, start_, end_] := MapThread[Rule, Rest @ Extract[DownValues[func][[start ;; end]], 
{{0}, {All, 1, 1, 1}, {All, 1, 1}}]]

Test data:

lis = Transpose[{Range[10^6], RandomInteger[10, 10^6]}];
(f[#1] = #2) & @@@ lis; (* create DownValues *)

Timings:

rule1 = makeFRule[f, 1, -1]; // AbsoluteTiming
rule2 = Cases[DownValues[f], f[i_Integer] :> Rule[i, f[i]], Infinity]; // 
AbsoluteTiming
rule1 == rule2

(* 
8.852543
10.243611
True
 *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.