Особенности в \norm* из physics.sty

Особенности в \norm* из physics.sty

Я активный пользователь пакета физики. К сожалению, команда, \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}

||где мы видим, что между the и подстрочным индексом добавляется дополнительный пробел, 2когда используется версия со звездочкой. Такое поведение также, по-видимому, препятствует использованию from, \mathrlapчтобы mathtoolsне поглотить подстрочный индекс в этом *случае.

решение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вместо использования \leftи \rightчья конечная задача - просто добавитьнежелательныйгоризонтальное пространство?

  3. В чем преимущество набора текста \norm\big{x}перед \norm[\big]{x}à la mathtools?

Возможные решения в порядке личных предпочтений

  1. Избегать physics.sty.
  2. Попросите автора physics.styпочистить код пакета.
  3. Добавлять

    \usepackage{mleftright}
    \mleftright
    

    к вашей преамбуле.

Комментарии

Я рекомендуюНЕТиспользование автоматического размера, если вы точно не знаете, что это нормально. Что, как показывает вывод \norm{A^k}_2, не является этим случаем. Обратите внимание на «не» в жирном курсиве заглавными буквами.

Пакет physicsявляется ярким примером того, как злоупотреблять xparse. Насколько я могу судить, это набор макросов, которые можно легко определить в преамбуле документа по мере необходимости, возможно, с помощью mathtools(не с автоматическим изменением размера по умолчанию, конечно).

Наконец: твоя идея \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}

Связанный контент