我想编写一个用于优化问题的宏,我目前的方法是编写一个宏,它采用目标函数和约束列表。条目以逗号分隔,每个条目的类型为“(不)相等/范围”,例如
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
等来替换实际参数;最后是输入。可选参数用于容纳alignat
或alignedat
需要知道要排版的列对数。
定义一个内部函数来提供所需的模板;然后将输入以逗号分隔并将每个项目提供给模板函数。
\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}