对齐中的 foreach 循环

对齐中的 foreach 循环

我想编写一个用于优化问题的宏,我目前的方法是编写一个宏,它采用目标函数和约束列表。条目以逗号分隔,每个条目的类型为“(不)相等/范围”,例如

x_i \geq 0 / i=1,...,n

我的想法来自定义具有任意数量参数的命令。但是,这不允许在对齐内有新行。

我的朋友发现了使用\pgfplotsforeachungrouped,但现在我无法&在循环内写入。以下代码可以编译,但看起来不太好看。

编辑:现在有 类型的条目\x/\y

\documentclass{article}
\usepackage{extarrows,pgffor}
\usepackage{pgfplots}
\begin{document}
  \begin{align*}
    \pgfplotsforeachungrouped \x/\y in {a/3, b/5, foo/0}{
      \x_i : \x = \x \quad i=\y \\
    }
\end{align*}
\end{document}

在此处输入图片描述

\x_i : \x &= \x \quad i=\y \\但是如果我用(仅添加)替换循环主体&,我会收到多个错误“未定义的控制序列。”

此外,使用 entrya/{0,\ldots,5}无法按预期工作。它仅接受0

我也希望将变量的范围放在\tag或类似的东西里面。结合这一点,我得到了另一个Undefined control sequence`\y¸。

  • 那么我怎样才能在循环内对齐这些线呢?已在 Steven B. Segletes 的回答中解决
  • 怎样才能在条目中包含更复杂的值?
  • 我怎样才能将条目的第二部分放在里面\tag*{}

可能有用的链接:我不明白表格中的 Foreach 循环,插入缺少的末端组,所以我无法判断这个想法是否有帮助,但它似乎是朝着这个方向发展的。

答案1

这是一个相当通用的宏,它接受四个强制参数和一个可选参数,如代码中所述。

这个想法是定义输入的方案,在示例中是#1/#2,但它可以是任何带有任意数量参数(当然最多 9 个)的方案;我们还为每一行定义模板,使用#1等来替换实际参数;最后是输入。可选参数用于容纳alignatalignedat需要知道要排版的列对数。

定义一个内部函数来提供所需的模板;然后将输入以逗号分隔并将每个项目提供给模板函数。

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\makealignment}{mommm}
 { % #1 = environment
   % #2 = optional for alignat
   % #3 = scheme for the variables
   % #4 = scheme for the rows
   % #5 = items
   \cs_set_protected:Npn \__hennich_row:w #3 \q_stop { #4 }
   \seq_set_split:Nnn \l__hennich_input_seq { , } { #5 }
   \seq_set_map:NNn
     \l__hennich_output_seq
     \l__hennich_input_seq
     { \__hennich_row:n { ##1 } }
   \IfNoValueTF{#2}{\begin{#1}}{\begin{#1}{#2}}
   \seq_use:Nn \l__hennich_output_seq { \\ }
   \end{#1}
 }

\seq_new:N \l__hennich_input_seq
\seq_new:N \l__hennich_output_seq
\cs_new_protected:Nn \__hennich_row:n { \__hennich_row:w #1 \q_stop }

\ExplSyntaxOff

\begin{document}

\makealignment{align*}
  {#1/#2}
  {#1_{i} : #1 &= #1 & i&=#2}
  {a/3, b/5, foo/0}

\makealignment{alignat}[2]
  {#1/#2}
  {#1_{i} : #1 &= #1 &\qquad i&=#2}
  {a/3, b/5, foo/0}

\end{document}

在此处输入图片描述

答案2

在这里我构建了一个标记列表,然后将其传递给align*。 使用\xaddtotoks允许列表中的第一个标记(此处\x)在构建标记列表时扩展一次。

\documentclass{article}
\usepackage{listofitems,amsmath}
\newtoks\alignbuild
\newcommand{\addtotoks}[2]{#1\expandafter{\the#1#2}}
\newcommand{\xaddtotoks}[2]{\expandafter\addtotoks\expandafter#1\expandafter{#2}}
\begin{document}
\readlist\mylist{1,2,3,666}
\foreachitem\x\in\mylist{%
  \xaddtotoks\alignbuild{\x : }%
  \xaddtotoks\alignbuild{\x &= }%
  \xaddtotoks\alignbuild{\x\\}%
}
\def\tmp{\begin{align*}}
\expandafter\tmp\the\alignbuild
\end{align*}
\end{document}

在此处输入图片描述

相关内容