11

I like using memoization (i.e. the construct myFunction[x_]:=myFunction[x]=...) when I have a heavy function that I need to re-evaluate on the same arguments. However, I find it frustrating that each time I quit the kernel(s), all the advantage goes lost.

Is there a way of saving the results? I can think of a very cumbersome way of doing it, such as this block upon defining our function

memo = If[FileExistsQ[FileNameJoin[{Directory[], "memo.mx"}]], Import["memo.mx"], {}];
myFunction[x_] := Module[{value = ...},
AppendTo[memo, "myFunction[" <> ToString[x] <> "]=" <> ToString[value]]; 
Export["memo.mx", Union@memo];
myFunction[x] = value]
Evaluate[ToExpression/@memo];

Is this okay, or is there a better (or even designated) way of doing this?

Ziofil
  • 2,470
  • 16
  • 30

2 Answers2

14

Not much different from your approach and maybe not the best/safest approach, but DumpSave helps a bit because at least you don't have to works with strings:

cacheFile = FileNameJoin[{$TemporaryDirectory, "fibonacciCache" <> ".mx"}];
If[FileExistsQ[cacheFile],
 Get[cacheFile],
 fibonacci[1] = 1;
 fibonacci[2] = 1;
 fibonacci[n_Integer] := Module[{},
   fibonacci[n] = fibonacci[n - 1] + fibonacci[n - 2];
   DumpSave[cacheFile, fibonacci];
   fibonacci[n]
   ]
 ]

For example

In[3]:= fibonacci[500] // Timing

Out[3]= {0.562500, \ 1394232245616978801397243828704072839500702565876973072641089629483255\ 71622863290691557658876222521294125}

Now Quit[]-ing and reevaluating the previous cell:

In[3]:= fibonacci[500] // Timing

Out[3]= {0., \ 1394232245616978801397243828704072839500702565876973072641089629483255\ 71622863290691557658876222521294125}

unlikely
  • 7,103
  • 20
  • 52
2

Here is another approach with LocalSymbol:

PersistentMemoize[key_, expr_] := Module[{name, value},
  name = "PersistentMemoize/" <> ToString[key // Hold // InputForm];
  value = LocalSymbol[name];
  If[Head[value] === LocalSymbol,
    value = LocalSymbol[name] = expr;
  ];
  value
];
SetAttributes[PersistentMemoize, HoldAll];

ClearPersistentMemoization[] := DeleteObject[LocalObjects["LocalSymbols/PersistentMemoize"]];

(* example *)

fib[n_] := fib[n] = PersistentMemoize[fib[n], Print["computing fib[" <> ToString[n] <> "]..."]; fib[n - 1] + fib[n - 2] ]; fib[1] = 1; fib[2] = 2; ```

tueda
  • 793
  • 3
  • 6