# Can I have a flexible partial derivative macro?

I was thinking about writing a partial derivative macro that has a similar syntax to the Mathematica D function. (example)

The syntax could be like this:

• \D{f}{x} expands to \frac{\partial f}{\partial x}
• \D{f}{x,y} expands to \frac{\partial^2 f}{\partial x\,\partial y}
• \D{f}{{x,2},y} expands to \frac{\partial^3 f}{\partial x^2\,\partial y}
• et cetera for any number of derivatives.

Bonus points for an optional argument so that for instance

• \D[subscript]{f}{{x,2},y} expands to f_{xxy}

I looked at the commath package but the syntax is a little tedious. For instance, to get \frac{\partial^3 f}{\partial x^2\,\partial y} with that package I would need to do \md{f}{3}{x}{2}{y}{}. And it doesn't generalize to three variables.

Before I dive in I thought I'd ask the hive and see what's been done.

-
Have you seen the cool package? – Torbjørn T. Jul 1 '11 at 20:52
@Torbjorn: cool is cool indeed! So I can use \pderiv[2,1]{f}{x,y} to get \frac{\partial^3 f}{\partial x^2\,\partial y}. – Matthew Leingang Jul 1 '11 at 21:16
@Torbjorn: if you will repost your comment as an answer I will accept it. I'm going with cool for this and other reasons. – Matthew Leingang Jul 7 '11 at 19:14
This must be something that every mathematician does. I think my first "serious" macros were (simple) versions of this. I'll definitely investigate the answers to this. – Andrew Stacey Jul 7 '11 at 20:54
Did you experience any errors with the \pderiv macro? Specifically, when having more than one power in the optional argument. (See the comments to my answer.) – Torbjørn T. Sep 28 '11 at 12:51
show 1 more comment

## 4 Answers

The cool package offers commands for writing partial derivates (and a lot of other stuff).

A short example:

\documentclass{article}
\usepackage{cool}
\begin{document}
\begin{equation*}
\pderiv{f}{x} \qquad
\pderiv[2,3]{f}{x,y} \qquad
\pderiv[1,n,4]{f}{x,y,z}
\end{equation*}
\end{document}


# Note

By default the last two of those will not work, as there is a bug in the package. This can be fixed by changing a \def to \edef in line 2059 of cool.sty, see Basic use of derivative with cool package fails with "Missing \endcsname inserted"

-
 I was just trying this out (from curiosity) and found that if I put more than one power in the first (optional) argument to the \pderiv then it complains vociferously. Any chance you could post a MWE? I'm sure I'm just doing something silly. – Andrew Stacey Sep 22 '11 at 8:53 @AndrewStacey Maybe not, I get an error as well, from examples copied directly from the cool demo file: ! Missing endcsname inserted. \toks@. I've never really used the package myself, I just stumbled upon it at one point, and remembered it for this question. Not sure what is going on ... – Torbjørn T. Sep 22 '11 at 10:56

I have this, which is quite similar to what you want:

\documentclass[a4paper]{article}

\makeatletter
\newcommand{\der}[2]{\begingroup
\@tempswafalse\toks@={}\count@=\z@
\@for\next:=#2\do
{\expandafter\check@var\next
\advance\count@\der@exp
\if@tempswa
\toks@=\expandafter{\the\toks@\,}%
\else
\@tempswatrue
\fi
\toks@=\expandafter{\the\expandafter\toks@\expandafter\partial\der@var}}%
\frac{\partial\ifnum\count@=\@ne\else^{\number\count@}\fi#1}{\the\toks@}%
\endgroup}
\def\check@var{\@ifstar{\mult@var}{\one@var}}
\def\mult@var#1#2{\def\der@var{#2^{#1}}\def\der@exp{#1}}
\def\one@var#1{\def\der@var{#1}\chardef\der@exp\@ne}
\makeatother

\begin{document}
$\der{f}{x}\qquad \der{f}{*{2}{x},y}\qquad \der{f}{*{3}{x},y,*{4}{z}}$
\end{document}


EDIT: the following code will render correctly also

\pder{f}{\mathbf{x}}
\pder{f_1}{x_1}


Here it is:

\makeatletter
\newcommand{\der}[2]{\begingroup
\@tempswafalse\toks@={}\count@=\z@
\@for\next:=#2\do
{\expandafter\check@var\next\@nil
\advance\count@\der@exp
\if@tempswa
\toks@=\expandafter{\the\toks@\,}%
\else
\@tempswatrue
\fi
\toks@=\expandafter{\the\expandafter\toks@\expandafter\partial\der@var}}%
\frac{\partial\ifnum\count@=\@ne\else^{\number\count@}\fi#1}{\the\toks@}%
\endgroup}
\def\check@var{\@ifstar{\mult@var}{\one@var}}
\def\mult@var#1#2\@nil{\def\der@var{#2^{#1}}\def\der@exp{#1}}
\def\one@var#1\@nil{\def\der@var{#1}\chardef\der@exp\@ne}
\makeatother

-
Interesting. Did you use the stars to mimic tabular preambles? – Matthew Leingang Jul 1 '11 at 20:33
Reading the code, I see now you used stars so you could implement it with \@ifstar. Clever. – Matthew Leingang Jul 1 '11 at 20:35
@Matthew: yes, the *{2}{x} comes from the tabular preambles, and, yes, it makes convenient to use \@ifstar. :) – egreg Jul 1 '11 at 21:07
@egreg: The following two lines $\der{f}{\mathbf{n}}$ $\def{f_1}{x_1}$ do not process correctly. Is it possible to fix the macro so they do? Thanks. – rogerl Oct 4 '11 at 15:34

Here my try. I prefer a more simply input format: \Der{<var>}{<var><num>,<var><num>,...} e.g. \Der{f}{x3,y,z4}. This also works for more complicated input like \Der{f}{{\hat{x}}3,y105}.

\documentclass{article}

\makeatletter

\newcommand\Der[2]{%
\begingroup
\@temptokena{\@gobble}%
\@tempcnta\z@
\@for\var:=#2\do{%
\expandafter\@Der\var\relax
}%
\ensuremath{\frac{\partial
\ifnum\@tempcnta>\@ne
^{\the\@tempcnta}%
\fi
#1}{\the\@temptokena}}%
\endgroup
}

\def\@Der#1#2\relax{%
\ifx\relax#2\relax
\advance\@tempcnta by \@ne
\@temptokena\expandafter{\the\@temptokena\,\partial{#1}}%
\else
\advance\@tempcnta by #2\relax
\@temptokena\expandafter{\the\@temptokena\,\partial{#1}^{#2}}%
\fi
}

\makeatother

\usepackage{amsmath}
\begin{document}

$\Der{f}{x} \qquad \Der{f}{x,y} \qquad \Der{f}{x2,y}$

$\Der{f}{x}\qquad \Der{f}{x2,y}\qquad \Der{f}{x3,y,z4}$

$\Der{f}{{\hat{x}}3,y1,z10}$

\end{document}


It is also possible to avoid the need for commas. I'm thought first this is more readable but I'm not sure about that anymore. This version doesn't support negative numbers (no loss) and might be a little more sensitive than the first.

\documentclass{article}

\makeatletter

\newcommand\Der[2]{%
\begingroup
\@temptokena{\@gobble}%
\@tempcnta\z@
\expandafter\@Der@var#2\relax
\ensuremath{\frac{\partial
\ifnum\@tempcnta>\@ne
^{\the\@tempcnta}%
\fi
#1}{\the\@temptokena}}%
\endgroup
}

\def\@Der@var#1{%
\ifx\relax#1\empty\else
\def\next{\expandafter\@Der@num\expandafter{\the\@tempcntb}{#1}}%
\afterassignment\next
\@tempcntb=0%
\fi
}

\def\@Der@num#1#2{%
\ifnum#1=\z@
\advance\@tempcnta by \@ne
\@temptokena\expandafter{\the\@temptokena\,\partial{#2}}%
\else
\advance\@tempcnta by #1\relax
\@temptokena\expandafter{\the\@temptokena\,\partial{#2}^{#1}}%
\fi
\@Der@var
}

\makeatother

\usepackage{amsmath}
\begin{document}

$\Der{f}{x} \qquad \Der{f}{xy} \qquad \Der{f}{x2y}$

$\Der{f}{x}\qquad \Der{f}{x2y}\qquad \Der{f}{x3 y z4}$

$\Der{f}{{\hat{x}}3y1z10}$

\end{document}


### Result (for both implementations):

-
 Thanks for playing. Both you and egreg used \@for, which means I should learn more about that. – Matthew Leingang Jul 2 '11 at 4:14

The esdiff package should not go unmentioned in this context.

In the meantime there are two other packages which facilitate easy typesetting of derivatives.

-
OK, it's been mentioned. :-) But could you add a code snippet to show how it works? – Matthew Leingang Oct 4 '11 at 17:29
What about just reading the (very short) package manual? I couldn't add any better code examples here. – Thorsten Donig Oct 4 '11 at 19:17
You're right. I just realized that this package does this and nothing else. – Matthew Leingang Oct 5 '11 at 18:55