0
$\begingroup$

So because I wanted my multiple notebooks to not interfere with each other, I start them with:

SetOptions[EvaluationNotebook[], CellContext -> Notebook]

Following the suggestion I saw here some time ago. I have some variables, IntsC and IntsS which are matrices of expressions (very long and time-consuming to calculate).

If I just save the notebook, close it, and then open it again, I have lost the expressions. I can only get what's printed in the cells. So I searched how to save a variable, and what I was told to do is:

DumpSave["integrals.mx", IntsC, IntsS];

and to load I would do this:

<< integrals.mx

This works fine if I do this on the same notebook. But if I open a different notebook, that doesn't work. It simply does nothing as far as I can tell. Variables IntsC and IntsS remain non-existent. No error message or anything.

How do I make it so that I can load integrals.mx in any context?

Sorry I'm very new to Mathematica, I tried reading on contexts but it was all very confusing and I couldn't make anything work. I'm used to things like Matlab and python where if you save something, you can load it anywhere, even in a different machine, no worrying about contexts (if that really is the problem). How do I get something that works the same way here?


In the meantime I found this suggestion, which tells me to do this:

ClearAll[loadInContext];
loadInContext[context_String,file_String/;FileExtension[file]==="mx"]:=
    Module[{tag},
        Block[{$NewSymbol=Sow[#1,tag]&},
            With[{created=(If[#1==={},{},First[#1]]&)[Reap[Import[file],tag][[2]]]},
                Scan[(Context[#1]=context)&,created]
            ]
        ]
    ]

And then I ran

loadInContext[$Context, "integrals.mx"]

However, this does nothing.

$\endgroup$
0
$\begingroup$

My understanding of the problem:

The same as Matlab and python, so long as you save it in the right format, Mathematica data and expressions can easily be shared between many different OSes and versions of Mathematica. Using DumpSave to save information, however, saves it in a binary format that is not meant to be as portable. The documentation states that you cannot share these files between systems with different values of $SystemWordLength.

There may be other restrictions I'm not aware of. If you just want to keep them on the same computer, DumpSave will work. The problem is that in the original notebook, the context ($Context) is probably something like Notebook$$25$691003' (where the apostrophe is actually a back tick). When you call IntsC, Mathematica assumes that you mean Notebook$$25$691003'IntsC so it doesn't make you write out all those extra characters. When you use DumpSave, this context information gets saved along with the variable. When you Get the file, it loads IntsC and IntsS back into that same context, which is different from your new notebook. You would then have to type out the full context and symbol name to access it.

My first recommendation:

Unless your output is truly gigantic, I would recommend using Save. It's used in almost the exact same way as DumpSave but doesn't have this same restriction.

Save["integrals.wl", {IntsC, IntsS}]

and then

<<"integrals.wl"

My second recommendation:

If your matrices are so large that you end up waiting forever to load plain-text files, you can still use DumpSave. There may be a more elegant way of doing this, but here's what I would do. Place this in the notebook where you're using DumpSave:

Do[
  With[
    {j = i},
    Context[j] = "ints`"
  ],
  {i, {"IntsC", "IntsS"}}
]
DumpSave["integrals.mx", "ints`"]

then, in the new notebook where you'd like to import them:

<<"integrals.mx"
Do[
  With[
    {j = i},
    Context[j] = $Context
  ],
  {i, Names["ints`*"]}
]

You should now be able to run IntsC and IntsS in the new notebook. Note that if you do this while the kernel is still running, it's not really a true test. You can always access variables from other contexts once they're in memory. If I run ints'a = 5 in one notebook, I can immediately go to another notebook and run ints'a without any need for DumpSave in between. If I first quit the kernel, this will not be the case.

In the first block of code, I'm running through the list of variables as strings (it's easier than figuring out how to prevent the symbols themselves from evaluating - I'm still not any good at using Hold and friends, if those are even applicable here). By using With, I'm immediately replacing the j with the actual string "IntsC", otherwise we find that we just change the context of the symbol j a bunch of times when we actually want to change the context of IntsC.

In the second block of code, I'm changing that ints' context to the local one. You could also skip the Do loop if you're okay with typing ints'IntsC and ints'IntsS all the time in the new notebook.

Some links I found helpful:

Finally, I would recommend checking out these links. The first one describes several ways of storing data from an answer here on MMA.SE. The (second)[https://reference.wolfram.com/language/guide/PersistentStorage.html] is a link to the Mathematica documentation on persistent storage, and even provides methods of storing data in the cloud.

$\endgroup$
  • $\begingroup$ Thank you. Your first recommendation works for me. Looking back now, I don't understand how I didn't find about Save when I was searching, it does exactly what I need. The expressions are very large for human eyes, but the file is just 100Kb. $\endgroup$ – Sirplentifus May 7 '20 at 11:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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