TransWikia.com

Expressive macro for tensors; raised and lowered indices

TeX - LaTeX Asked by Myridium on January 27, 2021

Does anyone have a satisfying solution to the problem of typesetting tensors with raised/lowered indices? For example, I can write the following equation:
ddot x^mu = Gamma^{mu}{}_{alpha}{}_{beta} dot x^alpha dot x^beta

enter image description here

When writing a lot of tensors, this is cumbersome.

What I’m looking for is a way to construct a command which can produce tensors like Gamma above with more expressive syntax. For example, a command tens that operates like this would be ideal:

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

The key quality of my desired syntax is that there is an arbitrary number of arguments of two distinct types. Argument encased in { } are raised indices, while arguments encased in [ ] are lowered indices. I don’t need a command that looks exactly like this; I am looking for something that is similarly expressive.

Does anyone have a solution to this problem? An implementation of a tens command that works as above? I don’t know how to do this.

4 Answers

In my opinion, the subscripts and superscripts are a single argument.

You can use the tensor package, without reinventing the wheel: it has a very handy syntax.

I also provide a tens command according to your preferences.

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
   }
   { kern2scriptspace }
 }
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
   }
   { kern2scriptspace }
 }
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}[alphabeta]
tens{dot{x}}{alpha} tens{dot{x}}{beta}
]

[
tens{Gamma}[mu]{nurho}[alpha]{nurho}
tens{dot{Gamma}}[mu]{nurho}[alpha]{nurho}
]

end{document}

enter image description here

Correct answer by egreg on January 27, 2021

Here is something that works like you describe but with round brackets instead of curly ones. As usual such things can be a bit fragile, so occasionally you need to relax a bit to mark it fully work, as can be seen in the second example.

documentclass{article}
makeatletter
edeftens@u{(}
edeftens@l{[}
deftens@U#1)#2{{}^{#1}expandaftertens@i#2relax}
deftens@L#1]#2{{}_{#1}expandaftertens@i#2relax}
deftens@i#1#2{edeftens@t{#1}%
ifxtens@ttens@u
expandaftertens@U#2
else
ifxtens@ttens@l
expandaftertens@L#2
else
#1#2
fi
fi}
deftens#1#2{#1expandaftertens@i#2}
makeatother
begin{document}
begin{tabular}{rl}
works: &
$tens{Gamma}[mu](nurho)[alpha](nurho) dottens{x}(alpha)
dottens{x}(beta)$ [2em]

does not work: & 
$tens{Gamma}[mu](nurho)[alpha](nurho) dottens{x}(alpha)
tens{x}(beta)$ [2em]

relax and it works again: &
$tens{Gamma}[mu](nurho)[alpha](nurho) dottens{x}(alpha)relax
tens{x}(beta)$ 
end{tabular}
end{document}

enter image description here

To be clear: such macros are mainly for recreation purposes and not for the real world. These days the LaTeX world has enough other problems...

Answered by user229669 on January 27, 2021

I wouldn’t use such a syntax, but SemanTeX can be set up to accomplish something resembling this (disclaimer: I am the author). Note that you will need a recent update of SemanTeX (October or later, I think) for this example to work. Note that I also prefer defining keys dot and ddot instead of directly using the commands dot and ddot.

documentclass{article}

usepackage{semantex}

NewVariableClasstens[
    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}

enter image description here


Personally, I would prefer to use a more keyval-based syntax, as below:

documentclass{article}

usepackage{semantex}

NewVariableClassTensor[
    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] $

NewObjectTensortGamma{Gamma}
NewObjectTensortx{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}

enter image description here

Answered by Gaussler on January 27, 2021

The definition of your desired macro tens using TeX primitives follows:

deftens#1{#1futureletnexttensA}
deftensA{deftensX{}%
   ifxnext[deftensX[##1]{{}_{##1}futureletnexttensA}fi 
   ifxnextbgroup deftensX##1{{}^{##1}futureletnexttensA}fi
   tensX}

%% test:

$tensGamma [mu]{nurho}[alpha]{nurho}$

$ddottens{x}{mu} = tens{Gamma}{mu}[alpha][beta] 
                      dottens{x}{alpha} dottens{x}{beta}$

Answered by wipet on January 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP