8

I tried to write derived tensor products using semantex (copied from p. 27 in the manual).

\documentclass{article}

\usepackage{amsmath,semantex}

\NewSymbolClass\MyBinaryOperator[
    define keys={
        {Lder}{upper=L},
        {Rder}{upper=R},
    },
]
\NewObject\MyBinaryOperator\tensor{\otimes}[
    define keys={
        {der}{Lder},
    },
]
\NewObject\MyBinaryOperator\fibre{\times}[
    % Americans are free to call it \fiber instead
    define keys={
        {der}{Rder},
    },
]

\begin{document}

\begin{equation}
    A\tensor[R,der] B 
\end{equation}

\end{document}

enter image description here

But I would like the L to appear on top of the tensor symbol instead of to the right. Is this possible?

Thanks!

4
  • Is my question unclear? I'm new to this site so just tell me if I can write it better. :)
    – Cinque
    Nov 15 '20 at 13:17
  • Use \overset{\tensor}{L}.
    – azetina
    Nov 15 '20 at 15:41
  • @azetina Thanks for your answer! But is it possible to make it a key like above so I can still write \tensor[R,der]?
    – Cinque
    Nov 15 '20 at 15:46
  • 1
    Yes. Use command command=\overset{L}.
    – azetina
    Nov 15 '20 at 16:23
6

Here is a MWE using semantex. The idea is to use the command key and input the desired command. In this case, you want to over set the L on the symbol. Thus, using command=\overset{L} will suffice.

enter image description here

\documentclass{article}

\usepackage{amsmath,semantex}

\NewSymbolClass\MyBinaryOperator[
    define keys={
        {Lder}{command=\overset{L}},
        {Rder}{upper=R},
    },
]
\NewObject\MyBinaryOperator\tensor{\otimes}[
    define keys={
        {der}{Lder},
    },
]
\NewObject\MyBinaryOperator\fibre{\times}[
    % Americans are free to call it \fiber instead
    define keys={
        {der}{Rder},
    },
]

\begin{document}

\begin{equation}
    A\tensor[R,der] B 
\end{equation}

\end{document}
2
  • Thanks, this was exactly what I wanted! :)
    – Cinque
    Nov 15 '20 at 18:05
  • Note that @egreg solution and Alan Xiang are also viable and robust.
    – azetina
    Nov 15 '20 at 18:10
5

I don't know how to do it with semantex, but it's not difficult with other tools.

\documentclass{article}
\usepackage{amsmath}
%\usepackage{xparse} % not needed with LaTeX 2020-10-01 or later

\ExplSyntaxOn

\keys_define:nn { cinque/tensor }
 {
  der .tl_set:N = \l__cinque_tensor_upper_tl,
  der .default:n = L,
  unknown .code:n = \tl_set_rescan:Nnx \l__cinque_tensor_subscript_tl { } { \l_keys_key_str },
 }
\tl_new:N \l__cinque_tensor_subscript_tl

\NewDocumentCommand{\tensor}{O{}}
 {
  \group_begin:
  \keys_set:nn { cinque/tensor } { #1 }
  \tl_if_empty:NTF \l__cinque_tensor_upper_tl
   { \otimes }
   { \overset{\l__cinque_tensor_upper_tl}{\otimes} }
  \tl_if_empty:NF \l__cinque_tensor_subscript_tl { \sb{\l__cinque_tensor_subscript_tl} }
  \group_end:
 }

\ExplSyntaxOff

\begin{document}

$A\otimes B$

$A\tensor B$

$A\tensor[R] B$

$A\tensor[der,R] B$

$A\tensor[R,der] B$

$A\tensor[\mathcal{X}] B$

\end{document}

enter image description here

6
  • What does \sb mean?
    – azetina
    Nov 15 '20 at 16:30
  • 1
    @azetina It's an alias for _; needed because _ doesn't mean “subscript” in the scope of \ExplSyntaxOn
    – egreg
    Nov 15 '20 at 16:45
  • @egreg When I wrote semantex, I tried using the \tl_set_rescan:Nnn trick, but ran into issues since some math did not come out as expected after being turned into a string and rescanned. This (and a few other things) prompted me to build my own, separate keyval system (using \keyval_parse:NNn). I never quite figured out the pattern of what code survived the string-ification and rescan. Maybe you can enlighten me?
    – Gaussler
    Nov 15 '20 at 16:56
  • @Gaussler I have no idea of what will turn out to be useful. I'd just do \NewDocumentCommand{\dertensor}{o}{\overset{L}{\otimes}\IfValueT{#1}{_{#1}}} which is simple and effective.
    – egreg
    Nov 15 '20 at 17:07
  • @egreg Yes, but it’s sometimes hard to properly control your notation from the preamble. Imagine you make a command \stalk for stalks of a sheaf at a point so that \stalk{#1}{#2} produces #1_{#2}. Applying it to \mathcal{O}_{X}, and you get a double subscript error. I prefer a keyval-based solution where I can write \sheafF[\vX, stalk=\primep] (with \vX meaning “variable X” and \primep being the prime ideal fraktured p) and make it stack the subscripts according to a preprogrammed procedure.
    – Gaussler
    Nov 15 '20 at 17:12
4

enter image description here

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xparse}
\usepackage{expl3}
\usepackage{amsmath}

\ExplSyntaxOn
\clist_new:N \l_doc_tmpa_clist
\tl_new:N \l_doc_tmpa_tl
\tl_new:N \l_doc_tmpb_tl

\tl_new:N \g_doc_template_a_tl
\tl_gset:Nn \g_doc_template_a_tl {
  \overset{\tiny L}{*1}
}

\cs_generate_variant:Nn \tl_set_rescan:Nnn {NnV}

\DeclareDocumentCommand{\tensor}{O{}}{
  \clist_set:Nn \l_doc_tmpa_clist {#1}
  \tl_set:Nn \l_doc_tmpa_tl {\otimes}
  
  \clist_map_inline:Nn \l_doc_tmpa_clist {
    \str_case:nn {##1}{
      {der} {
       \tl_set_eq:NN \l_doc_tmpb_tl \g_doc_template_a_tl
       \regex_replace_once:nnN {*1} {\u{\l_doc_tmpa_tl}} \l_doc_tmpb_tl
       \tl_set_eq:NN \l_doc_tmpa_tl \l_doc_tmpb_tl
      }
    }
  }
  
  \clist_map_inline:Nn \l_doc_tmpa_clist {
    \str_case:nn {##1}{
      {R} {
       \tl_set:No \l_doc_tmpa_tl {\l_doc_tmpa_tl \c_math_subscript_token {R}}
      }
    }
  }
  
  \mathbin{\tl_use:N \l_doc_tmpa_tl}
}
\ExplSyntaxOff

\begin{document}

\par $a \tensor[R] b$
\par $a \tensor[R,der] b$
\par $a \tensor[der] b$
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.