5
$\begingroup$

I have a .nb (notebook) file which I should convert to a .m (mathematica package) file to run it remotely from command line of a high performance computing server. Before doing that I want to test whether my .m file runs correctly or not. (If I could run a .nb file using the command line then I didn't have all this trouble explained below!)

In my .nb file, I have used the Symbolize command for introducing the indexed symbols and I have used Save to get the output of the code in the format of a .m file. Everything works fine when I run the .nb file and the output is produced. Here is a simple code in a .nb file

enter image description here

Notice that the Symbolize is used from Notation palette and $x_1$ is entered as x + Ctrl + _ + 1. But when this is converted to a .m file (see this answer for converting .nb to .m), it turns into

ClearAll["Global`*"]
Needs["Notation`"]
Symbolize[ParsedBoxWrapper[SubscriptBox["x", "i_"]]]
Subscript[x, 1] = 1;
SetDirectory[NotebookDirectory[]];
Save["OutPut.m", Subscript[x, 1]]

and after running the .m file I get this error

enter image description here

which means that $x_1$ is not a symbol. According to the following code, I conclude that Symbolize is not working in a .m file or there is some problem in the conversion of .nb to .m!

What should I do to fix this? Specifically, what should I do so that after converting .nb to .m such errors do not come up?

Any help or suggestion is appreciated. :)

$\endgroup$
7
$\begingroup$

This answer may seem slightly off but it was posted before recent updates. The bottom line holds though.

It symbolizes boxes, not expressions, it is not Subscript which is now special but SubscriptBox.

You are supposed to use $x_1$ in your code but if you can't use StandardForm/2d typesetting then you have to make a round trip to boxes and back to expression:

roundtrip =  Function[expr
  , ToExpression@MakeBoxes[expr, StandardForm]
  , HoldFirst
];

roundtrip[ Subscript[x, 1] = 123 ]

roundtrip[ Save["OutPut.m", Subscript[x, 1]] ]

FilePrint@"OutPut.m"

enter image description here

$\endgroup$
  • 1
    $\begingroup$ @H.R. What I meant is: SubscriptBox is symbolized, not Subscript, and expecting Subscript[_,_] to be considered a symbol is wrong. Of course you can do Subscript[x,1]=2 but this has nothing to do with Symbolize. It just creates downvalues for Subscript itself. p.s. you don't need GUI, you just need Mathematica and run NotebookEvaluate @ path, (UsingFrontEnd may be needed). $\endgroup$ – Kuba May 31 '17 at 9:53
  • 1
    $\begingroup$ @H.R. Check out this old post. I once got it to work, but it is tricky and I have no time to check again. $\endgroup$ – Rolf Mertig May 31 '17 at 10:34
  • $\begingroup$ Let us continue this discussion in chat. $\endgroup$ – Kuba Jun 1 '17 at 8:33
4
$\begingroup$

The Notation package relies on Box Form as used by the Front End. Packages (generally) do not use Box Form therefore the Notation package does not work there. If you start WolframKernel.exe and evaluate Get["Notation`"] you will see a variety of error messages starting with:

FrontEndObject::notavail: A front end is not available; certain operations require a front end.

In translating from Box Form to plain text compromises have to be made as there is no direct equivalent for many things.

A Box Form subscript is normally translated as Subscript but this does not preserve the Symbol-like behavior enacted by the Notation package. If you need Symbol-like behavior then a different compromise will need to be made. One option is to replace the Subscript expression with a Symbol, which is what the Notation package is doing behind the scenes. So your package code would look like:

ClearAll["Global`*"]

x⎵Subscript⎵1 = 1;

SetDirectory[NotebookDirectory[]];

Save["OutPut.m", x⎵Subscript⎵1]

(When the Notation package is loaded and subscripts are Symbolized this is the translation made by ToString[expr, InputForm].)

If your package will be loaded from within the Front End then it is possible to load the Notation package. Since packages are not written in Box Form we will need to manually apply ToExpression to our lines of code. Your package might look like:

ClearAll["Global`*"]

Needs["Notation`"]

Symbolize[ParsedBoxWrapper[SubscriptBox["x", "i_"]]]

\(x\_1 = 1\) // ToExpression

\(Save[\("OutPut.m", x\_1\)]\) // ToExpression

This does work when loaded from a Notebook with Get, producing a file:

x\[UnderBracket]Subscript\[UnderBracket]1 = 1

Expressions may be converted into the shorthand box form (e.g. \(x\_1 = 1\)) using:

Function[, ToString[MakeBoxes @ #, InputForm], HoldAllComplete]
$\endgroup$
  • $\begingroup$ (+1) Thanks for the nice and detailed answer. I have lots of indexed symbols in my code and it is really annoying to change them one by one. Do you have any further suggestion or improvement according to this issue? :) $\endgroup$ – H. R. May 31 '17 at 11:59
  • $\begingroup$ @H.R. I did not (yet) attempt an automated export solution. Which format interests you? (Assuming one does.) $\endgroup$ – Mr.Wizard May 31 '17 at 12:02
  • $\begingroup$ I think your first solution (x⎵Subscript⎵1) which matches the default output format of mathemtica for indexed symbols is suitable. :) $\endgroup$ – H. R. May 31 '17 at 12:06
  • $\begingroup$ @H.R. Okay, I shall see what I can do with that tomorrow. (I am at the end of my day.) $\endgroup$ – Mr.Wizard May 31 '17 at 12:09
  • $\begingroup$ I really appreciate your help. :) $\endgroup$ – H. R. May 31 '17 at 12:11

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.