我一直在使用类似的东西
\renewcommand\vec[1] {\boldsymbol{\MakeLowercase{#1}}}
\newcommand\mat[1] {\boldsymbol{\MakeUppercase{#1}}}
我已经花了一段时间来排版向量和矩阵。然而,每次我问A 问题\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
fromamsmath
来显示消息,但我认为这应该是实际的\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}