
Я использовал что-то вроде
\renewcommand\vec[1] {\boldsymbol{\MakeLowercase{#1}}}
\newcommand\mat[1] {\boldsymbol{\MakeUppercase{#1}}}
уже некоторое время для набора векторов и матриц. Однако, каждый раз, когда я спрашиваю, это всплываета вопрос, люди говорят мне, что это плохая идея использовать \Makeuppercase
в математическом режиме. Кроме того, \Makeuppercase
для меня это довольно сломанов этот момент, поэтому мне может понадобиться альтернатива.
Для этой альтернативы я думал, что было бы достаточно, если бы я мог выдавать предупреждение, когда для матриц используется символ нижнего регистра (или символ верхнего регистра для векторов). Я знаю, как выдавать предупреждение с помощью \@warning
или \GenericWarning
, но я не могу понять, как проверить, является ли что-то строчным или заглавным.
Кроме того, будет ли это на самом деле лучшим способом обеспечить единообразный набор векторов и матриц, как описано выше, или мне следует рассмотреть что-то совершенно иное?
Приложение
Поскольку все продолжают комментировать, насколько плоха идея принудительного учета регистра в математическом режиме, я чувствую, что должен подчеркнуть, что я знаю об этих проблемах, и это моя попытка найти обходной путь. Моя главная забота заключается в том, чтобы команды, которые у меня были, помогли мне сохранить мою нотацию согласованной, а семантику моего кода LaTeX ясной, и я бы предпочел сохранить эту согласованность каким-то образом.
Приведу пример: типичный набор уравнений, с которым я работаю, выглядит следующим образом:
\begin{align*}
\vec{f} &= \sigma(\mat{W}_\mathrm{fx} \vec{x} + \mat{W}_\mathrm{fh} \vec{h} + \vec{b}_\mathrm{f}) \\
\vec{i} &= \sigma(\mat{W}_\mathrm{ix} \vec{x} + \mat{W}_\mathrm{ih} \vec{h} + \vec{b}_\mathrm{i}) \\
\vec{s} &= \sigma(\mat{W}_\mathrm{sx} \vec{x} + \mat{W}_\mathrm{sh} \vec{h} + \vec{b}_\mathrm{s}) \\
\vec{c} &\gets \vec{f} \odot \vec{c} + \vec{i} \odot \phi(\vec{s})
\end{align*}
Теперь, в зависимости от контекста, может быть полезно/необходимо записать это следующим образом:
\begin{align*}
\mat{F} &= \sigma(\mat{X} \mat{W}_\mathrm{fx}^\mathsf{T} + \mat{H} \mat{W}_\mathrm{fh} + \vec{b}_\mathrm{f} \mat{1}) \\
\mat{I} &= \sigma(\mat{X} \mat{W}_\mathrm{ix}^\mathsf{T} + \mat{H} \mat{W}_\mathrm{ih} + \vec{b}_\mathrm{i} \mat{1}) \\
\mat{S} &= \sigma(\mat{X} \mat{W}_\mathrm{sx}^\mathsf{T} + \mat{H} \mat{W}_\mathrm{sh} + \vec{b}_\mathrm{s} \mat{1}) \\
\mat{C} &\gets \mat{F} \odot \mat{C} + \mat{I} \odot \phi(\mat{S})
\end{align*}
В этих преобразованиях часто случается, что я упускаю из виду заглавные буквы одной или нескольких переменных. Поскольку эти уравнения довольно хорошо выравниваются, это легко заметить в выводе, но также случается, что это не сразу видно. Я нахожу, что команды \vec
и \mat
делают ядро LaTeX более читабельным, и при проверке формул мне легче сосредоточиться на этих командах, чем на фактическом случае каждой переменной. Мне просто нравится верить, что нет ничего плохого в использовании технологий для компенсации моих недостатков.
При этом я согласен, что принудительное выполнение регистра — не лучшее решение. Поэтому сейчас я ищу решение, которое уведомляет меня, когда регистр не соответствует тому, что я ожидаю для вектора/матрицы, чтобы мне не приходилось выполнять проверку вручную.
решение1
Проверьте, совпадает ли аргумент с его версией в нижнем/верхнем регистре. Если они отличаются, выдайте предупреждение.
\documentclass{article}
\usepackage{amsmath}
\usepackage{bm}
\ExplSyntaxOn
\RenewDocumentCommand{\vec}{m}{\tsjolder_vec:n { #1 }}
\NewDocumentCommand{\mat}{m}{\tsjolder_mat:n { #1 }}
\msg_new:nnn { tsjolder/vec-mat } { wrong-case}
{
WARNING:~#1~used~when~#2~is~expected~\msg_line_context:
}
\cs_new_protected:Nn \tsjolder_vec:n
{
\str_if_eq:eeTF { #1 } { \str_lowercase:n { #1 } }
{
\bm{#1}
}
{
\msg_warning:nnnn { tsjolder/vec-mat } { wrong-case} { uppercase } { lowercase }
\bm{\text_lowercase:n { #1 }}
}
}
\cs_new_protected:Nn \tsjolder_mat:n
{
\str_if_eq:eeTF { #1 } { \str_uppercase:n { #1 } }
{
\bm{#1}
}
{
\msg_warning:nnnn { tsjolder/vec-mat } { wrong-case} { lowercase } { uppercase }
\bm{\text_uppercase:n { #1 }}
}
}
\ExplSyntaxOn
\begin{document}
$\mat{a}\vec{B}$
\end{document}
С этим кодом вы получите
Package tsjolder/vec-mat Warning: WARNING: lowercase used when uppercase is
(tsjolder/vec-mat) expected on line 41
Package tsjolder/vec-mat Warning: WARNING: uppercase used when lowercase is
(tsjolder/vec-mat) expected on line 41
в файле журнала и на терминале, но вывод в любом случае будет правильным.
решение2
Вы можете получить код символа с помощью `[char]
и сравнить его с \ifnum
. Прописные латинские буквы имеют код 65-90, а строчные — код 97-122.
МВЭ:
\documentclass{article}
\def\vec#1{\ifnum`#1<97 #1 not lc!\else$\mathbf{#1}$\fi}
\def\mat#1{\ifnum`#1>90 #1 not uc!\else$\mathbf{#1}$\fi}
\begin{document}
\vec{X}
\vec{x}
\mat{X}
\mat{x}
\end{document}
Результат:
Более надежная версия, которая проверяет фактические диапазоны и может обрабатывать предопределенные аргументы вместо буквальных символов, используя stringstrings
:
\documentclass{article}
\usepackage{stringstrings}
\def\vec#1{\testsolelylowercase{#1}\ifsolelylowercase$\mathbf{#1}$\else#1 not lc!\fi}
\def\mat#1{\testsolelyuppercase{#1}\ifsolelyuppercase$\mathbf{#1}$\else#1 not uc!\fi}
\begin{document}
\vec{X}
\vec{x}
\mat{X}
\mat{x}
% this one fails with the \ifnum code above
\def\myx{x}
\mat{\myx}
\end{document}
Я немного скорректировал логику проверок stringstrings
таким образом, что неалфавитные аргументы, такие как \delta
и , 1
разрешены, а макросы проверяют только первый символ, поэтому такие вещи, как , X'
также допустимы для матрицы (но x'
не ).
Проверка теперь следующая: если первый символ не является буквой, то всегда печатать, в противном случае проверять, является ли первый символ заглавным, то отклонять для вектора и принимать для матрицы. Обратите внимание, что я изменил имена макросов, потому что \vec
уже определено.
Также я переместил математический режим за пределы команды, что отлично работает. Я использовал \text
from amsmath
для сообщения, но я полагаю, что это должно быть фактическим \GenericWarning
и тогда \text
не нужно.
\documentclass{article}
\usepackage{amsmath}
\usepackage{stringstrings}
\def\chkvec#1{%
\testleadingalpha{#1}%
\ifleadingalpha%
\testcapitalized{#1}%
\ifcapitalized%
\text{vector argument } #1 \text{ starts with upper case!}%
\else%
\mathbf{#1}%
\fi%
\else%
\mathbf{#1}%
\fi}
\def\chkmat#1{%
\testleadingalpha{#1}%
\ifleadingalpha%
\testcapitalized{#1}%
\ifcapitalized%
\mathbf{#1}%
\else%
\text{matrix argument }#1\text{ starts with lower case!}%
\fi%
\else%
\mathbf{#1}%
\fi}
\begin{document}
$\chkvec{X^2}$
$\chkvec{x^2}$
$\chkmat{X'}$
$\chkmat{x'}$
\def\myx{X}
$\chkmat{\myx}$
$\chkvec{\delta}$
$\chkvec{1}$
\end{document}