
Eu tenho usado algo como
\renewcommand\vec[1] {\boldsymbol{\MakeLowercase{#1}}}
\newcommand\mat[1] {\boldsymbol{\MakeUppercase{#1}}}
já há algum tempo para compor vetores e matrizes. No entanto, toda vez que isso surge quando perguntoa pergunta, as pessoas me dizem que é uma má ideia usar \Makeuppercase
no modo matemático. Além disso, \Makeuppercase
está praticamente quebrado para mimneste ponto, então talvez eu precise de uma alternativa.
Para esta alternativa, pensei que seria suficiente emitir um aviso quando um símbolo minúsculo fosse usado para matrizes (ou um símbolo maiúsculo para vetores). Eu sei como emitir um aviso usando \@warning
ou \GenericWarning
, mas não consigo descobrir como testar se algo está em letras minúsculas ou maiúsculas.
Além disso, essa seria realmente a melhor maneira de impor uma composição tipográfica consistente de vetores e matrizes, conforme descrito acima, ou devo considerar algo completamente diferente?
Termo aditivo
Como todo mundo continua comentando o quão ruim é uma ideia impor casos no modo matemático, sinto que devo enfatizar que estou ciente dessas preocupações e esta é minha tentativa de encontrar uma solução alternativa. Minha principal preocupação é que os comandos que eu tinha me ajudassem a manter minha notação consistente e a semântica do meu código LaTeX clara e eu preferiria manter essa consistência de alguma forma.
Para dar um exemplo, um conjunto típico de equações com as quais trabalho é o seguinte:
\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*}
Agora, dependendo do contexto, pode ser útil/necessário escrever isto da seguinte forma:
\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*}
Nessas transformações acontece frequentemente que eu negligencie a capitalização de uma ou mais variáveis. Como essas equações se alinham muito bem, seria fácil identificá-las na saída, mas também acontece que não são imediatamente visíveis. Acho que os \vec
comandos e \mat
tornam o núcleo do LaTeX mais legível e, ao verificar as fórmulas, acho mais fácil focar nesses comandos do que no caso real de cada variável. Só gosto de acreditar que não há nada de errado em usar a tecnologia para compensar minhas deficiências.
Dito isto, concordo que a execução do caso não é a melhor coisa a fazer. Portanto, agora estou procurando uma solução que me avise quando o caso não corresponder ao que espero para um vetor/matriz para que eu não precise fazer a verificação manualmente.
Responder1
Verifique se o argumento é igual à versão em minúsculas/maiúsculas. Se forem diferentes, emita um aviso.
\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}
Com este código você obteria
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
no arquivo de log e no terminal, mas a saída estará correta de qualquer maneira.
Responder2
Você pode recuperar o código do caractere `[char]
e compará-lo com \ifnum
. O latim maiúsculo é 65-90 e o minúsculo é 97-122.
MWE:
\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}
Resultado:
Uma versão mais robusta que verifica os intervalos reais e pode lidar com argumentos predefinidos em vez de caracteres literais, usando 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}
Ajustei stringstrings
um pouco a lógica das verificações para que argumentos não alfabéticos como \delta
e 1
sejam permitidos, e as macros verificam apenas o primeiro caractere, então coisas como X'
também são aceitáveis para uma matriz (mas x'
não são).
A verificação agora é: se o primeiro caractere não for alfabético imprima sempre, caso contrário verifique se o primeiro caractere é maiúsculo, rejeite para um vetor e aceite para uma matriz. Observe que mudei os nomes das macros porque \vec
já está definido.
Também mudei o modo matemático para fora do comando, o que funciona bem. Usei \text
from amsmath
para a mensagem, mas imagino que deva ser real \GenericWarning
e \text
não é necessário.
\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}