Macro expressivo para tensores; índices elevados e baixos

Nov 27 2020

Alguém tem uma solução satisfatória para o problema de tensores de composição com índices elevados / reduzidos? Por exemplo, posso escrever a seguinte equação:\ddot x^\mu = \Gamma^{\mu}{}_{\alpha}{}_{\beta} \dot x^\alpha \dot x^\beta

Ao escrever muitos tensores, isso é complicado.

O que procuro é uma forma de construir um comando que possa produzir tensores como \Gammaacima com uma sintaxe mais expressiva. Por exemplo, um comando \tensque opera assim seria o ideal:

\ddot \tens{x}{\mu} = \tens{Gamma}{\mu}[\alpha][\beta] \dot \tens{x}{\alpha} \tens{x}{\beta}

A principal qualidade da minha sintaxe desejada é que há um número arbitrário de argumentos de dois tipos distintos . Os argumentos inseridos em { }são índices elevados, enquanto os argumentos inseridos em [ ]são índices reduzidos. Não preciso de um comando exatamente assim; Estou procurando algo que seja igualmente expressivo.

Alguém tem uma solução para este problema? Uma implementação de um \tenscomando que funciona como acima? Eu não sei fazer isso.

Respostas

6 egreg Nov 27 2020 at 20:17

Na minha opinião, os subscritos e sobrescritos são um único argumento.

Você pode usar o tensorpacote, sem reinventar a roda: ele tem uma sintaxe muito útil.

Eu também forneço um \tenscomando de acordo com suas preferências.

\documentclass{article}
\usepackage{tensor}

%\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\tens}{mo}
 {
  #1
  \IfNoValueTF { #2 } 
   {
    \__myridium_tens_up_lookup:
   }
   {
    \__myridium_tens_down_lookup: [ #2 ]
   }
 }

\cs_new_protected:Nn \__myridium_tens_down_lookup:
 {
  \peek_charcode_ignore_spaces:NTF [
   {
    \__myridium_tens_down:w
   }
   { \kern2\scriptspace }
 }
\cs_new_protected:Npn \__myridium_tens_down:w [ #1 ]
 {
  {\mathstrut}
  \sb{#1}
  \kern-\scriptspace
  \__myridium_tens_up_lookup:
 }
\cs_new_protected:Nn \__myridium_tens_up_lookup:
 {
  \peek_catcode_ignore_spaces:NTF \c_group_begin_token
   {
    \__myridium_tens_up:n
   }
   { \kern2\scriptspace }
 }
\cs_new_protected:Nn \__myridium_tens_up:n
 {
  {\mathstrut}
  \sp{#1}
  \kern-\scriptspace
  \__myridium_tens_down_lookup:
 }
\ExplSyntaxOff

\begin{document}

\subsection*{With \texttt{tensor}}
\[
\tensor{\ddot{x}}{^\mu}=
\tensor{\Gamma}{^\mu_\alpha_\beta}
\tensor{\dot{x}}{^\alpha} \tensor{\dot{x}}{^\beta}
\]

\[
\tensor{\Gamma}{_\mu^\nu^\rho_\alpha^\nu^\rho}
\tensor{\dot{\Gamma}}{_\mu^\nu^\rho_\alpha^\nu^\rho}
\]

\subsection*{With the hand-made macro}
\[
\tens{\ddot{x}}{\mu}=
\tens{\Gamma}{\mu}[\alpha\beta]
\tens{\dot{x}}{\alpha} \tens{\dot{x}}{\beta}
\]

\[
\tens{\Gamma}[\mu]{\nu\rho}[\alpha]{\nu\rho}
\tens{\dot{\Gamma}}[\mu]{\nu\rho}[\alpha]{\nu\rho}
\]

\end{document}

5 Gaussler Nov 27 2020 at 18:23

Eu não usaria essa sintaxe, mas o SemanTeX pode ser configurado para realizar algo semelhante a isso (isenção de responsabilidade: eu sou o autor). Observe que você precisará de uma atualização recente do SemanTeX (outubro ou mais tarde, eu acho) para que este exemplo funcione. Observe que também prefiro definir as teclas dote, em ddotvez de usar diretamente os comandos \dote \ddot.

\documentclass{article}

\usepackage{semantex}

\NewVariableClass\tens[
    output=\tens,
    definekeys={
        {dot}{ command=\dot },
        {ddot}{ command=\ddot },
        {preindex}{ rightreturn, symbolputright={{}} },
        {postindex}{ rightreturn, symbolputright=\kern-\scriptspace },
    },
    definekeys[1]={
        {default}{ preindex, lower={#1}, postindex },
        {arg}{ preindex, upper={#1}, postindex },
    },
]

\begin{document}

$ \tens{\dot x}{\mu} = \tens{\dot{\Gamma}}{\mu}[\alpha][\beta] \tens{\dot{x}}{\alpha} \tens{\dot{x}}{\beta} $

$ \tens{\ddot x}{\mu} = \tens{\dot{\Gamma}}{\mu}[\alpha][\beta] \tens{\dot{x}}{\alpha} \tens{\dot{x}}{\beta} $

$ \tens{x}[ddot]{\mu} = \tens{\Gamma}[dot]{\mu}[\alpha][\beta] \tens{x}[dot]{\alpha} \tens{x}[dot]{\beta} $

\end{document}


Pessoalmente, prefiro usar uma sintaxe mais baseada em keyval, como a seguir:

\documentclass{article}

\usepackage{semantex}

\NewVariableClass\Tensor[
    output=\Tensor,
    definekeys={
        {dot}{ command=\dot },
        {ddot}{ command=\ddot },
        {preindex}{ rightreturn, symbolputright={{}} },
        {postindex}{ rightreturn, symbolputright=\kern-\scriptspace },
    },
    definekeys[1]={
        {up}{ preindex, upper={#1}, postindex },
        {low}{ preindex, lower={#1}, postindex },
    },
]

\begin{document}

$ \Tensor{x}[dot,up=\mu] = \Tensor{\Gamma}[dot,up=\mu,low=\alpha,low=\beta] \Tensor{x}[dot,up=\alpha] \Tensor{x}[dot,up=\beta] $

$ \Tensor{x}[dot,up=\mu] = \Tensor{\Gamma}[dot,up=\mu,low=\alpha,low=\beta] \Tensor{x}[dot,up=\alpha] \Tensor{x}[dot,up=\beta] $

\NewObject\Tensor\tGamma{\Gamma}
\NewObject\Tensor\tx{x}

$ \tx[dot,up=\mu] = \tGamma[dot,up=\mu,low=\alpha,low=\beta] \tx[dot,up=\alpha] \tx[dot,up=\beta] $

$ \tx[dot,up=\mu] = \tGamma[dot,up=\mu,low=\alpha,low=\beta] \tx[dot,up=\alpha] \tx[dot,up=\beta] $

\end{document}

2 Noname Nov 27 2020 at 10:41

Aqui está algo que funciona como você descreveu, mas com colchetes em vez de curvas. Como de costume, essas coisas podem ser um pouco frágeis, então ocasionalmente você precisa \relaxum pouco para marcá-lo totalmente funcionar, como pode ser visto no segundo exemplo.

\documentclass{article}
\makeatletter
\edef\tens@u{(}
\edef\tens@l{[}
\def\tens@U#1)#2{{}^{#1}\expandafter\tens@i#2\relax}
\def\tens@L#1]#2{{}_{#1}\expandafter\tens@i#2\relax}
\def\tens@i#1#2{\edef\tens@t{#1}%
\ifx\tens@t\tens@u
\expandafter\tens@U#2
\else
\ifx\tens@t\tens@l
\expandafter\tens@L#2
\else
#1#2
\fi
\fi}
\def\tens#1#2{#1\expandafter\tens@i#2}
\makeatother
\begin{document}
\begin{tabular}{rl}
works: &
$\tens{\Gamma}[\mu](\nu\rho)[\alpha](\nu\rho) \dot\tens{x}(\alpha) \dot\tens{x}(\beta)$ \\[2em]

does not work: & 
$\tens{\Gamma}[\mu](\nu\rho)[\alpha](\nu\rho) \dot\tens{x}(\alpha) \tens{x}(\beta)$ \\[2em]

relax and it works again: &
$\tens{\Gamma}[\mu](\nu\rho)[\alpha](\nu\rho) \dot\tens{x}(\alpha)\relax \tens{x}(\beta)$ \\
\end{tabular}
\end{document}

Para ser claro: essas macros são principalmente para fins recreativos e não para o mundo real. Hoje em dia, o mundo LaTeX tem muitos outros problemas ...

1 wipet Nov 30 2020 at 22:04

A definição de sua macro desejada \tensusando primitivas TeX segue:

\def\tens#1{#1\futurelet\next\tensA}
\def\tensA{\def\tensX{}%
   \ifx\next[\def\tensX[##1]{{}_{##1}\futurelet\next\tensA}\fi 
   \ifx\next\bgroup \def\tensX##1{{}^{##1}\futurelet\next\tensA}\fi
   \tensX}

%% test:

$\tens\Gamma [\mu]{\nu\rho}[\alpha]{\nu\rho}$

$\ddot\tens{x}{\mu} = \tens{\Gamma}{\mu}[\alpha][\beta] \dot\tens{x}{\alpha} \dot\tens{x}{\beta}$