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

I am trying to expand the macro given in Can I have a flexible partial derivative macro? In particular, I would like to add a starred version that does not attempt to sum the exponents of the various derivatives, which is useful if the exponent isn't a number. My attempt is given below, but I didn't make much progress. The way I would like the command to work is shown in the second displayed math environment. Ideally, I would only have one command, and it would behave as shown in the third displayed math environment, but this seems overly ambitious.

\documentclass[12pt]{article}

\makeatletter
\newcommand\derivative[2]
{
    \begingroup
        \@temptokena{\@gobble}
        \@tempcnta\z@
        \@for\var:=#2\do
        {
            \expandafter\@derivative\var\relax
        }
        \frac
        {
            d
                \ifnum \@tempcnta > \@ne
                    ^{\the\@tempcnta}
                \fi
            #1
        }
        {\the\@temptokena}
    \endgroup
}
\def\@derivative#1#2\relax
{
    \ifx\relax#2\relax
        \advance\@tempcnta by \@ne
        \@temptokena\expandafter{\the\@temptokena \, d #1}
    \else
        \advance\@tempcnta by #2\relax
        \@temptokena\expandafter{\the\@temptokena \, d #1^{#2}}
    \fi
}
\makeatother

\makeatletter
\newcommand\derivativestar[2]
{
    \begingroup
        \@temptokena{\@gobble}
        \@temptokenb{}
        \@for\var:=#2\do
        {
            \expandafter\@derivativestar\var\relax
        }
        \frac
        {
            d^{\@temptokenb} #1
        }
        {\the\@temptokena}
    \endgroup
}
\def\@derivativestar#1#2\relax
{
    % need to test for first token
    \ifx\relax#2\relax
        \@temptokena\expandafter{\the\@temptokena \, d #1}
        \@temptokenb\expandafter{\the\@temptokenb + 1}
    \else
        \@temptokena\expandafter{\the\@temptokena \, d #1^{#2}}
        \@temptokenb\expandafter{\the\@temptokenb + #2}
    \fi
}
\makeatother

\begin{document}

\[
    \derivative{x}{{y}{2},{z}{3}}
\]

\[
    % \derivative*{x}{{y}{m},{z}{n}}
    \frac{d x^{m+n}}{d y^{m} \, d z^{n}}
\]

\[
    % \derivative{x}{{v}{3},{w}{k,2},y,{z}{m}}
    \frac{d x^{k+m+6}}{d v^{3} \, d w^{k+2} \, d y \, d z^{m}}
\]

\end{document}
share|improve this question
    
Good question. I'm not sure if this is easy since you're implementing algebra with TeX. –  Matthew Leingang Mar 6 '13 at 3:34
add comment

2 Answers

up vote 11 down vote accepted

From the description, it seems like what you want is auto-detection of non-numerical input. That means you do not need \derivative* but can leave the decision to the code. Robustness could be an issue: in the following I've assume we have a single token for each index (that can be solved). As you've coded in 'traditional' LaTeX, I've stuck as far as possible to the same approach:

\documentclass[12pt]{article}
\makeatletter
\newcommand{\ifintegerTF}[1]{%
  \ifnum`#1<`0 %
    \expandafter\@secondoftwo
  \else
    \ifnum`#1>`9 %
      \expandafter\expandafter\expandafter\@secondoftwo
    \else
      \expandafter\expandafter\expandafter\@firstoftwo
    \fi  
  \fi
}
\newcommand{\derivative}[2]{%
  \begingroup
    \toks@{}%
    \@temptokena{}%
    \@tempcnta\z@
    \@tempswatrue
    \@for\@tempa:=#2\do{%
      \expandafter\derivative@aux@i\@tempa\stop
    }%
    \frac
      {%
        d%
        \if@tempswa
          \ifnum\@tempcnta>\@ne
            ^{\number\@tempcnta}%
          \fi
          #1%  
        \else
          #1%
          \ifnum\@tempcnta>\z@
            \toks@\expandafter\expandafter\expandafter
              {\expandafter\the\expandafter\toks@ \expandafter + \the\@tempcnta}%
          \fi
          ^{\expandafter\@gobble\the\toks@}%
        \fi
      }
      {\the\@temptokena}
  \endgroup
}
\newcommand{\derivative@aux}{}
\long\def\derivative@aux@i#1#2\stop{%
  \@temptokena\expandafter{\the\@temptokena \, d#1}%
  \ifx\\#2\\
    \advance\@tempcnta\@ne
  \else
    \def\@tempb{\@gobble}%
    \@for\@tempa:=#2\do{%
      \expandafter\derivative@aux@ii\@tempa{#1}%
    }%
   \@temptokena\expandafter\expandafter\expandafter
    {\expandafter\the\expandafter\@temptokena\expandafter^\expandafter{\@tempb}}% 
  \fi
}
\newcommand{\derivative@aux@ii}[2]{%
  \ifintegerTF{#1}
    {\advance\@tempcnta#1 }%
    {%
      \toks@\expandafter{\the\toks@ + #1}%
      \@tempswafalse
    }% 
  \protected@edef\@tempb{\@tempb + #1}%
}


\begin{document}

\[
    \derivative{x}{{y}{2},{z}{3}}
\]

\[
    \derivative{x}{{y}{m},{z}{n}}
\]

\[
    \derivative{x}{{v}{3},{w}{k,2},y,{z}{m}}
\]

\end{document}

The key idea is to set a flag to indicate that there are non-numerical index values, and use that flag to then determine how to construct the output.

(If there is interest, I think a LaTeX3 version of this will be somewhat more readable: we don't have an integer test there but the various expansion issues would be easier to solve.)

share|improve this answer
    
This is nice! But in the second two examples, shouldn't the numerators be d^{m+n}x and d^{m+k+6}x? Also, it would be great to be able to handle, for example, k-2 instead of k+2 in the third example. (Finally, I'd use \partial instead of d, but that's pretty trivial). –  rogerl Mar 6 '13 at 14:35
    
@rogerl I wondered about both of those points, but according to the 'reference' version in the question it seems that is not what is being asked for. My aim was to produce what the questioner wanted, quite apart from any mathematical interpretation! –  Joseph Wright Mar 6 '13 at 14:38
    
Very nice! Sticking to traditional LaTeX was a choice born of ignorance, rather than preference, and, if you have the time and inclination, a solution made using more advanced techniques would also be appreciated. Sorry about the typo in placing the superscripts on the variables instead of the "d"s in the numerators of the examples. –  Stirling Mar 7 '13 at 0:24
    
@Joseph Wright Very helpful!! A request (I couldn't get it to work), could one use the last argument as an optional point of evaluation, like \left|_{#9} \right. kind of thing? –  nate Oct 22 '13 at 20:02
add comment

I think that LuaTeX is ideally suited for such tasks. Here is a proof of concept solution in ConTeXt (to translate to LuaLaTeX, you also need to port utilities.parsers.settings_to_array function; see util-prs.lua file in the ConTeXt tree for implementation details of this function)

\startluacode
  thirddata = thirddata or {}
  -- The pairs() iterator in lua does not guarantee the order in which 
  -- keys are accessed. So, instead of directly using settings_to_list
  -- I use a roundabout iterator.
  local settings_to_array = utilities.parsers.settings_to_array

  local format = string.format
  local split  = string.split

  function thirddata.partialD(settings)
      local list = settings_to_array(settings)

      local sum = 0
      local num = {}
      local den = {}

      for i = 1, #list do
         local s = split(list[i], "=")
         local key, value = s[1], s[2]

         local n = tonumber(value)

         if n ~= nil then
            sum = sum + n
         else
            num[#num + 1] = value
         end

         den[i] = format("\\partial %s^{%s}", key, value)
      end


      num[#num + 1] = sum
      num = table.concat(num, "+")
      den = table.concat(den)

      num  = format("\\partial^{%s}", num)


      context.dfrac( num, den)
  end
\stopluacode

\def\partialD%
  {\dosingleargument\dopartialD}

\unprotected\def\dopartialD[#1]{\ctxlua{thirddata.partialD(\!!bs#1\!!es)}}

\enablemode[lmmath]

\starttext
\startTEXpage[offset=3mm]
$\partialD[u=m, x=1, y=2, z=n]$
\stopTEXpage
\stoptext

which gives

enter image description here

share|improve this answer
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.