Mathematica Q&A Series: Converting to Conventional Mathematical Typesetting
Got questions about Mathematica? The Wolfram Blog has answers! We’ll regularly answer selected questions from users around the web. You can submit your question directly to the Q&A Team.
This week’s question comes from Jee:
How can I transform the output of partial differentiation such as f(1, 0)[x, y] to the mathematical form ?
Read below or watch this screencast for the answer (we recommend viewing it in full-screen mode):
We will assume that the reader is already familiar with the basics of differentiation in Mathematica. To quickly catch up with the topic, one should read the recent Q&A blog post “Three Functions for Computing Derivatives”.
The typesetting in which derivatives are displayed in Mathematica may vary depending on the situation. Yet they are all interpreted through the function Derivative, which is an equivalent of the differential operator in traditional mathematics. Take a look at the following list, where each element represents a different way differentiation can be entered:
For the last element we used the key sequence Esc + d + t + Esc. Despite different appearances, the underlying expressions are of the same syntax, which can be revealed with the function InputForm:
If one deals with differentiation of undefined functions, the output will always be of the form shown in the left column, dictated by the underlying syntax of the right column. How does one go from this typesetting to other conventional mathematical notations? Well, we can start by using the function TraditionalForm, which was created exactly for this purpose:
This is a type of traditional mathematical notation where partial derivatives are denoted by indexes in the function’s superscript. Yet this is not what Jee is looking for, which is a convention that uses the symbol ∂. The full list of Mathematica syntax that may be displayed via TraditionalForm as a conventional notation can be found in the extensive tables of the tutorial TraditionalForm Reference Information. We can learn from it that the notation we need can be provided by the function D:
The function Defer was used to prevent Mathematica from automatic evaluation from the syntax of function D to the one of function Derivative. Great, but what if after some derivations we end up with an answer given in terms of indexed notation? How do we display it in terms of the symbol ∂? Well, we can construct a function that reads out the elements of syntax given by Derivative, puts them in the form of D, and applies TraditionalForm:
To better understand the structure of the function, consider the table below.
In the particular case considered, pdConv will read indexes 0, 1, and 2; variables x, y, and z; and function name f from the syntax provided by Derivative and put them in the syntax of function D. The function pdConv will then use Defer and TraditionalForm to display the result in desired conventional typesetting. Note that zero- and first-order derivatives are “Special Cases” labeled in the last row. They should be displayed differently compared to higher-order derivatives, and are handled in the last line of pdConv.
Function pdConv will now work with any properly defined expression. Here is a computation that ends up displayed according to the underlying Derivative syntax:
Applying our function pdConv will typeset this expression in terms of the symbol ∂:
After we copy and evaluate the output cell, the Defer function used inside pdConv will release its hold on the evaluation:
And so this expression is still computable. For example an explicit function can be substituted instead of f(x, y, z) for further evaluation:
Hence Mathematica allows computing with expressions in traditional mathematical typesetting if they are properly defined, unlike many other systems that only help to format and display the typesetting. The function pdConv acts simply as TraditionalForm with respect to any other part of an expression that is not related to Derivative:
Click here to download this post as a Computable Document Format (CDF) file.
If you have a question you’d like answered in this blog, you can submit it to the Q&A Team. For daily bite-sized Mathematica tips, follow our @MathematicaTip Twitter feed.
Cute, I’ve never used it before. Looks perfect. Also TeXForm is helpful… And it’s amusing to listen to the Russian accent.
Nice! Another option would be to use the same code tied into MakeBoxes:
Derivative /: MakeBoxes[Derivative[inds__][g_][vars__], TraditionalForm] := ToBoxes[Apply[Defer[D[g[vars], ##]] &,
Transpose[{{vars}, {inds}}] /. {{var_, 0} :>
Sequence[], {var_, 1} :> {var}}], TraditionalForm]
Now TraditionalForm will display the derivatives the fractional notation, e.g., f'[x] // TraditionalForm
thx a lot
It’s very helpful. I can say goodbye to Maple now. 哈哈~~
It will only work if the derivative is calculated at a symbol.
Try this:
pdConv[Derivative[1][f][3 x + 1]]
I would add that provision as Derivative[inds__][g_][vars__Symbol]
Amazing for how many years I had to put together so many Format Statements…Free at Last….
Is there any reason why the Output provided by pdConv isnt built-in to Mathematica?…Is there a reason that someone would want f^(1,0)[x,y] in the First Place??….I never did….I could see a lot more pleased faces using Mathematica if Derivatives, just like you write them with pencil and paper, would be Standard output….
Like MakeBoxes Solution from the other Comments Better….I dont have to use //pdConv every time I write a formula….I just run MakeBoxes once and it works every time…
It’s nice that this solution allows a round-trip between the different forms, but I sometimes want an even more compact TraditionalForm for readability and would be willing to sacrifice the round-trip computability. So here is another suggestion that leaves out the function arguments, and also uses straight DifferentialD symbols when there is only a single variable (I used some tricks from the above comments but don’t use the detour via D[…] because I wanted to sneak in an If statement). The same method could probably also produce a round-trip capable output, but that’s not what I was after.
Derivative /:
MakeBoxes[Derivative[\[Alpha]__][f1_][vars__Symbol],
TraditionalForm] := Module[{dd},
ToBoxes[
If[Length[{\[Alpha]}] == 1,
MakeBoxes[dd, TraditionalForm] ^= “\[DifferentialD]”,
MakeBoxes[dd, TraditionalForm] ^= “\[PartialD]”];
Row[{dd^Total[{\[Alpha]}], f1}]/
Row[Map[Row[{dd, #}] &,
Select[({vars}^{\[Alpha]}), (# =!= 1 &)]], “\[ThinSpace]”],
TraditionalForm]
]
The quotation marks in my last post seem to have gotten replaced by the wrong unicode characters. Not very nice for posting code.
Notwithstanding, I’ll try again with a different version: the output again suppresses the function arguments and outputs straight derivatives (DifferentialD) in TraditionalForm when appropriate. But now the output can also be re-used by copying it into an input cell. The straight derivatives are then translated to Dt[…] instead of Derivative[…].
Derivative /:
MakeBoxes[Derivative[\[Alpha]__][f1_][vars__Symbol],
TraditionalForm] := Module[{bb, dd, sp},
MakeBoxes[dd, _] ^=
If[Length[{\[Alpha]}] == 1, “\[DifferentialD]”, “\[PartialD]”];
MakeBoxes[sp, _] ^= “\[ThinSpace]”;
bb /: MakeBoxes[bb[x__], _] := RowBox[Map[ToBoxes[#] &, {x}]];
FractionBox[ToBoxes[bb[dd^Plus[\[Alpha]], f1]],
ToBoxes[Apply[bb,
Riffle[Map[bb[dd, #] &,
Select[({vars}^{\[Alpha]}), (# =!= 1 &)]], sp]]]]
]
An example would be:
D[f[g[x]] + h[x, y], {x, 2}] // TraditionalForm
Note the parenthesis around the squared derivative in the first term of the output: the original solution that started this page is missing this parenthesis, and it uses only partial derivative symbols.
Moreover, the output in this example is correctly translated back if I copy and paste it and manually insert the argument “(x,y)” in the partial derivative (that’s the price I have to pay for a more compact appearance in the output).
Correction regarding the missing parenthesis I mentioned in my last post: it’s not missing when using the original function pdConv defined above, but when applying the same function as an UpValue definition following Simon’s post.
Is anyone familiar with blocking matrices? I have a function to block four matrices. I have successfully used the function several times, but as my matrices get larger I am starting to lose rows..