Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I saved an InterpolationFunction in a ".mx" files using DumpSave on a variable that was scoped by a Module. Here is a stripped-down example:

Module[{interpolation},
   interpolation=Interpolation[Range[10]];
   DumpSave["interpolation.mx", interpolation];
]

Is there a way to find out the variable name, presumably of the form interpolation$nnn, of the expression when I Get the interpolation? It is not apparent what the variable is when using

<<"interpolation.mx"

Next time I will not use a Module for scoping the save variable, but meantime I'd like to access the saved data and assign it to a new variable.

share|improve this question
1  
Why don't you just use Export? When just dealing with data, I find it really annoying that DumpSave saves variable names. Export["interp.mx", Interpolation@Range[10]]. –  Szabolcs Mar 13 '12 at 22:36
    
I would solve it using Block instead Module, besides it, the question is interesting, to see how to work with internal module variables. –  FJRA Mar 14 '12 at 0:20
    
@szabolcs thanks for the tip. I'll use Export next time. Aside from the variable name, are the mx files equivalent? I.e. platform-specific? –  JxB Mar 14 '12 at 2:18
    
@JxB yep, they're platform specific. Lately I use Export["file.mmaz", Compress[expression], "String"] and Uncompress@Import["file.mmaz", "String"] for good performance and platform independence. The disadvantage is relatively high memory use, and of course it is still slower than MX. If performance is not an issue (small expressions), just export/import to/from the WDX format. –  Szabolcs Mar 14 '12 at 6:25
1  
For the future you may wish to reference these save options I outlined. –  Mr.Wizard Mar 14 '12 at 10:40
show 1 more comment

3 Answers

up vote 7 down vote accepted

You can open the MX file in an ASCII editor. The variable name is there in plain text (interpolation$511 in my case). The rest is binary gibberish.

So given an MX file with a single variable with the $ suffix, the following expression can be used to access that variable directly:

getExpression[filename_] := Module[{a}, 
   ToExpression[(a = StringCases[Import[filename, "Text"], 
   WordCharacter ... ~~ "$" ~~ NumberString][[1]])];
   << (filename);
   ToExpression[a]
  ]

E.g.,

result = getExpression["interpolation.mx"]
  (* InterpolatingFunction[{{1,10}},<>] *)

Evaluating the variable name before reading it with Get (or <<) seemingly overcomes the Temporary attribute discussed in Leonid`s answer. As a (perhaps unwanted) side-effect of the above expression, the original variable remains defined.

This approach could probably be extended to work with multiple variables and expressions in one MX file.

share|improve this answer
    
So I could parse the first n bytes of the file, using ReadList say, to get the name. Nice to know. –  JxB Mar 14 '12 at 2:21
    
I wonder if manually renaming the variable in a text editor (or with Mma) to remove the $nnn from the variable works, or breaks the file formatting. Will check into it. –  JxB Mar 14 '12 at 2:23
    
Sjoerd, I added an expression for reassigning the variable directly from Mma. Hope you don't mind. –  JxB Mar 14 '12 at 3:48
    
@JxB Of course not, it's a great addition. –  Sjoerd C. de Vries Mar 14 '12 at 6:28
add comment

Here is another method, although I don't know how to capture the symbol name programatically...

On[General::newsym];
Get["/tmp/test.mx"];
Off[General::newsym];
 (* General::newsym: Symbol a$1772 is new. >> *)
share|improve this answer
    
Curious: execute this once, and you get the symbol name; a 2nd time and the message disappears but the symbol gets assigned. –  JxB Mar 14 '12 at 20:41
add comment

You seem to be out of luck (although I will be happy to be proven wrong). This is a rather subtle point, related to the Temporary attribute and garbage-collection. I will just share a few observations. First, note that after loading of .mx file on a fresh kernel, the variable is not found anywhere, it is not among the living:

<< "interpolation.mx"
names = Flatten[Names[# <> "*"] & /@ Contexts[]];
Flatten@StringCases[names, ___ ~~ "interpolation" ~~ ___]

{"Manipulate`Dump`interpolationToAnimation", 
   "Manipulate`Dump`interpolationToManipulate"}

Here is one way to make it persist:

Module[{interpolation},
  ClearAll[interpolation];
  interpolation = Interpolation[Range[10]];
  DumpSave["interpolation.mx", interpolation];
]

Now it will be found. By using ClearAll, I removed the Temporary attribute from interpolation. Interestingly, another way to do this is to define a DownValue rather than an OwnValue for it:

Module[{interpolation}, 
  interpolation[1] = Interpolation[Range[10]];
  DumpSave["interpolation.mx", interpolation];
]

In this case, too, it can be found, since garbage-collection of Module-generated variables works differently for DownValues.

I can not fully explain why this affected the code for DumpSave, which is still inside Module. One guess I have is that it gets recorded by DumpSave all right, with all attributes, including Temporary. Then, when you load it, it probably gets garbage-collected immediately after creation, due to this attribute.

Serializing in this manner using Module is also bad (although I am myself guilty of having done this, e.g. here) for another reason: Module-generated variables are only guaranteed to be unique within a single Mathematica session. It is better to use some custom code to generate variables with names guaranteed to be unique for all sessions (which is easy to do. I recommend to read this discussion).

share|improve this answer
    
Very interesting! Please see my edit to Sjoerd's answer: Evaluating the variable name first is a hack to get around the Temporary issue, I suppose because the variable is then already defined when it is read in? I confess I do not fully understand what is going on. –  JxB Mar 14 '12 at 3:52
    
@JxB Looks like you are right, good catch. So, apparently, I was proven wrong (which is good, at least in this case:-)). I am a bit surprised, because the mechanism that is used in .mx files is quite low-level, it presumably does not communicate with the high-level kernel state, but populates the symbols directly at the low level. So, I'd think it would add the Temporary attribute. Perhaps, it prevents immediate garbage collection because it was referenced in the input line, but these are all just guesses. –  Leonid Shifrin Mar 14 '12 at 20:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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