变量序列的宏

变量序列的宏

目前,我有一个宏\bigseq,它接受一个变量名和一个最后一个数字并生成#1_{1},#1_{2},\ldots,#1_{#2},例如x_{1},x_{2},\ldots,x_{n}

现在,有时我想在给定特定数字时生成一个完整序列。我想要一个宏\seq,它采用第一个和最后一个索引并输出整个序列。例如,对于37,我想得到x_{3},x_{4},x_{5},x_{6},x_{7}。这可能吗?

答案1

\documentclass[a4paper]{article}
\usepackage{etoolbox}
\newcommand{\bigseqx}[3]{{#1_{#2}%
  \count255=\numexpr#2\relax
  \whileboolexpr{ test {\ifnumcomp{\count255}{<}{\numexpr#3\relax}}}
    {\advance\count255 by 1 ,#1_{\number\count255 }}%
}}

\begin{document}
$\bigseqx{x}{3}{7}$
\end{document}

一些解释。我们使用\whileboolexpretoolbox 的宏(还有其他软件包提供类似的功能);它需要两个参数:第一个是由关键字引入的测试test,后面是实际测试,因此只要测试结果为真,我们就会执行第二个参数中的代码。但在开始此循环之前,我们排版序列的第一个元素,并将临时计数器设置为第二个参数\bigseqx(第一个是变量的符号)。代码递增计数器并排版逗号和下一个下标变量。当计数器等于第三个参数时,测试结果为假。

我们将临时计数器设置为由计算的值\numexpr,并再次用于\numexpr将计数器与第三个参数进行比较,因此输入如下

\bigseqx{x}{\value{cnt}}{\value{cnt}+9}

(其中cnt是 LaTeX 计数器)有效;\numexpr\value{cnt}+9\relax评估表达式(并且\relax标记被吞掉,因为它只是数字表达式的终止符)。


注意:此刻我写下的答案我并没有使用expl3

它甚至更短expl3

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\bigseqx}{mmm}
 {
  #1\sb{#2}
  \int_step_inline:nnnn { #2+1 } { 1 } { #3 }
   {
    , #1\sb{##1}
   }
 }
\ExplSyntaxOff
\begin{document}

$\bigseqx{x}{3}{7}$

\end{document}

这个想法与上面的相同,但工作原理应该更清楚:我们打印第一个元素,然后打印逗号和下一个元素,直到完成。关键点是\int_step_inline:nnnn它将起点、步骤、终点和要执行的操作作为参数,其中我们可以通过引用当前值#1(这是##1因为\int_step_inline:nnnn在定义中使用了)。前三个参数中的每一个都可以是使用 的任何数学工具的整数表达式expl3

答案2

以下是我针对以下问题做出的调整后的回答编写宏来排版一系列可变数量的项,现在允许用户定义最小索引。除了\ensuremath可以根据需要删除的 robust 之外,它是完全可扩展的。使用它的方式如下\seq{<var>}{<min>}{<max>},例如\seq{x}{3}{7}

\documentclass{article}

\usepackage{amsmath}

\newcommand*{\seq}[3]{% #1 = variable, #2/#3 = min./max. number of terms
    \ensuremath{%
    \ifnum#2<0 \else
        #1_{#2}\expandafter\seqx\expandafter{\the\numexpr#2+1\relax}{#3}{#1}%
    \fi
    }%
}

% Internal recursive macro
\newcommand*{\seqx}[4]{% #1 = current index, #2 = max index, #3 = variable, #4 = \fi
    #4% = \fi
    \ifnum#1>#2 \else
        +#3_{#1}%
        \expandafter\seqx\expandafter{\the\numexpr#1+1\relax}{#2}{#3}%
    \fi
}

\begin{document}

\seq{x}{1}{10}

\seq{x}{3}{7}

\end{document}

答案3

我想您也可以使用 \forloop 包来做到这一点,下面是一个小例子:

\documentclass{report}
\usepackage{forloop}
\begin{document}
\newcounter{themenumber}
\newcommand{\seq}[2]
{%
\forloop{themenumber}{#1}{\value{themenumber} < #2}{%
    $ x_{\arabic{themenumber}}, $%
}%
}

\seq{2}{6}
\end{document}

相关内容