Peculiaridades em \norm* de Physics.sty

Peculiaridades em \norm* de Physics.sty

Eu sou um usuário frequente do pacote de física. Infelizmente, o \normcomando parece ter algumas peculiaridades associadas a ele. De acordo com a documentação a versão estrelada pretende resultar em uma norma cujo tamanho é fixo. No entanto, considere o seguinte MWE

insira a descrição da imagem aqui

\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}

onde podemos ver que espaço extra é adicionado entre o ||e o subscrito 2quando a versão com estrela é usada. Esse comportamento também parece impedir \mathrlapque o usuário mathtoolsengula o subscrito da *caixa.

Responder1

Análise

Vamos ver o que physics.styacontece. Primeiro, a definição de \norm:

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

O ltipo de argumento coleta tudo até (e excluindo) o primeiro {. Agora vejamos \braces:

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

Não vejo razão para isso \ifnum; de qualquer forma, isso significa que precisamos olhar para \@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}
}

Uau! Uma das definições de macro mais feias que já vi. De qualquer forma, isso mostra o que acontece quando você liga \norm*{A^k}_{2}: é traduzido para

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

o que é simplesmente bobo. Algumas notas, agora.

  1. O que eu disse sobre “sem motivo” agora se transforma em “está errado”.

  2. Onde está o problema em dizer #6#8#7em vez de usar \lefte \rightcujo trabalho final é apenas adicionarindesejadoespaço horizontal?

  3. Onde está a vantagem de digitar \norm\big{x}à \norm[\big]{x}la mathtools?

Possíveis soluções em ordem de preferência pessoal

  1. Evitar physics.sty.
  2. Peça ao autor physics.stypara limpar o código do pacote.
  3. Adicionar

    \usepackage{mleftright}
    \mleftright
    

    ao seu preâmbulo.

Comentários

Eu recomendoNÃOusando o dimensionamento automático, a menos que você saiba exatamente que está tudo bem. O que, como mostra a saída de \norm{A^k}_2, não é este caso. Por favor, observe o “não” em negrito e itálico maiúsculo.

O physicspacote é um excelente exemplo de como abusar xparse. Pelo que posso ver, é uma coleção de macros que podem ser facilmente definidas no preâmbulo do documento conforme necessário, talvez com a ajuda de mathtools(não com dimensionamento automático por padrão, é claro).

Finalmente: sua ideia de \mathrlapexecutar ping no subscrito não é tão boa. Mas você é o juiz final sobre isso.

Responder2

Não posso oferecer nenhuma visão específica sobre os comos e porquês das definições macro do physicspacote. No entanto, usando o mathtoolspacote (que você já está carregando), é fácil encontrar uma definição substituta de \norme \norm*que atenda aos seus objetivos de formatação.

insira a descrição da imagem aqui

\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}

informação relacionada