physics.sty 中 \norm* 的特性

physics.sty 中 \norm* 的特性

我是物理包的重度用户。不幸的是,该\norm命令似乎有一些与之相关的怪癖。根据文档,带星号的版本旨在产生一个大小固定的范数。但是,请考虑以下 MWE

在此处输入图片描述

\documentclass[11pt]{article}

\usepackage{lmodern}
\usepackage{amsmath}
\usepackage{physics}
\usepackage{mathtools}

\begin{document}
\[
 \norm{A^k}_2 \quad \norm*{A^k}_2 \quad
 \frac{1}{\norm{A^k}_{\mathrlap{2}}} \quad \frac{1}{\norm*{A^k}_{\mathrlap{2}}}
\]
\end{document}

||我们可以看到,使用星号版本时,在和下标之间添加了额外的空格2。此行为似乎也是为了防止使用\mathrlapfrommathtools吞噬下标*

答案1

分析

让我们看看physics.sty会发生什么。首先,定义\norm

\DeclareDocumentCommand\norm{ l m }{\braces#1{\lVert}{\rVert}{#2}} % Norm

参数类型l收集了直到(不包括)第一个 的所有内容{。现在让我们看看\braces

\DeclareDocumentCommand\braces{}{{\ifnum\z@=`}\fi\@braces}

我认为没有理由这样做\ifnum;无论如何,这意味着我们需要考虑\@braces

\DeclareDocumentCommand\@braces{ s t\big t\Big t\bigg t\Bigg m m m }
{ % General braces with automatic and manual sizing
        \IfBooleanTF{#1}
        {\left#6\smash{#8}\right#7\vphantom{#8}}
        {
                \IfBooleanTF{#2}{\bigl#6{#8}\bigr#7}{
                        \IfBooleanTF{#3}{\Bigl#6{#8}\Bigr#7}{
                                \IfBooleanTF{#4}{\biggl#6{#8}\biggr#7}{
                                        \IfBooleanTF{#5}{\Biggl#6{#8}\Biggr#7}{\left#6{#8}\right#7}
                                }
                        }
                }
        }
        \ifnum\z@=`{\fi}
}

哇!这是我见过的最丑陋的宏定义之一。无论如何,这显示了调用时会发生什么\norm*{A^k}_{2}:它会被翻译成

{% <-- from the \ifnum in \braces
 \left\lVert\smash{A^k}\right\rVert\vphantom{A^k}
}% <-- from the \ifnum in \@braces

这太愚蠢了。现在来谈谈几点。

  1. 我刚才说的“没有理由”现在变成了“这是错误的”。

  2. #6#8#7\leftand代替\right最后的工作只是添加不需要的水平空间?

  3. \norm\big{x}\norm[\big]{x}à la相比,打字有什么优势mathtools

按个人偏好顺序列出的可能解决方案

  1. 避免physics.sty
  2. 要求作者physics.sty清理包代码。
  3. 添加

    \usepackage{mleftright}
    \mleftright
    

    你的序言。

评论

我建议不是使用自动调整大小,除非您确切知道这样做没问题。但正如 的输出所示\norm{A^k}_2,情况并非如此。请注意粗体斜体大写的“not”。

physics软件包是如何滥用的典型示例xparse。据我所知,它是一组宏,可以根据需要在文档序言中轻松定义,也许借助mathtools(当然,默认情况下不是自动调整大小)。

最后:你 ping 下标的想法\mathrlap不太好。但你是最终的评判者。

答案2

physics我无法提供关于该包的宏定义如何以及为什么的特别见解。但是,使用该mathtools包(您已经加载了该包),很容易就能找到符合您的格式目标的替代\norm定义\norm*

在此处输入图片描述

\documentclass[11pt]{article}

\usepackage{lmodern}
%\usepackage{amsmath} % is loaded automatically by 'mathtools'
\usepackage{physics}
\usepackage{mathtools} % for '\mathrlap' and '\DeclarePairedDelimiter' macros

\makeatletter  
%% Switch meanings of starred and unstarred macros
%% (see https://tex.stackexchange.com/a/278398/5001)
\newcommand{\XDeclarePairedDelimiter}[3]{%  "X" for "exchange"
  \expandafter\DeclarePairedDelimiter\csname RIGHT\string#1\endcsname{#2}{#3}%
  \newcommand#1{%
    \@ifstar{\csname RIGHT\string#1\endcsname}
            {\@ifnextchar[{\csname RIGHT\string#1\endcsname}
                          {\csname RIGHT\string#1\endcsname*}%
}}}
\makeatother
\let\norm\relax % undefine existing "\norm" macro
\XDeclarePairedDelimiter{\norm}{\lVert}{\rVert}

\begin{document}
\[
 \norm{A^k}_2    \quad 
 \norm*{A^k}_2   \quad
 \frac{1}{\norm{A^k}_{\mathrlap{2}}} \quad 
 \frac{1}{\norm*{A^k}_{\mathrlap{2}}}
\]
\end{document}

相关内容