I'd like to change the definition of one of the predefined math operators (\hom
).
Is there an equivalent to the \renewcommand
statement for operators?
math-operators
I'd like to change the definition of one of the predefined math operators (\hom
).
Is there an equivalent to the \renewcommand
statement for operators?
You are starting from a false premise: it's good to have macros for frequently used constructs and math operators such as “sine” and “log” are no exception.
If an operator appears only a few times, then what's wrong in using
\operatorname{foo}
for those few cases? If you don't want to type so much, then
\newcommand{\op}[1]{\operatorname{#1}}
would allow simply typing
\op{foo}
that requires just three keystrokes more than your proposed syntax.
It's quite difficult to have a safe routine for scanning a name in the same way TeX does for control sequences. The scanning of control sequence names is built-in, while you should do it character by character, storing them as you go until finding something that's not a letter.
There's another catch: your proposed character ¡
will definitely not work if the document is compiled under
\usepackage[utf8]{inputenc}
because in that case it is not a single character, but two: its UTF-8 representation is 0xC2A1
. You could use `
, instead.
\documentclass{article}
\usepackage{xparse,amsmath}
\ExplSyntaxOn
\tl_new:N \l__canaaerus_name_tl
\cs_new_protected:Npn \canaaerus_bq_mathop:
{
% clear the container
\tl_clear:N \l__canaaerus_name_tl
% start the recursion
\canaaerus_absorb:
}
\cs_new_protected:Npn \canaaerus_absorb:
{
\peek_catcode:NTF a
{% if the next token is a letter absorb it
\__canaaerus_absorb_next:n
}
{% otherwise produce the operator name
\__canaaerus_deliver:
}
}
\cs_new_protected:Npn \__canaaerus_absorb_next:n #1
{
% add the next letter to the container
\tl_put_right:Nn \l__canaaerus_name_tl { #1 }
% restart the recursion
\canaaerus_absorb:
}
\cs_new_protected:Npn \__canaaerus_deliver:
{
% produce the operator name
\operatorname{\l__canaaerus_name_tl}
}
% define the active back quote
\group_begin:
\char_set_catcode_active:N `
\cs_gset_eq:NN ` \canaaerus_bq_mathop:
\group_end:
\ExplSyntaxOff
% make the backquote math active
\AtBeginDocument{\mathcode``=\string"8000 }
\begin{document}
$`cos(\alpha+\beta)-`sin x$
\end{document}
Highly inefficient, but working. Of course, syntax errors such as typing
`sinx
wouldn't be caught.
A different approach is to ease defining operators:
\documentclass{article}
\usepackage{xparse,amsmath}
\ExplSyntaxOn
\NewDocumentCommand{\DeclareMathOperators}{m}
{
\keys_set:nn { canaaerus/mathop } { #1 }
}
\keys_define:nn { canaaerus/mathop }
{
unknown .code:n = \canaaerus_defop:n { #1 }
}
\cs_new_protected:Npn \canaaerus_defop:n #1
{
\cs_if_exist:cTF { \l_keys_key_tl }
{
\msg_error:nnx { canaaerus/mathop } { exist } { \exp_not:c { \l_keys_key_tl } }
}
{
\tl_if_empty:nTF { #1 }
{
\cs_new:cpx { \l_keys_key_tl } { \exp_not:N \operatorname { \l_keys_key_tl } }
}
{
\cs_new:cpx { \l_keys_key_tl } { \exp_not:N \operatorname { #1 } }
}
}
}
\msg_new:nnnn { canaaerus/mathop } { exist }
{
#1 already~defined
}
{
The~command~#1 already~exists,~ignored
}
\cs_generate_variant:Nn \msg_error:nnn { nnx }
\ExplSyntaxOff
\DeclareMathOperators{
Tor,
Hom,
Span=span,
%span, % if uncommented it would raise an error
}
\begin{document}
$\Tor\quad\Hom\quad\Span$
\end{document}
No interface for this has been provided, which I believe is a mistake. A simple workaround is to remove the definition of the command before redeclaring it:
\let\ln\relax
\DeclareMathOperator{\ln}{log} % this is how the logarithm should be denoted
A \RedeclareMathOperator
command could be defined as follows
\documentclass{article}
\usepackage{amsmath}
\makeatletter
\newcommand\RedeclareMathOperator{%
\@ifstar{\def\rmo@s{m}\rmo@redeclare}{\def\rmo@s{o}\rmo@redeclare}%
}
% this is taken from \renew@command
\newcommand\rmo@redeclare[2]{%
\begingroup \escapechar\m@ne\xdef\@gtempa{{\string#1}}\endgroup
\expandafter\@ifundefined\@gtempa
{\@latex@error{\noexpand#1undefined}\@ehc}%
\relax
\expandafter\rmo@declmathop\rmo@s{#1}{#2}}
% This is just \@declmathop without \@ifdefinable
\newcommand\rmo@declmathop[3]{%
\DeclareRobustCommand{#2}{\qopname\newmcodes@#1{#3}}%
}
\@onlypreamble\RedeclareMathOperator
\makeatother
\DeclareMathOperator{\ln}{log} % gives error
\RedeclareMathOperator{\ln}{log} % is accepted
\RedeclareMathOperator{\foo}{foo} % gives error
\RedeclareMathOperator*{\deg}{deg} % now \deg typesets limits below and above
Best Answer
I'm not aware of any pendant, but you can use
\DeclareMathOperator
(not\DefineMathOperator
) a second time if you mark the macro as not defined first. However, changing it doesn't make that much sense, because such a math operator is only there to print the operator name in the correct font. You shouldn't add code or arguments to it. See \DeclareMathOperator won't take arguments for more about that.