有没有办法阻止 \mathchoice 重置其内容的边界(相对于上标/下标位置)?

有没有办法阻止 \mathchoice 重置其内容的边界(相对于上标/下标位置)?

我有一系列范数宏,我想\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

以下是一种解决方法,并进行了一些修复:

  1. 使用\lVert\rVert代替\|(尝试\|-x\|了解原因);
  2. \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 的建议。

相关内容