我正在尝试扩展给出的宏 我可以有一个灵活的偏导数宏吗? 具体来说,我想添加一个带星号的版本,它不会尝试对各种导数的指数求和,如果指数不是数字,这将很有用。我的尝试如下所示,但我没有取得太大进展。我希望命令的工作方式显示在第二个显示的数学环境中。理想情况下,我只有一个命令,它的行为将如第三个显示的数学环境中所示,但这似乎过于雄心勃勃。
\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}
答案1
从描述来看,您想要的是自动检测非数字输入。这意味着您不需要\derivative*
但可以将决定权留给代码。稳健性可能是一个问题:在下面,我假设每个索引都有一个标记(可以解决)。正如您在“传统”LaTeX 中编码的那样,我尽可能坚持相同的方法:
\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}
关键思想是设置一个标志来指示存在非数字索引值,然后使用该标志确定如何构造输出。
(如果有兴趣,我认为 LaTeX3 版本会更具可读性:我们在那里没有整数测试,但各种扩展问题会更容易解决。)
答案2
我认为 LuaTeX 非常适合这类任务。这是 ConTeXt 中的概念验证解决方案(要转换为 LuaLaTeX,您还需要移植utilities.parsers.settings_to_array
函数;请参阅util-prs.lua
ConTeXt 树中的文件以了解此功能的实现细节)
\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
这使