The amsopn package

Michael Downes

28 October 1996 Version 1.02

1 Introduction

The amsopn package provides a command \DeclareMathOperator for defining new ‘math operator names’ similar to the standard function names \sin, \lim, \max, etc.

Standard file identification.

  \NeedsTeXFormat{LaTeX2e}% LaTeX 2.09 can't be used (nor non-LaTeX)
  [1994/12/01]% LaTeX date must December 1994 or later
  \ProvidesPackage{amsopn}[1996/10/28 v1.2b operator names]

First we may need some utility definitions if amsopn is used by itself with a non-AMS class.

  \@ifundefined{DN@}{%
    \def\FN@{\futurelet\@let@token}%
    \def\DN@{\def\next@}%
  }{}

The definition of \nolimits@ shows a standard AMS-TEX construction. We want to find out what the next token is going to be, so we use

    \futurelet\@let@token\next@

The \@let@token is assigned the value of the next token and then we must define \next@ to look at \@let@token and decide what to do. We could name \next@ to be \nolimits@@ or something, but by always using \next@ in similar constructions we cut down on the number of control sequence names that we use. But this means that \nolimits@ must incorporate the appropriate definition of \next@. Notice that \next@ turns around and redefines itself again; once more this is to save a control sequence name.

What \nolimits@ does is keep a \limits typed by the user from having any effect. This is used for operatornames whose standard usage is never to have limits.

  \def\nolimits@{%
    \DN@{\nolimits\ifx\@let@token\limits\expandafter\@gobble\fi}%
    \FN@\next@}

In operator names, it is sometimes desired to have text-mode punctuation characters such as *-/:'. Because the body of an operator name is set in math mode, these few punctuation characters will not come out right (wrong symbol/and or wrong spacing). The purpose of \newmcodes@ is to make them act like their normal text versions.

Where practical, we use decimal numbers to cut down main mem usage (" not needed).

  \begingroup \catcode`\"=12
  \gdef\newmcodes@{\mathcode`\'39\mathcode`\*42\mathcode`\."613A%
   \mathcode`\-45\mathcode`\/47\mathcode`\:"603A\relax}
  \endgroup

The command \operatorname prints its argument as a ‘math operator’ like \sin or \det, with proper font and spacing.

  \DeclareRobustCommand{\operatorname}{%
    \@ifstar{\qopname\newmcodes@ m}%
            {\qopname\newmcodes@ o}}%

In the interior of the \mathop we need a null object (we choose a zero kern for minimum waste of main mem) in order to guard against the case where #3 is a single letter; TEX will seize it and center it on the math axis if there is nothing else inside the \mathop atom.

  \DeclareRobustCommand{\qopname}[3]{%
    \mathop{#1\kern\z@\operator@font#3}%
    \csname n#2limits@\endcsname}
\DeclareMathOperator The command \DeclareMathOperator defines the first argument to be an op-

erator name whose text is the second argument. The star form means that the operator name should take limits (like \max or \lim).

  \newcommand{\DeclareMathOperator}{%
    \@ifstar{\@declmathop\@empty}{\@declmathop o}}

In the basic set of operator names (below) we did not use \DeclareRobustCommand because of the hash table cost. But we use it here to minimize the chances of trouble, since we are producing a user-defined command.

  \long\def\@declmathop#1#2#3{%
    \@ifdefinable{#2}{%
      \DeclareRobustCommand{#2}{\qopname\newmcodes@#1{#3}}}}
  %
  \@onlypreamble\DeclareMathOperator
  \@onlypreamble\@declmathop
  \def\arccos{\qopname\relax o{arccos}}
  \def\arcsin{\qopname\relax o{arcsin}}
  \def\arctan{\qopname\relax o{arctan}}
  \def\arg{\qopname\relax o{arg}}
  \def\cos{\qopname\relax o{cos}}
  \def\cosh{\qopname\relax o{cosh}}
  \def\cot{\qopname\relax o{cot}}

1. INTRODUCTION 3

\def\coth{\qopname\relax o{coth}}
\def\csc{\qopname\relax o{csc}}
\def\deg{\qopname\relax o{deg}}
\def\det{\qopname\relax\@empty{det}}
\def\dim{\qopname\relax o{dim}}
\def\exp{\qopname\relax o{exp}}
\def\gcd{\qopname\relax\@empty{gcd}}
\def\hom{\qopname\relax o{hom}}
\def\inf{\qopname\relax\@empty{inf}}
\def\injlim{\qopname\relax\@empty{inj\,lim}}
\def\ker{\qopname\relax o{ker}}
\def\lg{\qopname\relax o{lg}}
\def\lim{\qopname\relax\@empty{lim}}
\def\liminf{\qopname\relax\@empty{lim\,inf}}
\def\limsup{\qopname\relax\@empty{lim\,sup}}
\def\ln{\qopname\relax o{ln}}
\def\log{\qopname\relax o{log}}
\def\max{\qopname\relax\@empty{max}}
\def\min{\qopname\relax\@empty{min}}
\def\Pr{\qopname\relax\@empty{Pr}}
\def\projlim{\qopname\relax\@empty{proj\,lim}}
\def\sec{\qopname\relax o{sec}}
\def\sin{\qopname\relax o{sin}}
\def\sinh{\qopname\relax o{sinh}}
\def\sup{\qopname\relax\@empty{sup}}
\def\tan{\qopname\relax o{tan}}
\def\tanh{\qopname\relax o{tanh}}

\operator@font This command is provided to allow the document styles to decide in which way math operators like ‘max’ or ‘log’ are typeset. The default is to set them in ⟨math group⟩ zero of the current math version.

\def\operator@font{\mathgroup\symoperators}

For backwards compatibility we keep this old command name for the time being:

\def\operatornamewithlimits{\operatorname*}

These macros use \mathpalettes so that they will change size in script and scriptscript styles, though it’s hard to imagine they will ever be used there (the arrows, particularly, look bad in subscript sizes). Notice that the use of \ex@ means that the vertical spacing may not be optimal in script and scriptscript sizes. Unfortunately TEX provides no easy way to do math mode vertical spacing that varies with current math style like mu units.

\def\varlim@#1#2{\mathop{\vtop{\ialign{##\crcr
 \hfil$#1\m@th\operator@font lim$\hfil\crcr
 \noalign{\nointerlineskip\kern\ex@}#2#1\crcr
 \noalign{\nointerlineskip\kern-\ex@}\crcr}}}}
\def\varinjlim{\mathpalette\varlim@\rightarrowfill@}
\def\varprojlim{\mathpalette\varlim@\leftarrowfill@}

4 THE AMSOPN PACKAGE

\def\varliminf{\mathpalette\varliminf@{}}
\def\varliminf@#1{\mathop{\@@underline{\vrule\@depth.2\ex@\@width\z@
   \hbox{$#1\m@th\operator@font lim$}}}}
\def\varlimsup{\mathpalette\varlimsup@{}}
\def\varlimsup@#1{\mathop{\@@overline
  {\hbox{$#1\m@th\operator@font lim$}}}}
\DeclareOption{namelimits}{\let\nmlimits@\displaylimits}
\DeclareOption{nonamelimits}{\let\nmlimits@\nolimits}
\ProcessOptions\relax

The usual \endinput to ensure that random garbage at the end of the file doesn’t get copied by docstrip.

\endinput