Crear una macro para muchas diferenciaciones parciales.

Crear una macro para muchas diferenciaciones parciales.

Por favor mire el siguiente MWE:

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand\pdiff{s o m O{1} g O{1} g O{1}}% Star, function, variable 1, how many differentiations, ...
 {\newcount\pdiffn% Count the number of differentiations
  \advance\pdiffn #4\relax%
  \IfValueT{#5}{\advance\pdiffn #6\relax}%
  \IfValueT{#7}{\advance\pdiffn #8\relax}%
  \frac%
   {\partial \ifnum\pdiffn >1\relax ^{\the\pdiffn} \fi%
    \IfValueT{#2}{#2}}%
   {\IfValueT{#7}{\mathinner{\partial #7 \ifnum#8 >1\relax ^{#8} \fi}}%
    \IfValueT{#5}{\mathinner{\partial #5 \ifnum#6 >1\relax ^{#6} \fi}}%
    \mathinner{\partial #3 \ifnum#4 >1\relax ^{#4} \fi}}}

\begin{document}

\Huge

\[ \pdiff[f(x,y,z)]{y} \]

\[ \pdiff[f(x,y,z)]{y}[3]{x}{z} \]

\[ \pdiff[f(x,y,z)]{y}[9999]{x}[3333]{z}[8888] \]

\end{document}

(Ignore el argumento del tipo de estrella, lo usé para crear una fractura plana (ahora no es necesario).)

Esto funciona bien si la diferenciación se restringe a 3 variables. ¿Existe la posibilidad de extender esta macro a más variables? De esta forma no funcionará, porque ya hay 8 argumentos.

Conozco "SplitList" y "ProcessList" pero aquí es más complicado porque tengo que sumar el número de diferenciaciones para cada variable.

¿Algunas ideas?

ingrese la descripción de la imagen aquí

Respuesta1

Un listofitemsenfoque que utiliza valores clave. La sintaxis es, por ejemplo.

\pdiff[y=3,x,z,p=2,d=3,q,r=2,s]{f(x,y,z,p,d,q,r,s)}

Aquí está el MWE

\documentclass{article}
\usepackage{listofitems,tikz}
\newcounter{totalindex}
\newcommand\pdiff[2][1]{%
  \setsepchar{,/=}%
  \readlist\Partialvars{#1}%
  \setcounter{totalindex}{0}%
  \foreach \Varindex in {1,...,\listlen\Partialvars[]}%
    {%
      \ifnum\listlen\Partialvars[\Varindex]>1\relax%
        \addtocounter{totalindex}{\Partialvars[\Varindex,2]}%
      \else%
        \stepcounter{totalindex}%
      \fi%
    }%
    \frac{\partial\ifnum\thetotalindex>1\relax^{\thetotalindex}\fi#2}%
         {%
          \foreach\Varindex in {1,...,\listlen\Partialvars[]}%
           {%
             \partial\Partialvars[\Varindex,1]%
             \ifnum\listlen\Partialvars[\Varindex]>1\relax^{\Partialvars[\Varindex,2]}\fi%
           }%
         }%
}
\begin{document}
\[ \pdiff[y]{f(x,y,z)} \]
\[ \pdiff[y=3,x,z]{f(x,y,z)} \]
\[ \pdiff[y=9999, x=3333, z=8888]{f(x,y,z)} \]
\[ \pdiff[y=3,x,z,p=2,d=3,q,r=2,s]{f(x,y,z,p,d,q,r,s)} \]
\end{document}

ingrese la descripción de la imagen aquí

Si bien el tikz \foreachbucle, utilizado anteriormente, es una construcción fácilmente comprensible para recorrer un índice, se puede eliminar el uso del tikzpaquete por completo, utilizando la construcción de bucle integrada en el listofitemspaquete. Sin embargo, en este caso, el bucle se realiza a través de los elementos de la lista y se puede acceder indirectamente al número de índice mediante \<loop-variable>cnt.

\documentclass{article}
\usepackage{listofitems}
\newcounter{totalindex}
\newcommand\pdiff[2][1]{%
  \setsepchar{,/=}%
  \readlist\Partialvars{#1}%
  \setcounter{totalindex}{0}%
  \foreachitem \Var \in \Partialvars[]%
    {%
      \ifnum\listlen\Partialvars[\Varcnt]>1\relax%
        \addtocounter{totalindex}{\Partialvars[\Varcnt,2]}%
      \else%
        \stepcounter{totalindex}%
      \fi%
    }%
    \frac{\partial\ifnum\thetotalindex>1\relax^{\thetotalindex}\fi#2}%
         {%
          \foreachitem \Var \in \Partialvars%
           {%
             \partial\Partialvars[\Varcnt,1]%
             \ifnum\listlen\Partialvars[\Varcnt]>1\relax^{\Partialvars[\Varcnt,2]}\fi%
           }%
         }%
}
\begin{document}
\[ \pdiff[y]{f(x,y,z)} \]
\[ \pdiff[y=3,x,z]{f(x,y,z)} \]
\[ \pdiff[y=9999, x=3333, z=8888]{f(x,y,z)} \]
\[ \pdiff[y=3,x,z,p=2,d=3,q,r=2,s]{f(x,y,z,p,d,q,r,s)} \]
\end{document}

Respuesta2

No hace falta reinventar la rueda: ya existe un paquete específico: esdiff, que también gestiona los puntos de evaluación como índices:

\documentclass{article}

\usepackage{esdiff}

\begin{document}

    \[ \diffp{f(x, y, z)}{{x^{3333}}{y^{9999}}{z^{8888}}{t^{55555}}} \]%

    \[ \diffp*{f(x, y, z)}{{x^{3333}}{y^{9999}}{z^{8888}}{t^{55555}}}{(x_0,y_0,z_0,t_0)} \]%

\end{document} 

ingrese la descripción de la imagen aquí

Respuesta3

Puede utilizar una lista separada por comas para la lista de variables. Yo uso la convención que

x/2,y/3,z

significa "dos vecesX, tres vecesyy una vezz”. También puedes utilizar x/2,y/3,z/1, si lo prefieres.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\pdiff}{smm}
 {
  \IfBooleanTF{#1}
   {% with \pdiff* call the inner function for inline
    \egreg_pdiff_inline:nn { #2 } { #3 } % TO DO
   }
   {% with \pdiff call the inner function for display
    \egreg_pdiff_frac:nn { #2 } { #3 }
   }
 }

% allocate some variables
\int_new:N \l__egreg_pdiff_total_int
\seq_new:N \l__egreg_pdiff_vars_seq
\seq_new:N \l__egreg_pdiff_var_seq
\tl_new:N \l__egreg_pdiff_denom_tl

\cs_new_protected:Nn \egreg_pdiff_frac:nn
 {
  % clear the variables to be given values later
  \int_zero:N \l__egreg_pdiff_total_int
  \tl_clear:N \l__egreg_pdiff_denom_tl
  % split the second argumen at commas
  \seq_set_split:Nnn \l__egreg_pdiff_vars_seq { , } { #2 }
  % map this sequence for adding to the denominator and
  % computing the number of derivatives
  \seq_map_function:NN \l__egreg_pdiff_vars_seq \__egreg_pdiff_var:n

  % now print:
  % \l__egreg_pdiff_total_int is set to the number of derivatives
  % \l__egreg_pdiff_denom_tl contains the denominator
  \frac
   {
    \partial
    \int_compare:nT { \l__egreg_pdiff_total_int > 1 }
     { \sp { \int_to_arabic:n { \l__egreg_pdiff_total_int } } }
    #1
   }
   {
    \tl_use:N \l__egreg_pdiff_denom_tl
   }
 }

\cs_new_protected:Nn \__egreg_pdiff_var:n
 {
  % split the argument at / (it should be in the form 'x' or 'x/2')
  \seq_set_split:Nnn \l__egreg_pdiff_var_seq { / } { #1 }
  % if the sequence has one term, no exponent is present
  \int_compare:nTF { \seq_count:N \l__egreg_pdiff_var_seq < 2 }
   {% simple variable: add to the denominator and increment the number
    \tl_put_right:Nn \l__egreg_pdiff_denom_tl { \partial #1 }
    \int_incr:N \l__egreg_pdiff_total_int
   }
   {% multiple: add to the denominator and increment the number
    % item 1 contains the variable, item 2 the exponent
    \tl_put_right:Nx \l__egreg_pdiff_denom_tl
     {
      \partial
      \seq_item:Nn \l__egreg_pdiff_var_seq { 1 }
      \sp { \seq_item:Nn \l__egreg_pdiff_var_seq { 2 } }
     }
    \int_add:Nn \l__egreg_pdiff_total_int { \seq_item:Nn \l__egreg_pdiff_var_seq { 2 } }
   }
 }
\ExplSyntaxOff

\begin{document}

\[
\pdiff{f(x,y)}{x}
\quad
\pdiff{f(x,y,z)}{x/20,y/32,z}
\]

\end{document}

ingrese la descripción de la imagen aquí

Respuesta4

ActualizarVea una versión mejor al final.

Aunque existen paquetes para conseguirlo, os presento otra forma, ya que xparseaquí ya se encarga ;-)

Una forma de expl3dividir una lista de especificadores de derivados y crear una lista de tokens:

Sintaxis: \pdiff{x/3,y/4,z/17}{f(x,y,z)}especificaría la tercera derivada. con respecto a x, el cuarto con respecto a y y el 17 con respecto a z.

La omisión del poder o la /voluntad se interpretará como orden derivada 1.

(Se debe agregar una marca para detectar números negativos accidentales)

El argumento de la función no se evalúa ni se verifica.

El número de derivados se calcula internamente.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\cs_generate_variant:Nn \int_add:Nn {Nx}
\seq_new:N \l_pdiff_deriv_seq

\NewDocumentCommand{\pdiffs}{mm}{%
  \int_zero:N \l_tmpa_int
  \seq_set_from_clist:Nn \l_tmpa_seq {#1} % Split the comma list
  \seq_map_inline:Nn \l_tmpa_seq {% Traverse the local entries
    \seq_set_split:Nnn \l_tmpb_seq {/} {##1}% Split into variable and order
    \tl_put_right:Nn \l_tmpa_tl {\partial}% Built the nominator list
    \int_compare:nNnTF {\seq_count:N \l_tmpb_seq } = {\c_one} {% Is there only one split element?
      \seq_put_right:Nn \l_tmpb_seq {\c_one}% Yes
      \tl_put_right:Nx \l_tmpa_tl {\seq_item:Nn \l_tmpb_seq {1}} % Add now 'power'
    }{%
      \int_compare:nNnTF {\seq_item:Nn \l_tmpb_seq {2}} = {\c_one } {
        % Is the derivative order one --> no power? 
        \tl_put_right:Nx \l_tmpa_tl {\seq_item:Nn \l_tmpb_seq {1}}
      }{
        \tl_put_right:Nx \l_tmpa_tl {\seq_item:Nn \l_tmpb_seq {1}^{\seq_item:Nn \l_tmpb_seq  {2}}}
      }
    }
    \int_add:Nx \l_tmpa_int {\seq_item:Nn \l_tmpb_seq {2}}
  }
  % Display the list
  \mathinner{\frac{\partial^{\int_use:N\l_tmpa_int}#2}{\tl_use:N \l_tmpa_tl}}
}
\ExplSyntaxOff


\begin{document}

\Huge

\[\pdiffs{x/5,y/3}{f(x,y,z)}\]


\[\pdiffs{x/4,y/8,z/17}{f(x,y,z)}\]


\end{document}

ingrese la descripción de la imagen aquí

Versión mejorada con comprobaciones y autoexpansión de las variables:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\cs_generate_variant:Nn \int_add:Nn {Nx}
\cs_generate_variant:Nn \int_set:Nn {Nx}

\seq_new:N \l_pdiff_var_seq



\msg_new:nnn {pdiff}{negativedifforder}{Error:~The~order~of~derivative~is~negative~for~variable~#1!} 


\NewDocumentCommand{\pdiffs}{mm}{%
  \int_zero:N \l_tmpa_int
  \tl_clear:N \l_tmpa_tl
  \seq_clear:N \l_pdiff_var_seq
  \seq_set_from_clist:Nn \l_tmpa_seq {#1}
  \seq_map_inline:Nn \l_tmpa_seq {%
    \seq_set_split:Nnn \l_tmpb_seq {/} {##1}
    \seq_put_right:Nx \l_pdiff_var_seq {\seq_item:Nn \l_tmpb_seq {1}}
    \int_compare:nNnTF {\seq_count:N \l_tmpb_seq } = {\c_one} {
      \int_set:Nn \l_tmpb_int {\c_one}
      \seq_put_right:Nn \l_tmpb_seq {\c_one}
      \tl_put_right:Nn \l_tmpa_tl {\partial}
      \tl_put_right:Nx \l_tmpa_tl {\seq_item:Nn \l_tmpb_seq {1}}
    }{%
      \int_set:Nx \l_tmpb_int {\seq_item:Nn \l_tmpb_seq {2}}
      \int_compare:nNnTF { \l_tmpb_int } < {\c_zero} {
        \msg_fatal:nnx {pdiff}{negativedifforder}{\seq_item:Nn \l_tmpb_seq {1}}
      }{%
        \int_compare:nNnF {\l_tmpb_int } = {\c_zero} {%
          \tl_put_right:Nn \l_tmpa_tl {\partial}
          \int_compare:nNnTF{ \l_tmpb_int } = {\c_one } {
            \tl_put_right:Nx \l_tmpa_tl {\seq_item:Nn \l_tmpb_seq {1}}
          }{%
            \tl_put_right:Nx \l_tmpa_tl {\seq_item:Nn \l_tmpb_seq {1}^{\seq_item:Nn \l_tmpb_seq  {2}}}
          }
        }
      }
    }
    \int_add:Nx \l_tmpa_int {\l_tmpb_int}
  }
  \mathinner{\frac{\partial^{\int_use:N\l_tmpa_int}#2(\seq_use:Nn \l_pdiff_var_seq {,})}{\tl_use:N \l_tmpa_tl}}
}
\ExplSyntaxOff


\begin{document}

\Huge

\[\pdiffs{x/5,y/3,z/0}{f}\]


\[\pdiffs{x/4,y/8,z/17}{f}\]


\end{document}

información relacionada