Macro expressive pour les tenseurs; indices élevés et abaissés

Nov 27 2020

Quelqu'un at-il une solution satisfaisante au problème de la composition de tenseurs avec des indices élevés / abaissés? Par exemple, je peux écrire l'équation suivante:\ddot x^\mu = \Gamma^{\mu}{}_{\alpha}{}_{\beta} \dot x^\alpha \dot x^\beta

Lors de l'écriture de nombreux tenseurs, c'est fastidieux.

Ce que je recherche, c'est un moyen de construire une commande qui peut produire des tenseurs comme \Gammaci-dessus avec une syntaxe plus expressive. Par exemple, une commande \tensqui fonctionne comme ceci serait idéale:

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

La qualité clé de ma syntaxe souhaitée est qu'il existe un nombre arbitraire d'arguments de deux types distincts . Les arguments inclus dans { }sont des indices élevés, tandis que les arguments inclus dans [ ]sont des indices abaissés. Je n'ai pas besoin d'une commande qui ressemble exactement à ceci; Je recherche quelque chose qui soit tout aussi expressif.

Quelqu'un at-il une solution à ce problème? Une implémentation d'une \tenscommande qui fonctionne comme ci-dessus? Je ne sais pas comment faire ça.

Réponses

6 egreg Nov 27 2020 at 20:17

À mon avis, les indices et les exposants sont un seul argument.

Vous pouvez utiliser le tensorpackage, sans réinventer la roue: il a une syntaxe très pratique.

Je propose également une \tenscommande selon vos préférences.

\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

Je n'utiliserais pas une telle syntaxe, mais SemanTeX peut être configuré pour accomplir quelque chose qui ressemble à ceci (avertissement: je suis l'auteur). Notez que vous aurez besoin d'une mise à jour récente de SemanTeX (octobre ou plus tard, je pense) pour que cet exemple fonctionne. Notez que je préfère également définir des clés dotet ddotau lieu d'utiliser directement les commandes \dotet \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}


Personnellement, je préférerais utiliser une syntaxe plus basée sur les valeurs de clé, comme ci-dessous:

\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

Voici quelque chose qui fonctionne comme vous le décrivez, mais avec des parenthèses rondes au lieu de boucles. Comme d'habitude, de telles choses peuvent être un peu fragiles, vous devez donc parfois le \relaxmarquer un peu pour que cela fonctionne pleinement, comme on peut le voir dans le deuxième exemple.

\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}

Pour être clair: ces macros sont principalement destinées à des fins de loisirs et non pour le monde réel. De nos jours, le monde LaTeX a suffisamment d'autres problèmes ...

1 wipet Nov 30 2020 at 22:04

La définition de la macro souhaitée à l' \tensaide des primitives TeX est la suivante:

\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}$