我正在尝试为优化问题创建一个简单的宏,该宏必须(根据发布者)使用 LaTeX2e 进行编译。我希望该宏在使用方面看起来像下面的示例(约束的实际处理更复杂,但我试图消除分散注意力的细节;这是我能找到的产生错误的最简单的示例)。我显然需要记录第一个约束的添加时间,以便后续约束不会打印“subject to”。但是,当我添加下面三行注释中的任何一行时,LaTeX 告诉我 ifnum 不完整。此外,如果我将 setcounter 的第二个参数更改为 1,则不会收到错误(尽管行为不正确)。这里的问题是什么?
\documentclass{article}
\usepackage{amsmath}
\newcounter{opc}
\newcommand{\optimizationproblem}[3]
{
\setcounter{opc}{1}
\begin{array}{ll}
\text{#1} & #2 #3
\end{array}
}
\newcommand{\constraint}[1]
{
\ifnum \value{opc} = 1
%\setcounter{opc}{0}
\\ \text{subject to} & #1
%\setcounter{opc}{0}
\else
\\ #1
\fi
%\setcounter{opc}{0}
}
\begin{document}
\begin{equation*}
\optimizationproblem
{minimize}
{c^{T} x}
{
\constraint{A x = b}
\constraint{x \geq 0}
}
\end{equation*}
\end{document}
答案1
这是条件跨越两列的常见问题。
有一个更简单的解决方案:仅当尚未打印时才打印“subject to”。
\documentclass{article}
\usepackage{amsmath}
\newif\ifsubjectto
\newcommand{\optimizationproblem}[3]{%
\global\subjecttotrue
\begin{array}{ll}
\text{#1} & #2 #3
\end{array}%
}
\newcommand{\constraint}[1]{%
\\
\ifsubjectto
\global\subjecttofalse
\text{subject to}%
\fi & #1
}
\begin{document}
\begin{equation*}
\optimizationproblem{minimize}
{c^{T} x}
{
\constraint{A x = b}
\constraint{x \geq 0}
}
\end{equation*}
\end{document}
答案2
当条件的前提为假时,您不能将所有其余的内容都放在之前,\\
因为\else
TeX 假定条件的结尾永远不会终止。
您可以通过执行以下操作来解决这个问题
\documentclass{article}
\usepackage{amsmath}
\newcounter{opc}
\newcommand{\optimizationproblem}[3]
{%
\setcounter{opc}{1}%
\begin{array}{ll}
\text{#1} & #2 #3
\end{array}%
}
\newcommand{\constraint}[1]
{%
\ifnum \value{opc} = 1
\subjectto{#1}%
\else
\anotherline{#1}%
\fi
\setcounter{opc}{0}%
}
\newcommand\subjectto[1]{\\\text{subject to} & #1}
\newcommand\anotherline[1]{\\#1}
\begin{document}
\begin{equation*}
\optimizationproblem
{minimize}
{c^{T} x}
{
\constraint{A x = b}
\constraint{x \geq 0}
}
\end{equation*}
\end{document}
我认为,例如,使用键值接口来设置它会更优雅,使用逗号分隔的列表作为约束。LaTeX 3 语法使这变得非常容易,尽管它不是必需的。(而且所有这些都可以用 2e 编译 - 那里没有问题。)