# Problems with DumpSave and memoization

I defined a function that takes some time to compute using memoization:

y[a_, b_, c_] := y[a, b, c] = First[\$y /. NDSolve[.........]


so that if I call y[a,b,c] a second time it doesn't do the NDSolve computation all over again if it has already done it.

How can I save the result of this to file? I tried DumpSave["test.mx", y[3/10, 2, 0]] after calling y[3/10, 2, 0] (i.e. it is now an InterpolatingFunction; the result of NDSolve), but I get the error

"DumpSave::bsnosym: y[3/10,2,0] is not defined as a symbol or a context. >>"


If I call y[3/10,2,0][2] etc I get the correct numeric result.

Is there some reason this is not working?

-
Welcome to Mathematica.se! I've formatted your code to make it more readable. For inline code, wrap the code in grave marks . For code blocks, indent each line by 4 spaces. – rcollyer Jul 30 '12 at 18:21
I merged your registered and unregistered accounts so that you now have all questions and answers and the corresponding rep in one, registered account. You should be able to comment now. – Sjoerd C. de Vries Aug 1 '12 at 13:55

## 2 Answers

The reason this isn't working is that DumpSave expects a symbol as the second argument. The doc page says:

DumpSave["file.mx",symbol] writes definitions associated with a symbol to a file in internal Mathematica format.

With

ClearAll[y]
y[a_, b_, c_] := y[a, b, c] =  NDSolve[{y''[x] == a x, y[0] == b, y'[0] == c}, y[x], {x, 0, 10}]


and

y[3/10, 2, 0]


{{y[x] -> InterpolatingFunction[][x]}}

you can see that y is a symbol

y // Head


Symbol

whereas y[3/10, 2, 0] is not:

 y[3/10, 2, 0] // Head


List

It is the expression {{y[x] -> InterpolatingFunction[][x]}} as we have seen above.

To save expressions, such as a single instantiations of your memoized function, you can use Put (>>).

y[3/10, 2, 0] >> "test.mx"

Clear[y]
<<"test.mx"


{{y[x] -> InterpolatingFunction[][x]}}

To save the whole of y, basic definition and all memoized versions, you can DumpSave y itself:

DumpSave["test.mx", y];
Clear[y]
<<"test.mx"
?y


y[3/10,2,0]={{y[x]->InterpolatingFunction[{{0.,10.}},{4,23,2,{27},{4},0,0,0,0,Automatic},{{0.,0.0002208643237,<<...>>,9.481521054,10.}},{DeveloperPackedArrayForm,{0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81},{2.,<<...>>,3.}},{Automatic}][x]}}

y[a_,b_,c_]:=y[a,b,c]=NDSolve[{(y^[Prime][Prime])[x]==a x,y[0]==b,(y^[Prime])[0]==c},y[x],{x,0,10}]

An extensive treatment of all ways to save data for posterity can be found here.

EDIT

To conveniently select a specific memoized definition you could use the following:

dumpSaveSelect[y_] :=
DynamicModule[{sol, file},
Manipulate[
(DownValues[y][[i, 1]]) /.
HoldPattern -> HoldForm, {{i, 1, "DownValue:"}, 1,
Length[DownValues[y]], 1, ControlType -> SetterBar},
Button["DumpSave",
sol = DownValues[y][[i, 1]];
file = SystemDialogInput["FileSave", "myfile.mx"];
DumpSave[file, sol],
Method -> "Queued"
],
ControlPlacement -> {Top, Bottom}
]
]

dumpSaveSelect[y]


-
Thanks for the useful answers, but I don't want to dump the whole of 'y' really (since y will be growing as I compute the interpfuncs for more and more params. Unless there is a way to just append the bits of y that have not yet been written to file?). Is it not poss to just dump a y[1,2,3] for certain params? – fpghost Jul 31 '12 at 12:42
@fpghost If you examine my answer closely, you'll see a discussion of Put that just does that. – Sjoerd C. de Vries Jul 31 '12 at 21:21
I am aware I can use "put" as you suggested, but surely then I lose the economy of DumpSave? (the normal saving of my interp funcs outputs ~200MB files you see). I'd like to save them in this compressed format. – fpghost Aug 1 '12 at 12:07
@fpghost, you should register so that you are able to comment on answers to your questions... – J. M. Aug 1 '12 at 12:26
@fpghost In that case, just assign y[3/10, 2, 0] to a variable and DumpSave that. This is basically what Bill Simpson does. Or, you might consider using Compress. – Sjoerd C. de Vries Aug 1 '12 at 13:48

Enter the following

In[1]:= sol=NDSolve[{y′[x]==y[x],y[1] == 2},y,{x, 0, 3}][[1, 1]]

Out[1]= y->InterpolatingFunction[{{0.,3.}},<>]

In[2]:= DumpSave["nds.mx",sol]

Out[2]= {y->InterpolatingFunction[{{0.,3.}},<>]}


Exit Mathematica

Start Mathematica, and run this

In[1]:= Get["nds.mx"] (* or use two < and no quotes and nds.mx *)

In[2]:= y[1]/.sol

Out[2]= 2.
`
-
I formatted your code, as it was difficult to follow as it was. Plus I added a bit of explanatory text to improve the flow of the answer. – rcollyer Jul 30 '12 at 18:23