12

I defined a macro for the supremum norm by

\DeclarePairedDelimiter{\supnorm}{\|}{\|_\infty}

which works nicely. However, as soon as I want to place a superscript like

\supnorm{f}^2

things look funny, as the 2 appears after the infty-sign. However, I would like to look things more like what you get by

\|f\|_\infty^2

Of course, one can achieve this by using

\newcommand{\supnorm}[1]{\|#1\|_\infty}

but then one looses the nice functionality of \DeclarePairedDelimiter, which I really started to like a lot. Any ideas how one can combine the benefits of both?

Nils L
  • 9,716

4 Answers4

10

You need to get the \infty outside of the grouping. And that will involve redoing the options:

\documentclass[a4paper]{memoir}
\usepackage{mathtools,xparse}
\DeclarePairedDelimiter{\supnormX}{\lVert}{\rVert}
\DeclareDocumentCommand\supnorm{ s o m }{%
  \IfBooleanTF{#1}{% starred
    \supnormX*{#3}_\infty
  }{% not starred
    \IfNoValueTF{#2}{% no []
      \supnormX{#3}_\infty
    }{% data in []
      \supnormX[#2]{#3}_\infty
    }
  }
}
\begin{document}
\[
\supnorm{A}^2
\]
\end{document}
daleif
  • 54,450
  • 5
    you're listed as one of the maintainers of mathtools. may i suggest that generalizing the definition of \DeclarePairedDelimiter there would be a worthy project. – barbara beeton Oct 07 '13 at 13:31
  • 1
    Hmm, I'm a bit reluctant to make it depend on xparse and also, why only subscripts..... I'll think about it. – daleif Oct 07 '13 at 17:05
  • 1
    hmmm. i didn't mean to imply subscripts only -- certainly superscripts should be dealt with, and i'm not sure whether there are other variations that might be relevant. and i understand why you might want to steer clear of xparse at this moment (and don't disagree). thinking is good. thanks. – barbara beeton Oct 07 '13 at 17:42
10

Here's a different implementation of \DeclarePairedDelimiter for which I use a different name.

\documentclass[a4paper]{memoir}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
\DeclareDocumentCommand{\xDeclarePairedDelimiter}{mmmO{}}
 {
  \NewDocumentCommand{#1}{sO{}m}
   {
    \IfBooleanTF{##1}
     {
      \egreg_paired_delimiter_expand:nnnn {#2}{#3}{##3}{#4}
     }
     {
      \egreg_paired_delimiter_fixed:nnnnn {##2}{#2}{#3}{##3}{#4}
     }
   }
 }
\cs_new_protected:Npn \egreg_paired_delimiter_expand:nnnn #1 #2 #3 #4
 {% Fix the spacing issue with \left and \right (D. Arsenau, P. Stephani and H. Oberdiek)
  \mathopen{}
  \mathclose\c_group_begin_token
   \left#1
   #3
   \group_insert_after:N \c_group_end_token
   \right#2
   \tl_if_empty:nF {#4} { \c_math_subscript_token {#4} }
 }
\cs_new_protected:Npn \egreg_paired_delimiter_fixed:nnnnn #1 #2 #3 #4 #5
 {
  \mathopen{#1#2}#4\mathclose{#1#3}
  \tl_if_empty:nF {#5} { \c_math_subscript_token {#5} }
 }
\ExplSyntaxOff

%% the final optional argument to \xDeclarePairedDelimiter
%% is a subscript to the right fence
\xDeclarePairedDelimiter{\supnormX}{\lVert}{\rVert}[\infty]

\begin{document}
\[
\supnormX{A}^2\quad
\supnormX[\big]{A}^2\quad
\supnormX[\Big]{A}^2\quad
\supnormX[\bigg]{A}^2\quad
\supnormX[\Bigg]{A}^2\quad
\supnormX*{\frac{A}{2}}^2
\]
\end{document}

enter image description here


Since daleif has shown interest in extending this idea, I add a way to define the macros with a key-value interface. The main (internal) functions remain the same.

\documentclass[a4paper]{memoir}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
\DeclareDocumentCommand{\KDeclarePairedDelimiter}{mm}
 {
  \__egreg_delimiter_clear_keys: % reset to the default
  \keys_set:nn { egreg/delimiters } { #2 }
  \use:x % we want to expand the values of the token variables set with the keys
   {
    \exp_not:n {\NewDocumentCommand{#1}{sO{}m} }
     {
      \exp_not:n { \IfBooleanTF{##1} }
       {
        \exp_not:N \egreg_paired_delimiter_expand:nnnn
         { \exp_not:V \l_egreg_delimiter_left_tl }
         { \exp_not:V \l_egreg_delimiter_right_tl }
         { \exp_not:n { ##3 } }
         { \exp_not:V \l_egreg_delimiter_subscript_tl }
       }
       {
        \exp_not:N \egreg_paired_delimiter_fixed:nnnnn 
         { \exp_not:n { ##2 } }
         { \exp_not:V \l_egreg_delimiter_left_tl }
         { \exp_not:V \l_egreg_delimiter_right_tl }
         { \exp_not:n { ##3 } }
         { \exp_not:V \l_egreg_delimiter_subscript_tl }
       }
     }
   }
 }

\keys_define:nn { egreg/delimiters }
 {
  left      .tl_set:N = \l_egreg_delimiter_left_tl,
  right     .tl_set:N = \l_egreg_delimiter_right_tl,
  subscript .tl_set:N = \l_egreg_delimiter_subscript_tl,
 }

\cs_new_protected:Npn \__egreg_delimiter_clear_keys:
 {
  \keys_set:nn { egreg/delimiters } { left=.,right=.,subscript={} }
 }

\cs_new_protected:Npn \egreg_paired_delimiter_expand:nnnn #1 #2 #3 #4
 {% Fix the spacing issue with \left and \right (D. Arsenau, P. Stephani and H. Oberdiek)
  \mathopen{}
  \mathclose\c_group_begin_token
   \left#1
   #3
   \group_insert_after:N \c_group_end_token
   \right#2
   \tl_if_empty:nF {#4} { \c_math_subscript_token {#4} }
 }
\cs_new_protected:Npn \egreg_paired_delimiter_fixed:nnnnn #1 #2 #3 #4 #5
 {
  \mathopen{#1#2}#4\mathclose{#1#3}
  \tl_if_empty:nF {#5} { \c_math_subscript_token {#5} }
 }
\ExplSyntaxOff

\KDeclarePairedDelimiter{\supnormX}{
  left=\lVert,
  right=\rVert,
  subscript=\infty
}

\begin{document}
\[
\supnormX{A}^2\quad
\supnormX[\big]{A}^2\quad
\supnormX[\Big]{A}^2\quad
\supnormX[\bigg]{A}^2\quad
\supnormX[\Bigg]{A}^2\quad
\supnormX*{\frac{A}{2}}^2
\]
\end{document}
egreg
  • 1,121,712
  • You missed mathtools build in fix to the \left...\right spacing. – daleif Oct 14 '13 at 13:11
  • @daleif Just load mleftright and use \mleft and \mright. ;-) Seriously, I find your approach in mathtools too complicated. – egreg Oct 14 '13 at 13:49
  • Then again you rely on many external packages. – daleif Oct 14 '13 at 15:50
  • 1
    @daleif Fixing it with the same trick as mleftright is quite easy. I added it. – egreg Oct 14 '13 at 15:58
  • Isn't that what I do in mathtools? – daleif Oct 14 '13 at 19:06
  • @daleif I don't know. Your definition is overly complicated, in my opinion. You define three (perhaps more) commands for each \DeclarePairedDelimiter when it's not necessary at all. – egreg Oct 14 '13 at 19:52
  • That was because people were asking for methods to change the inner workings of the macro. – daleif Oct 14 '13 at 20:02
  • Hmm, I'm thinking about providing an extension to \DeclarePairedDelimiterX, taking arguments like this: \DeclarePairedDelimiterXX\macro[1]{pre code}{left delim}{right delim}{post code}{body}, then the L2 norm is \DeclarePairedDelimiterXX\norm2[2]{}\lVert\rVert{_2}{#1}. Precode can be used to create, say a probability operator with build in support for conditionals. – daleif May 06 '14 at 15:01
  • @daleif Nice idea. But maybe a key-value interface would be better. – egreg May 06 '14 at 15:05
  • Been trying, but keeps getting into trouble. One thing is that the key-values has to be stored with the macro. Hmm, perhaps prefixing them? – daleif May 06 '14 at 15:14
  • @daleif I'll add how it's possible to do it (with my macros). – egreg May 06 '14 at 15:35
  • Problem is, I'd (at the momemnt) like to do a version that does not depend on xparse. – daleif May 06 '14 at 15:37
  • Hmm, I think I'd rather leave it to the user what does in front or after, thus not only appending a subscript. I'll see what I come up with. Might also be time to convert mathtools to expl3 but that will wait for a future version – daleif May 07 '14 at 09:08
  • I think for now I'll will keep it simple and just implement \DeclarePairedDelimiterXX as mentioned above. For now implementing without xparse make things a lot more complicated. BTW: with xparse, if I implement a macro that builds other macros, and the user can specify the number of supported arguments, can I then use \NewDocumentCOmmand or will one have to resort to \newcommand in order not having to explain the m syntax to LaTeX users. – daleif May 07 '14 at 10:15
  • @daleif The problem is that many people would like something as \norm{2}{X} to become ||X||, and then both \norm{2}*{X} and \norm*{2}{X} to work (so that you can put the star either just after \norm, or define \newcommand*\Euklidnorm{\norm{2}} that still accepts the star (or the optional argument). – yo' Jan 27 '15 at 18:33
  • Not understood what so ever!? How is 2 related in this case? – daleif Jan 27 '15 at 18:59
7

Update:

Now with all the options provided by \DeclarePairedDelimiter! See the new definition (without using xparse):

\DeclarePairedDelimiter{\norm}{\lVert}{\rVert}
\makeatletter
\newcommand{\@supnormstar}[1]{\norm*{#1}_\infty}
\newcommand{\@supnormnostar}[2][]{\norm[#1]{#2}_\infty}
\newcommand{\supnorm}{\@ifstar\@supnormstar\@supnormnostar}
\makeatother

For example, the following code:

\[\supnorm{\frac{\sqrt5-1}{2}}^2\]
\[\supnorm*{\frac{\sqrt5-1}{2}}^2\]
\[\supnorm[\big]{\frac{\sqrt5-1}{2}}^2\]

will give you:

enter image description here

Francis
  • 6,183
1

This is just shameless advertising for my own package, SemanTeX. (Note that SemanTeX is a pretty heavy package, sacrificing speed in return for flexibility. So this solution will be significantly slower than the others presented here. Still, you will need a lot of norms to feel the difference.)

\documentclass{article}

\usepackage{semantex} % You will need a recent update of it

\NewVariableClass\MyVar

\NewObject\MyVar\norm[ left par=\lVert, right par=\rVert, arg keyval=false, define keys[1]={ {default}{ output options={sep lower={#1}} }, }, ]

\begin{document}

$ \norm{x} $, $ \norm[par=\big]{x} $, $ \norm[par=auto]{ \frac{1}{2} } $

$ \norm[2]{x} $

$ \norm[\infty]{x} $, $ \norm[\infty,par=\big]{x} $, $ \norm[\infty,par=auto]{\frac{1}{2}} $

\NewObject\MyVar\supnorm[copy=\norm,\infty]

$ \supnorm{x} $, $ \supnorm[par=\big]{x} $, $ \supnorm[par=auto]{\frac{1}{2}} $

\end{document}

enter image description here

Gaussler
  • 12,801