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.

In an earlier post I asked a question about writing a flexible derivative macro, and someone suggested that a LaTeX3 version might be easier to understand, so I decided to try my hand at writing one. Unfortunately, I ran into some problems. First, I had trouble getting started with implementing the functionality to sum the numerical derivative orders. In particular, I got an error when I tried adding the command \@tempcnta\z@ to the clean-up portion of my macro. Since my LaTeX knowledge is extremely limited, I don't now another way to add up the numerical derivative orders. I also tried wrapping the command in \ExplSyntaxOff and \ExplSyntaxOn, but this didn't help. Second, the command sometimes requires more braces than I would like. I think the commented example below is a reasonable usage. However, the implementation does not support this, and requires an extra set of braces (as shown immediately below the commented example). I think the basic functionality is there (I'll mostly use the command as shown in the first example), but it'd be nice to get the extra features (summing the numerical derivative orders and eliminating the need for extra braces).

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
    % allocate variables to typeset the derivative
    \tl_new:N \l_myderivative_num_exp_tl
    \tl_new:N \l_myderivative_den_tl
    \tl_new:N \l_myderivative_den_factor_var_flag_tl
    \tl_new:N \l_myderivative_den_factor_exp_tl

    % function to write the derivative
    \NewDocumentCommand{\derivative}{m>{\SplitList,}m}
    {
        % clear any old values
        \tl_clear:N \l_myderivative_num_exp_tl
        \tl_clear:N \l_myderivative_num_exp_flag_tl
        \tl_clear:N \l_myderivative_den_tl
        \tl_clear:N \l_myderivative_den_factor_var_flag_tl
        \tl_clear:N \l_myderivative_den_factor_exp_flag_tl

        % format the denominator
        \tl_map_inline:nn { #2 }
        {
            \myderivative_add_den_factor:n { ##1 }
        }

        % write the derivative
        \frac
        {
            \partial
            \tl_if_empty:NF \l_myderivative_num_exp_flag_tl
            {
                ^{\l_myderivative_num_exp_tl}
            }
            #1
        }
        {
            \l_myderivative_den_tl
        }
    }

    % helper function to process a factor in the denominator
    \cs_new_protected:Npn \myderivative_add_den_factor:n #1
    {
        % clear the variables
        \tl_clear:N \l_myderivative_den_factor_var_flag_tl
        \tl_clear:N \l_myderivative_den_factor_exp_tl

        \tl_if_empty:NF \l_myderivative_den_tl
        {
            % add a thin space if we've already processed at least one factor
            \tl_put_right:Nn \l_myderivative_den_tl { \, }
        }

        % format the factor
        \tl_map_inline:nn { #1 }
        {
            \myderivative_fmt_den_factor:n { ##1 }
        }

        % check for an implicit exponent
        \tl_if_empty:NT \l_myderivative_den_factor_exp_flag_tl
        {
            \tl_if_empty:NF \l_myderivative_num_exp_tl
            {
                \tl_put_right:Nn \l_myderivative_num_exp_flag_tl { 1 }
                \tl_put_right:Nn \l_myderivative_num_exp_tl { + }
            }
            \tl_put_right:Nn \l_myderivative_num_exp_tl { 1 }
        }
    }

    % helper function to format a factor in the denominator
    \cs_new_protected:Npn \myderivative_fmt_den_factor:n #1
    {
        \tl_if_empty:NTF \l_myderivative_den_factor_var_flag_tl
        {
            % if the flag is not set, then we are processing the variable
            \tl_put_right:Nn \l_myderivative_den_tl { \partial #1 }

            % set the flag
            \tl_put_right:Nn \l_myderivative_den_factor_var_flag_tl { 1 }
        }
        {
            % if the flag is set, then we are processing the exponent
            \tl_put_right:Nn \l_myderivative_den_tl { ^{#1} }

            % update the numerator exponent
            \tl_if_empty:NF \l_myderivative_num_exp_tl
            {
                \tl_put_right:Nn \l_myderivative_num_exp_tl { + }
            }
            \tl_put_right:Nn \l_myderivative_num_exp_tl { #1 }

            % set the flag
            \tl_put_right:Nn \l_myderivative_den_factor_exp_flag_tl { 1 }
            \tl_put_right:Nn \l_myderivative_num_exp_flag_tl { 1 }
        }
    }
\ExplSyntaxOff

\begin{document}

\[
    \derivative{f}{xp,yq,zr}
\]

\[
    \derivative{f}{x2,y3,z4}
\]

\[
    \derivative{f}{x}
\]

\[
    \derivative{f}{{\hat{x}}{2},{\tilde{y}}{3}}
\]

%\[
%   \derivative{f}{{\hat{x}}}
%\]

\[
    \derivative{f}{{{\hat{x}}}}
\]

\end{document}
share|improve this question
1  
Any particular reason that you want to do this in pure TeX and not use LuaTeX? –  Aditya Mar 30 '13 at 23:00
    
Well, it's LaTeX, not TeX: that would be even more of a nightmare. I'm trying to learn LaTeX3, and someone mentioned in my earlier post that a solution was possible with LaTeX3, so I decided to try it as a learning exercise. Thanks for your LuaTeX solution in the earlier post, though; that is very nice, too. –  Stirling Apr 4 '13 at 23:52
    
You can use the luatex engine with the latex macro package as well by running the lualatex command. Search for questions tagged lualatex. –  Aditya Apr 5 '13 at 4:44
    
This is a very late comment, but what kind of functionality were you actually looking for? Can you give an example of ideal use? –  Sean Allred Feb 5 at 5:08
1  
Can you give example use cases of what different uses would produce? –  Sean Allred Mar 22 at 16:40

1 Answer 1

An implementation might look something like

\documentclass{article}
\usepackage{expl3,xparse}

\makeatletter
\newcommand{\ifintegerTF}[1]{%
  \ifnum`#1<`0 %
    \expandafter\@secondoftwo
  \else
    \ifnum`#1>`9 %
      \expandafter\expandafter\expandafter\@secondoftwo
    \else
      \expandafter\expandafter\expandafter\@firstoftwo
    \fi  
  \fi
}

\ExplSyntaxOn
\int_new:N \l__stirling_total_int
\seq_new:N \l__stirling_denom_seq
\tl_new:N \l__stirling_denom_tl
\tl_new:N \l__stirling_numer_tl
\seq_new:N \l__stirling_powers_seq
\cs_new_protected:Npn \stirling_derivative:nn #1#2
  {
    \group_begin:
      \int_zero:N \l__stirling_total_int
      \seq_clear:N \l__stirling_powers_seq
      \tl_clear:N \l__stirling_denom_tl
      \clist_map_function:nN {#2} \__stirling_derivative_entry:n
      \int_compare:nNnF \l__stirling_total_int = \c_zero
        {
          \seq_put_right:Nx \l__stirling_powers_seq
            { \int_use:N \l__stirling_total_int }
        }
      \tl_set:Nx \l__stirling_numer_tl
        {
          d
          \seq_if_empty:NF \l__stirling_powers_seq
            {
              ^
                { \seq_use:Nn \l__stirling_powers_seq { + } }
            }
          #1
        }
      \frac { \l__stirling_numer_tl } { \l__stirling_denom_tl }
    \group_end:
  }
\cs_new_protected:Npn \__stirling_derivative_entry:n #1
  {
    \__stirling_derivative_entry_aux:nw #1 \q_stop
  }
\cs_new_protected:Npn \__stirling_derivative_entry_aux:nw #1#2 \q_stop
  {
    \tl_if_empty:NF \l__stirling_denom_tl
      { \tl_put_right:Nn \l__stirling_denom_tl { \, } }
    \tl_if_empty:nTF {#2}
      {
        \int_incr:N \l__stirling_total_int
        \tl_put_right:Nn \l__stirling_denom_tl { d #1 }
      }
      {
        \seq_clear:N \l__stirling_denom_power_seq
        \clist_map_function:nN {#2} \__stirling_derivative_entry_power:n
        \tl_put_right:Nx \l__stirling_denom_tl
          {
            d #1 \exp_not:N ^
              { 
                \seq_use:Nn \l__stirling_denom_power_seq { + }
              }
          }
      }
  }
\cs_new_protected:Npn \__stirling_derivative_entry_power:n #1
  {
    \ifintegerTF {#1}
      { \int_add:Nn \l__stirling_total_int {#1} }
      { \seq_put_right:Nn \l__stirling_powers_seq {#1} }
    \seq_put_right:Nn \l__stirling_denom_power_seq {#1}
  }
\DeclareDocumentCommand \derivative { m m }
  { \stirling_derivative:nn {#1} {#2} }
\ExplSyntaxOff


\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}

I've kept the same \ifintegerTF command as used in the older question, and have fixed the mathematics part raised in the other question. Other than that, it's pretty straight-forward.

share|improve this answer

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.