
我一直在使用類似的東西
\renewcommand\vec[1] {\boldsymbol{\MakeLowercase{#1}}}
\newcommand\mat[1] {\boldsymbol{\MakeUppercase{#1}}}
現在排版向量和矩陣已經有一段時間了。然而,每次我問的時候都會出現這個問題A 問題\Makeuppercase
,人們告訴我在數學模式下使用是個壞主意。此外,\Makeuppercase
對我來說已經很糟糕了在此刻,所以我可能需要一個替代方案。
對於這種替代方案,我認為如果我可以在矩陣使用小寫符號(或向量使用大寫符號)時發出警告就足夠了。我知道如何使用\@warning
or發出警告\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}