5
$\begingroup$

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?

$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$
    – rcollyer
    Commented Jul 30, 2012 at 18:21
  • $\begingroup$ 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. $\endgroup$ Commented Aug 1, 2012 at 13:55

2 Answers 2

3
$\begingroup$

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.}},{Developer`PackedArrayForm,{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]

result

$\endgroup$
6
  • $\begingroup$ 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? $\endgroup$
    – fpghost
    Commented Jul 31, 2012 at 12:42
  • $\begingroup$ @fpghost If you examine my answer closely, you'll see a discussion of Put that just does that. $\endgroup$ Commented Jul 31, 2012 at 21:21
  • $\begingroup$ 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. $\endgroup$
    – fpghost
    Commented Aug 1, 2012 at 12:07
  • 1
    $\begingroup$ @fpghost, you should register so that you are able to comment on answers to your questions... $\endgroup$ Commented Aug 1, 2012 at 12:26
  • $\begingroup$ @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. $\endgroup$ Commented Aug 1, 2012 at 13:48
1
$\begingroup$

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.
$\endgroup$
1
  • 2
    $\begingroup$ 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. $\endgroup$
    – rcollyer
    Commented Jul 30, 2012 at 18:23

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.