9

I am a heavy user of the physics package. Unfortunately, the \norm command seems to have some quirks associated with it. According to the documentation the starred version is meant to result in a norm whose sized is fixed. However, consider the following MWE

enter image description here

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

where we can see that extra space is added between the || and the subscript 2 when the starred version is used. This behavior also appears to prevent one from using \mathrlap from mathtools from swallowing up the subscript in the * case.

0

2 Answers 2

12

Analysis

Let's see what physics.sty does. First, the definition of \norm:

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

The l argument type collects everything up to (and excluding) the first {. Now let's look at \braces:

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

I see no reason for this \ifnum; anyway, it means we need to look at \@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}
}

Wow! One of the ugliest macro definitions I have ever seen. Anyway, this shows what happens when you call \norm*{A^k}_{2}: it gets translated into

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

which is just silly. Some notes, now.

  1. What I said about “no reason” now turns into “it's wrong”.

  2. Where's the problem in saying #6#8#7 instead of using \left and \right whose final job is just to add unwanted horizontal space?

  3. Where's the advantage in typing \norm\big{x} over \norm[\big]{x} à la mathtools?

Possible solutions in order of personal preference

  1. Avoid physics.sty.
  2. Ask the author of physics.sty to clean up the package code.
  3. Add

    \usepackage{mleftright}
    \mleftright
    

    to your preamble.

Comments

I recommend NOT using automatic sizing unless you know precisely that it's OK. Which, as shown by the output of \norm{A^k}_2, is not this case. Please, note the “not” in boldface italic uppercase.

The physics package is a prime example of how to abuse xparse. As far as I can see, it's a collection of macros that can easily be defined in the document preamble as needed, maybe with the help of mathtools (not with automatic sizing by default, of course).

Finally: your idea of \mathrlapping the subscript is not so good. But you're the final judge on it.

4

I can offer no particular insights into the hows and whys of the macro definitions of the physics package. However, using the mathtools package (which you're already loading), it's straightforward to come up with a replacement definition of \norm and \norm* that meets your formatting objectives.

enter image description here

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .