我正在尝试创建一些能够很好地处理条件概率的函数。到目前为止,我有以下内容:
\usepackage{xparse}
\NewDocumentCommand \prob { >{\SplitArgument{1}{|}} m } {
\probc #1
}
\NewDocumentCommand \probc { m m } {
\ensuremath{\mathbb{P}\!\left(#1\IfValueT{#2}{\;\middle\vert\;#2}\right)}
}
这似乎效果不错。现在,我想编写一个新函数\problm
,它的功能与 相同\prob
,但它包装了 中的每个(1 个或可能是 2 个)参数\texttt
。(lm
中的\problm
表示语言模型;在语言模型的上下文中编写概率时,我希望跳过必须将\texttt
所有输入写入 的步骤\prob
。)
为了做到这一点,我尝试了以下方法:
\NewDocumentCommand \problm { >{\SplitArgument{1}{|}} m } {
\probc \ProcessList{#1}{\texttt}
}
但是,这不起作用。为什么会失败?我怎样才能以干净、简洁的方式完成我想做的事情?理想情况下,解决方案只使用默认或xparse
命令,但如果有一个更简单的解决方案,使用完全不同的工具集,那么它也可能很有用!
顺便说一句,我知道我可以编写一个\problmc
看起来几乎像\probc
但\texttt
插入了一些的新函数,但我想重用底层probc
函数。
答案1
我将定义一个通用命令,我们可以将我们想要的真实参数的“装饰”传递给它。
它看起来比你想象的要复杂,因为我真的不喜欢无条件地使用\left
和\right
。
您可以跟踪各种情况来了解如何选择括号和中间分隔符的大小。
\documentclass{article}
\usepackage{amsmath,amssymb}
\NewDocumentCommand{\genericprob}{m s o >{\SplitArgument{1}{|}}m }{%
% #1 = decoration, #2 = * for automatic sizing, #3 = optional size
% #4 = argument
\mathbb{P}
\IfBooleanTF{#2}
{% automatic sizing
\!\left(%
\genericprobaux{#1}{\;\middle|\;}#4%
\right)%
}%
{% no automatic sizing
\IfNoValueTF{#3}
{% normal size
(\genericprobaux{#1}{\mid}#4)%
}
{% optional sizing
\mathopen{#3(}\genericprobaux{#1}{\mathrel{#3|}}#4\mathclose{#3)}%
}%
}%
}
\NewDocumentCommand{\genericprobaux}{mmmm}{%
#1{#3}%
\IfValueT{#4}{#2#1{#4}}%
}
\NewDocumentCommand{\prob}{}{\genericprob{}}
\NewDocumentCommand{\problm}{}{\genericprob{\mathtt}}
\begin{document}
First of all a paragraph to show why it is in general not advisable to
use automatic sizing; here's an example inspired from a picture in Math.SE
taken from a paper typeset with \TeX{} where \verb|\prob*| does
automatic size $\prob*{\bigcup\limits_{g\in B_j}g(R)}$; this uses the
dreaded \verb|\limits|, but even without it the result is not optimal:
compare $\prob*{\bigcup_{g\in B_j}g(R)}$ with $\prob[\big]{\,\bigcup_{g\in B_j}g(R)}$
and judge for yourself.
\begin{gather*}
\prob{x}\ne\prob{x|y}
\\
\prob[\Big]{x}\ne\prob[\bigg]{x|y}
\\
\prob*{\frac{x}{2}}\ne\prob*{\frac{x}{2}|y}
\\
\problm{x}\ne\problm{x|y}
\\
\problm[\Big]{x}\ne\problm[\bigg]{x|y}
\\
\problm*{\frac{x}{2}}\ne\problm*{\frac{x}{2}|y}
\end{gather*}
Inspiring picture at \texttt{https://math.stackexchange.com/q/4038452/62967}
\end{document}
当然,最后一行实际上没有什么意义,只是为了说明。
显示的方程式之前的段落说明了为什么自动调整大小不是最好的。我相信这个例子是不言自明的。在使用的公式中\big
,需要一个细小的空格。排版并不简单,但只要有一定经验,在查看打印输出之前就会看到这些冲突。
那怎么样\ensuremath
?你只是在交换两个密钥时失去了语义。
最重要的是:如何\prob
没有参数?因为它的定义由 组成\genericprob{}
,其余参数由这个更通用的宏获取。这避免了代码重复:我们可以用\problm
不同的“装饰”定义和其他命令。
答案2
您的\ProcessList
之前未求值\probc
,因此参数\probc
采用\ProcessList
和{#1}
,这显然不是您想要的。相反,您可以引入另一个包装器宏来包裹\texttt
您的输入。
\documentclass[]{article}
\usepackage{xparse}
\usepackage[]{amssymb}
\NewDocumentCommand \prob { >{\SplitArgument{1}{|}} m }
{\probc #1}
\NewDocumentCommand \probc { m m }
{\mathbb{P}\!\left(#1\IfValueT{#2}{\;\middle\vert\;#2}\right)}
\NewDocumentCommand \problm { >{\SplitArgument{1}{|}} m }
{\problmc#1}
% we have to test for a value here as well, otherwise the value test in `\probc` wouldn't work due to the `\texttt`.
\NewDocumentCommand \problmc { m m }
{\IfValueTF{#2}{\probc{\texttt{#1}}{\texttt{#2}}}{\probc{\texttt{#1}}{#2}}}
\begin{document}
$\problm{language1}$
$\problm{language1|language2}$
\end{document}