11

I need a simple latex macro which takes some format and creates a sequence out of it. For example,

\macro[N]{x^N y^N} => x^1 y^1 + x^2 y^2 + \dots + x^N y^N
\macro[N]{x^N y_N} => x^1 y_1 + x^2 y_2 + \dots + x^N y_N
\macro[N]{(x^N y_N)^2} => (x^1 y_1)^2 + (x^2 y_2)^2 + \dots + (x^N y_N)^2

enter image description here

  • 1
    Welcome! (And nice question, although I think I've seen a duplicate, but I'm unable to find it on the spot...). Just a question: what should happen if N≤2? – Rmano Mar 17 '23 at 08:56

7 Answers7

9

You can define an auxiliary macro and do the replacement.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\makesum}{O{N}m} { \akkapelli_makesum:nn { #1 } { #2 } }

\tl_new:N \l__akkapelli_makesum_template_tl \cs_generate_variant:Nn \cs_set_protected:Nn { NV }

\cs_new_protected:Nn \akkapelli_makesum:nn { \tl_set:Nn \l__akkapelli_makesum_template_tl { #2 } \tl_replace_all:Nnn \l__akkapelli_makesum_template_tl { #1 } { {##1} } \cs_set_protected:NV __akkapelli_makesum_do:n \l__akkapelli_makesum_template_tl __akkapelli_makesum_do:n { 1 } + __akkapelli_makesum_do:n { 2 } + \dots + __akkapelli_makesum_do:n { #1 } }

\ExplSyntaxOff

\begin{document}

$\makesum{x^Ny^N}$

$\makesum{x^Ny_N}$

$\makesum[M]{(x^M y_M)^2}$

\end{document}

The optional argument (default N) is substituted in the second argument with #1, so we can define a macro based on it and use it.

enter image description here

However, I'd prefer a different approach: in the second argument you use #1 for the “variable part”:

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\makesum}{O{N}m} { \akkapelli_makesum:nn { #1 } { #2 } }

\cs_new_protected:Nn \akkapelli_makesum:nn { \cs_set_protected:Nn __akkapelli_makesum_do:n { #2 } __akkapelli_makesum_do:n { 1 } + __akkapelli_makesum_do:n { 2 } + \dots + __akkapelli_makesum_do:n { #1 } }

\ExplSyntaxOff

\begin{document}

$\makesum{x^#1y^#1}$

$\makesum{x^#1y_#1}$

$\makesum[M]{(x^#1 y_#1)^2}$

$\makesum[100]{(x^{#1} y_{#1})^2}$

\end{document}

Note the necessary braces in the last case.

enter image description here

If integer exponents are used, it is better to cope with the “small” cases.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\makesum}{O{N}m} { \akkapelli_makesum:nn { #1 } { #2 } }

\cs_new_protected:Nn \akkapelli_makesum:nn { \cs_set_protected:Nn __akkapelli_makesum_do:n { #2 } \regex_match:nnTF { \A [0-9]* \Z } { #1 } {% numeric argument \int_case:nnF { #1 } { {0}{0} {1}{__akkapelli_makesum_do:n { 1 }} {2}{__akkapelli_makesum_do:n { 1 } + __akkapelli_makesum_do:n { 2 }} {3}{__akkapelli_makesum_do:n { 1 } + __akkapelli_makesum_do:n { 2 } + __akkapelli_makesum_do:n { 3 }} } { __akkapelli_makesum_generic:n { #1 } } } { __akkapelli_makesum_generic:n { #1 } } }

\cs_new_protected:Nn __akkapelli_makesum_generic:n { __akkapelli_makesum_do:n { 1 } + __akkapelli_makesum_do:n { 2 } + \dots + __akkapelli_makesum_do:n { #1 } }

\ExplSyntaxOff

\begin{document}

$\makesum{x^#1y^#1}$

$\makesum{x^#1y_#1}$

$\makesum[M]{(x^#1 y_#1)^2}$

$\makesum[1]{x^{#1} y_{#1}}$

$\makesum[2]{x^{#1} y_{#1}}$

$\makesum[3]{x^{#1} y_{#1}}$

$\makesum[4]{x^{#1} y_{#1}}$

$\makesum[100]{(x^{#1} y_{#1})^2}$

\end{document}

enter image description here

egreg
  • 1,121,712
6

If you are willing to write \N for the symbol to be replaced, I can offer the following solution.

\documentclass{article}
\usepackage{amsmath}

\newcommand{\macro}[2][]{ \def\N{1} #2 + \def\N{2} #2 +\cdots+ \def\N{#1} #2 }

\begin{document} \verb|\macro[N]{x^\N y^\N}| gives $\macro[N]{x^\N y^\N}$

\bigskip\verb|\macro[N]{x^\N y_\N}| gives $\macro[N]{x^\N y_\N}$

\bigskip\verb|\macro[M]{(x^\N y_\N)^2}| gives $\macro[M]{(x^\N y_\N)^2}$

\end{document}

Result

Οὖτις
  • 2,897
  • 1
  • 5
  • 18
6

This solution is a purely (e-)TeX one. It uses the same idea as Οὖτις's, but it doesn't require that the input be a control sequence (the input must be a character). I got rid of the optional argument because I dont understand its purpose, but if it was intended as egreg used it, you can simply change the \def to a \newcommand whose optional argument is by default N.

\def\macro#1#2{{%
    \everyeof={}%                   So nothing weird happens at the end of \scantokens
    \catcode`#1=\active%            Make the parameter an active character
    \scantokens{%                   Retokenize the following code so that #1's catcode is changed
        \def#1{1}#2\def#1{2}+#2%    Print a_1+a_2
    }%
    +\cdots+#2%                     Print +...+a_N
}}

$$\macro{N}{x^Ny^N}$$ $$\macro{N}{x^Ny_N}$$ $$\macro{M}{(x^My_M)}$$

Gives:

macro usage

Slurp
  • 876
5

You did not tell whether with the result of \macro the focus is on obtaining the set of tokens, e.g., for defining another macro from it, or is on obtaining some nice typesetting in the pdf file.

If you just need some nice typesetting in the pdf-file, and if the LaTeX-distribution used by you is up to date, then probably some regexp-replacing via the function \regexp_replace_all:nnN of expl3's l3regexp-package does what you need:

\documentclass{article}

\ExplSyntaxOn \cs_new_protected:Npn \macro [#1] #2 { \group_begin: \tl_set:Nn \l_tmpa_tl {#2} \group_begin: \regex_replace_all:nnN {#1} {1} \l_tmpa_tl \l_tmpa_tl \group_end: + \group_begin: \regex_replace_all:nnN {#1} {2} \l_tmpa_tl \l_tmpa_tl \group_end: + \dots + \regex_replace_all:nnN {#1} {\cB{#1\cE}} \l_tmpa_tl \l_tmpa_tl \group_end: } \ExplSyntaxOff

\begin{document}

% ( causes LaTeX to switch to inline math mode. % ) causes LaTeX to switch back to whatever typesetting it was in before % switching to inline math took place.

\verb|(\macro[N]{x^N y^N})| yields: (\macro[N]{x^N y^N})

\verb|(\macro[N]{x^N y_N})| yields: (\macro[N]{x^N y_N})

\verb|(\macro[M]{(x^M y_M)^2})| yields: (\macro[M]{(x^M y_M)^2})

\verb|(\macro[Moo]{(x^Moo y_Moo)^2})| yields: (\macro[Moo]{(x^Moo y_Moo)^2})

\end{document}

enter image description here


Be aware that using argument-delimiters [ and ] (square brackets) for macro arguments which must be provided with each call/instance of the macro in question actually is considered very bad practise in LaTeX. This deviates from usual syntax in LaTeX - in LaTeX usually only optional macro arguments, i.e., arguments which you don't need to provide with each call/instance of the macro in question, are to be nested between [ and ].

This time I did it this way in order for the code to comply to your requests.

Ulrich Diez
  • 28,770
3

What about this?

\documentclass{article}
\usepackage{pgffor}

\newcommand{\macro}[2]{% \foreach \n in {1,...,#1}{% #2% \ifnum\n<#1 + \fi }% }

\begin{document}

$\macro{5}{x^\n y^\n}$

$\macro{5}{(x^\n y_\n)^2}$

\end{document}

enter image description here

scd
  • 774
2

You are almost there. A few remarks:

  • macros are called \newcommand in LaTeX
  • you can't name them the way you did
  • instead, use simple terms using characters only (no digits, _ etc.)
  • the first parameter [1] indicates the number of parameters passed, later accessed as parmeter #1 (i.e. #2, #3 etc. if you pass more)
  • I used math-mode $ $ inside, but that depends on the context you'll use your macro in
  • LaTeX just expands the the content of #1 character by character ... that's why I needed to use {#1} inside to "break this"

Find more on macros in this wikibook. Which makes me aware of using \ensuremath, see there.

result

\documentclass[10pt]{article}

\newcommand\A[1]{$x^1 y^1 + x^2 y^2 + \dots + x^{#1} y^{#1}$} \newcommand\B[1]{$x^1 y_1 + x^2 y_2 + \dots + x^{#1} y_{#1}$} \newcommand\C[1]{$(x^1 y_1)^2 + (x^2 y_2)^2 + \dots + (x^{#1} y_{#1})^2$}

\begin{document}

\A{13} \bigskip

\B{-33} \bigskip

\C{123}

\end{document}

MS-SPO
  • 11,519
0

A Lua solution:

\documentclass{article}
\usepackage{amsmath}
\usepackage{luacode}

\begin{luacode} function makesum(placeholder, template) tex.print( template:gsub(placeholder, "1") .. "+" .. template:gsub(placeholder, "2") .. [[+ \dots + ]] .. template) end \end{luacode}

\ExplSyntaxOn

\NewDocumentCommand\makesum {O{N} m} { \directlua{makesum("\luaescapestring{\unexpanded{#1}}", "\luaescapestring{\unexpanded{#2}}")} } % we need \unexpanded here to preserve the fragile and old-style robust commands because \luaescapestring fully expands the argument without doubling '#', see https://tex.stackexchange.com/a/638779/250119 for list of common Lua functions for manipulation

\ExplSyntaxOff

\begin{document}

$\makesum{x^Ny^N}$

$\makesum{\vec{x}^Ny^N}$

$\makesum{x^Ny_N}$

$\makesum[M]{(x^M y_M)^2}$

\end{document}

This uses string.gsub without "proper" escaping, so ensure % does not appear in the placeholder or the template (see https://stackoverflow.com/questions/9790688/escaping-strings-for-gsub for workarounds).

output image

user202729
  • 7,143