# A simple macro for optimization problems (ifnum error)

I am trying to create a simple macro for optimization problems that must (as per the publisher) compile with LaTeX2e. I want the macro to look like the example below in terms of usage (the actual processing of constraints is more complicated, but I tried to eliminate distracting details; this was the simplest example that I could find that produced an error). I obviously need to record when the first constraint is added so that subsequent constraints do not print "subject to". However, when I add any of the three commented lines below, LaTeX tells me that the ifnum is incomplete. Additionally, if I change the second argument of setcounter to 1, then I do not receive an error (although the behavior is not correct). What is the problem here?

\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}


It's the usual problem of a conditional straddling two columns.

There's a simpler solution: print “subject to” only if not already printed.

\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}


• I had not encountered the problem of a conditional across columns before. Your code solves the simple problem above, and your insight allowed me to fix my actual problem -- thanks for explaining why you did what you did! – Stirling Jul 1 '16 at 0:02
• It could also be solved with the counter, but as it would just assume 0 and 1 values, a new conditional is simpler. The \global is necessary because alignment cells form groups; on the other hand, \setcounter acts globally, so no special precaution would be needed. – egreg Jul 1 '16 at 0:09

You can't have all the rest of the stuff to the \\ before the \else when the antecedent of the conditional is false because TeX assumes that the end of the conditional will never terminate.

You can work around this by doing something like the following

\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}


I think it would be more elegant to set this up with, for example, a key-value interface, using a comma-separated list for the constraints. The LaTeX 3 syntax makes this pretty easy, although it is not essential. (And it can all be compiled with 2e - there's no problem there.)

• I typically use the macro here: tex.stackexchange.com/questions/98141/… (with some updates), but it made the publisher anxious, so I just decided to switch to something simpler for this project. – Stirling Jul 1 '16 at 0:06
• Ah, well. At least LaTeX itself doesn't make your publisher anxious. Be happy ;). – cfr Jul 1 '16 at 0:07