我有一系列范数宏,我想\left\| ...\right\|
在显示数学中将其扩展,但保留为\| ... \|
内联数学。每个范数都有一个宏独有的下标:
\newcommand {\normbrak} [2] % display/inline -aware norm brackets
{\mathchoice{\left\|#1\right\|_{#2}}{\|#1\|_{#2}}{\|#1\|_{#2}}{\|#1\|_{#2}}}
\newcommand {\inorm} [1] {\normbrak{#1}{1}} % 1-norm (nuclear norm)
\newcommand {\iinorm} [1] {\normbrak{#1}{2}} % 2-norm (operator norm)
\newcommand {\fronorm} [1] {\normbrak{#1}{\text{F}}} % Frobenius norm
\newcommand {\infnorm} [1] {\normbrak{#1}{\infty}} % infinity norm
\newcommand {\Linorm} [1] {\normbrak{#1}{L^1}} % L1 norm
\newcommand {\Liinorm} [1] {\normbrak{#1}{L^2}} % L2 norm
\newcommand {\Linfnorm} [1] {\normbrak{#1}{L^\infty}} % L-infinity norm
在某些地方,我希望写,例如,\fronorm{\hat H}^{-1}
在范数上也得到上标。我的问题是,\mathchoice
似乎重置了上标和下标的位置,产生
而不是适当的
一个可能的解决方案是重写每个宏,例如
\newcommand {\normbrak} [3] {%
\mathchoice
{\left\|#1\right\|_{#2}\IfNoValueF {#3} {\sp{#3}}}
{\|#1\|_{#2}\IfNoValueF {#3} {\sp{#3}}}
{\|#1\|_{#2}\IfNoValueF {#3} {\sp{#3}}}
{\|#1\|_{#2}\IfNoValueF {#3} {\sp{#3}}}%
}
\NewDocumentCommand {\fronorm} {me{^}} {%
\normbrak{#1}{\text{F}}{#2}%
}
但这显得混乱和多余。
有没有办法可以阻止\mathchoice
超出其内容的界限,或者除此之外还有其他宏\mathchoice
可以在这里起作用?
答案1
在调用之前您必须吸收可能的上标\mathchoice
。
以下是一种解决方法,并进行了一些修复:
- 使用
\lVert
和\rVert
代替\|
(尝试\|-x\|
了解原因); - 用
\mathrm{F}
而不是\text{F}
(在定理陈述中尝试看看为什么)。
\documentclass{article}
\usepackage{amsmath}
\NewDocumentCommand{\normbrak}{mme{^}}{%
\mathchoice{\makenormbrak{\left}{\right}{#1}{#2}{#3}}
{\makenormbrak{}{}{#1}{#2}{#3}}
{\makenormbrak{}{}{#1}{#2}{#3}}
{\makenormbrak{}{}{#1}{#2}{#3}}%
}
\NewDocumentCommand{\makenormbrak}{mmmmm}{%
#1\lVert #3 #2\rVert_{#4}\IfValueT{#5}{^{#5}}%
}
\newcommand {\inorm} [1] {\normbrak{#1}{1}} % 1-norm (nuclear norm)
\newcommand {\iinorm} [1] {\normbrak{#1}{2}} % 2-norm (operator norm)
\newcommand {\fronorm} [1] {\normbrak{#1}{\mathrm{F}}}% Frobenius norm
\newcommand {\infnorm} [1] {\normbrak{#1}{\infty}} % infinity norm
\newcommand {\Linorm} [1] {\normbrak{#1}{L^1}} % L1 norm
\newcommand {\Liinorm} [1] {\normbrak{#1}{L^2}} % L2 norm
\newcommand {\Linfnorm} [1] {\normbrak{#1}{L^\infty}} % L-infinity norm
\begin{document}
\[
\fronorm{\hat{H}}^{-1}
\]
\begin{center}% for comparison
$\fronorm{\hat{H}}^{-1}$
\end{center}
\end{document}
然而,这张图片清楚地显示了为什么使用\left
和\right
非常危险,因为它会导致过大的分隔符。
答案2
为了帮助任何面临同样问题的人:
我想出了一个可行的解决方案,尽管不太优雅:
\ExplSyntaxOn
\NewDocumentCommand {\norm} {som} {%
\IfBooleanTF {#1} {\left\|#3\right\|} {\|#3\|}%
\IfNoValueF {#2} {\sb{%
\str_case:nnF {#2} {
{F} {\text F}
{inf} {\infty}
{L1} {L^1}
{L2} {L^2}
{Linf} {L^\infty}
}
{#2}%
}}%
}
\ExplSyntaxOff
例如,这使得\norm[F]{\hat H}^{-1}
和\norm*[L2]{\sum\limits_k a_k}^2
都能够按预期工作,并*
手动调用\left| right\|
版本而不是默认\| \|
版本。
不够优雅,因为括号的选择应该由内容的高度自动决定,但是...可行。
感谢@DavidCarlisle 和@daleif 的建议。