\mathop、\operatorname 和 \DeclareMathOperator 有什么区别?

\mathop、\operatorname 和 \DeclareMathOperator 有什么区别?

在源文件中,我们可以看到各种版本,用于定义诸如限制等内容。所以我的问题是,哪个版本用于什么用途。在选择其中一个版本时,是否有任何“最佳实践”?

答案1

\operatorname什么时候用(或其包装器\DeclareMathOperator) 代替更好\mathop?答案很简单:总是这样,除非你确切知道 的行为是什么\mathop


首先,当然必须记得\operatorname\DeclareMathOperator是由amsopn包提供的,该包由自动加载amsmath,但也可以独立使用。

让我们看看主要的定义:

\DeclareRobustCommand{\operatorname}{%
  \@ifstar{\qopname\newmcodes@ m}%
          {\qopname\newmcodes@ o}}%
\DeclareRobustCommand{\qopname}[3]{%
  \mathop{#1\kern\z@\operator@font#3}%
  \csname n#2limits@\endcsname}
\newcommand{\DeclareMathOperator}{%
  \@ifstar{\@declmathop m}{\@declmathop o}}
\long\def\@declmathop#1#2#3{%
  \@ifdefinable{#2}{%
    \DeclareRobustCommand{#2}{\qopname\newmcodes@#1{#3}}}}

该命令\qopname实际上并非用于文档中;其第一个参数的目的是添加一些声明,例如\newmcodes@在排版运算符名称之前。

\operatorname和各自\DeclareMathOperator都有一个 *-variant,它传递给\qopname第二个参数m而不是o。后一个命令只是一个包装器:

\DeclareMathOperator{\xyz}{xyz}
\DeclareMathOperator*{\XYZ}{XYZ}

几乎相当于说

\DeclareRobustCommand{\xyz}{\operatorname{xyz}}
\DeclareRobustCommand{\XYZ}{\operatorname*{XYZ}}

(但处理得更有效)所以我们需要检查的只是\operatorname

调用\operatorname{xyz}翻译为

\qopname\newmcodes@ o {xyz}

变成

  \mathop{\newmcodes@\kern\z@\operator@font xyz}\csname nolimits@\endcsname}
  1. 声明\newmcodes@注意某些字符在数学公式中像平常一样被不同地处理(特别是连字符不会变成减号);

  2. \kern\z@插入一个不可见的对象,这样整个内容\mathop就永远不会是一个字符(参见https://tex.stackexchange.com/a/41267/4427了解详情);

  3. \operator@fonts选择数学运算符的预定义字体,通常是直立的文本字体;

  4. \nolimits@只是 的别名\nolimits,因此除非声明取消,否则后面的下标和上标不会在运算符的上方和下方排版\limits

对于它来说\operatorname*,它完全相同,唯一的区别是\nmlimits@将执行 而不是\nolimits@。此宏定义为等同于\displaylimits,这使得运算符的行为类似于标准\lim\min

如果某个操作符在文档中只使用几次,那么可能无需用 定义命令\DeclareMathOperator;但在我看来,如果使用适当的逻辑结构名称,源代码的可读性会增强。

需要\mathop记住的是,它不会选择任何特定的字体,也不会纠正一些小故障:因此

\mathop{\mathrm{abc-def}}

将会有所不同

\operatorname{abc-def}

后者通常是预期的。在某些罕见情况下,\mathop它本身就很有用:

\newcommand{\diff}{\mathop{}\!d}

是一个例子,其中空格\mathop用于在“d”之前提供正确的间距。请注意,如果确实想要一个直立的“d”,将其定义为是不正确的,\operatorname{d}并且与之前相同,应该使用\mathrm{d}而不是d:明确地,替代方案是

\newcommand{\diff}{\mathop{}\!\mathrm{d}}

此外\stackrel,更好的amsmath命令\overset\underset用内部定义的\mathop{...}\limits,但包裹在其他一些构造中。

答案2

\mathop是最原始的命令,声明班级字符或子公式为一元数学运算符例如\sum。与二元运算符\mathbin或声明二元关系\mathrel例如用 声明。

大多数数学运算符都以文本名称写出。一些定义来自latex.ltx

\def\max{\mathop{\operator@font max}}
\def\min{\mathop{\operator@font min}}
\def\sup{\mathop{\operator@font sup}}
\def\inf{\mathop{\operator@font inf}}
\def\arg{\mathop{\operator@font arg}\nolimits}
\def\ker{\mathop{\operator@font ker}\nolimits}
\def\dim{\mathop{\operator@font dim}\nolimits}
\def\hom{\mathop{\operator@font hom}\nolimits}

您会看到使用了一种特殊的字体\operator@font;此外,还可以看到,用声明的运算符\mathop通常是排版的有限制,即在显示模式下,上标和下标被放置在特殊位置。可以使用 关闭此功能\nolimits

\operatorname来自 AMSTeX 包将其封装为用户命令:

\DeclareRobustCommand{\operatorname}{%
  \@ifstar{\qopname\newmcodes@ m}%
          {\qopname\newmcodes@ o}}%
\DeclareRobustCommand{\qopname}[3]{%
  \mathop{#1\kern\z@\operator@font#3}%
  \csname n#2limits@\endcsname}

这基本上意味着\operatorname{dual}将排版一个看起来像\arg(即没有限制)的数学运算符“dual”并且将排版一个看起来像(即有限制)的\operatorname*{dual}数学运算符“dual” 。\max

\DeclareMathOperator是相应的声明,即\DeclareMathOperator\dual{dual}创建一个新的宏\dual,其工作原理类似于\max

关于使用:

  • 使用\mathop,任何东西都可以声明为数学运算符,即如果您想使用*前缀运算符(有限制),您只需说\mathop{*}
  • \DeclareMathOperator如果您想定义一个新的运算符(如),则应该使用\max
  • \operatorname应用于仅需要一次特殊操作符名称的特殊情况。

答案3

\mathop是一个纯 TeX 命令,它声明了一个大运算符,例如

\newcommand{\Res}{\mathop{\hbox{Res}}}

DeclareMathOperator来自 AmsMath 的amsopn子包,称为:

\DeclareMathOperator{\Res}{Res}

而是operatorname一种“即时”操作符。输入

\operatorname{Res} 

与或\Res定义的含义相同mathopDeclareMathOperator

我认为,如果您加载了 AmSMath(始终是个好主意),那么我会使用DeclareMathOperator,并且operatorame在文件中很少使用此运算符的情况下,或者使数学模式下的某些文本直立并使用空格填充。

相关内容