\documentclass[a4paper]{article} \usepackage{remreset} \usepackage[short]{optidef} \usepackage{listings} \usepackage{enumitem} \usepackage{hyperref} \lstset{basicstyle=\ttfamily,breaklines=true} % Title Page \title{\textit{\textbf{Optidef}} \\ A Latex library for optimization problems\\ \textnormal{Version - 2.2}} \author{Jesus Lago Garcia} \makeatletter \renewcommand \thesection {\@arabic\c@section} \@removefromreset{section}{chapter} \makeatother \begin{document} \maketitle \newpage \tableofcontents \newpage \section{Introduction and features} This Latex library provides a standard set of environments for writing optimization problems. The most important features are: \begin{enumerate} \item It references optimization problem using three different policies: no equation is referenced, the problem is referenced with a single label, each equation has an individual reference. \item It defines two problem size formats: a long format and a short format. \item It allows four different outputs for the location of the constraints. \item It allows the definition of a limitless number of constraints. \item Four different type of problems: \textit{minimize}, \textit{maximize}, \textit{arg min} and \textit{arg max}. \end{enumerate} \section{Using the package} The package can be imported by directly adding \begin{lstlisting} \usepackage{optidef} \end{lstlisting} to the document preamble. When importing the packages two options can be used, \verb|short| and \verb|nocomma|: \begin{lstlisting} \usepackage[short,nocomma]{optidef} \end{lstlisting} For an explanation of the \verb|short| option check Section \ref{sec:longshort}. For the \verb|nocomma| option check Section \ref{sec:comma}. For a detailed description of how to use the package keep reading the next section. \section{Environment Syntax Definition} Considering that \verb|Const.i| stands for constraint $i$, \verb|LHS.i| stands for the left-hand-side of constraint $i$, and \verb|RHS.i| for the right-hand-side counterpart, the basic structure to define a general optimization problem with $N$ constraints is: \begin{verbatim} \begin{mini#}|sizeFormat|[constraintFormat] {optimizationVariable} {objectiveFunction\label{objective}} {\label{optimizationProblem}} {optimizationResult} \addConstraint{LHS.1}{RHS.1\label{Const1}}{extraConst1} \addConstraint{LHS.2}{RHS.2\label{Const2}}{extraConst2} . . \addConstraint{LHS.N}{RHS.N\label{ConstN}}{extraConstN} \end{mini#} \end{verbatim} \subsection{Definition of Problem parameters} \begin{enumerate}[label=(\roman*)] \item \verb|mini#|: defines the type of environment and reference used. There are four environments: \verb|mini|, \verb|maxi|, \verb|argmini|, and \verb|argmaxi|. There are three types of referencing: \verb|mini|, \verb|mini*| and \verb|mini!|. Consult Section \ref{sec:environments} for more details. \item (Optional) \verb|sizeFormat|: optional parameter to define the size format of the problem. The possible values are: \begin{itemize} \item l: for the long format as defined in Section \ref{sec:longshort}. \item s: for the short format as defined in Section \ref{sec:longshort}. \end{itemize} \item (Optional) \verb|constraintFormat|: optional parameter to change the format of the constraints. The parameter \verb|constraintFormat| can take the following values: \begin{itemize} \item 0: for the Standard definition in Section \ref{sec:format}. \item 1: for Alternative 1 in Section \ref{sec:format}. \item 2: for Alternative 2 in Section \ref{sec:format} \item 3: for Alternative 3 in Section \ref{sec:format} \end{itemize} \item \verb|optimizationVariable|: variable to be optimizated in the problem, e.g. $w \in \Re^N$. \item \verb|objectiveFunction\label{objective}|: function to be minimized/maximized as a function of the optimization variable, e.g. $\|w\|_2$. If required, the objective function label should also be included withing this term \item \verb|\label{optimizationProblem}|: it defines the main and general reference for the optimization problem. It is used for the \verb|mini| and \verb|mini!| enviroments. In the \verb|mini*| environment should be left blank, i.e. \{\}, \textbf{not to be ommited}. \item \verb|optimizationResult|: a term expressing the result of the optimization problem, e.g. $J(w^*)~=$. If not needed leave it blank, \textbf{not to be ommited}. \end{enumerate} The last two defined problem parameters, \verb|\label{optimizationProblem}| and \verb|optimizationResult|, could be made optional. However, in order to improve the problem readibility, line breaking between the 7 parametes was implemented; unfortunately, linea breaking and optional parameters are not compatible and these two parameters had to be made mandatory. \subsection{Adding Constraints} After the definition of the problem parameters, the environment accepts the definition of an infinite number of constraints. For this definitions the following command is used: ~\\ \verb|\addConstraint{LHS.k}{RHS.k\label{Const.k}}{extraConst.k}| ~\\ The command accepts three different parameters \begin{enumerate} \item \verb|LHS.k|: the left-hand side of the the constraint $k$, e.g. $3w^\top w$. \item (Optional) \verb|RHS.k\label{Const.k}|: the right-hand side of the constraint k if the equations should be aligned in the equality or inequality signs, e.g. $\leq \|w\|_\infty$. If required, the constraint label should also be included in this term. \item (Optional) \verb|extraConst.k|: optional parameter to add extra alignment point for additional constraint information. An example would be the constraint names. Look Example \ref{ex:extra} or the fourth described feature in Section \ref{sec:alignment}. \end{enumerate} \subsubsection{Constraints referencing} Notice that the label for the constraints is always included in the right hand side expression and it only makes sense for the case of using the \verb|mini!| enviroment. The label of the objective function can also be included in a similar way. \section{Environment Types} \label{sec:environments} There are three basic environments depending on the type of referencing that should be used. \begin{enumerate} \item The \textbf{mini} environment for defining problems with a single reference label: \begin{mini} {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{} \addConstraint{g(w)}{=0} \end{mini} \item The \textbf{mini*} environment if the problem does not have to be referenced: \begin{mini*} {w}{f(w)+ R(w+6x)} {}{} \addConstraint{g(w)}{=0} \end{mini*} \item The \textbf{mini!} environment if each equation should be referenced: \begin{mini!} {w}{f(w)+ R(w+6x)\label{eq:Ex2}} {\label{eq:Ex1}}{} \addConstraint{g(w)}{=0} \end{mini!} \end{enumerate} \noindent Additionally, there are four basic definitions of optimization problems: \begin{enumerate} \item The \textbf{mini} environment: \begin{mini} {w}{f(w)+ R(w+6x)} {}{} \addConstraint{g(w)}{=0} \end{mini} \item The \textbf{maxi} environment: \begin{maxi} {w}{f(w)+ R(w+6x)} {}{} \addConstraint{g(w)}{=0} \end{maxi} \item The \textbf{argmini} environment: \begin{argmini} {w}{f(w)+ R(w+6x)} {}{} \addConstraint{g(w)}{=0} \end{argmini} \item The \textbf{argmaxi} environment: \begin{argmaxi} {w}{f(w)+ R(w+6x)} {}{} \addConstraint{g(w)}{=0} \end{argmaxi} \end{enumerate} \section{Long and Short Output Formats} \label{sec:longshort} The library permits the definition of two different problem size: a long format and a short format. \subsection{Long Format} Selected by \verb|sizeFormat|=l. It makes use of \textit{subject to} and \textit{minimize/maximize} \begin{mini*}|l| {w}{f(w)+ R(w+6x)}{}{} \addConstraint{g(w)}{=0} \end{mini*} \subsection{Short Format} Selected by \verb|sizeFormat|=s. It uses instead the shorter \textit{s.t.} and \textit{min/max} \begin{mini*}|s| {w}{f(w)+ R(w+6x)}{}{} \addConstraint{g(w)}{=0} \end{mini*} \noindent By the default the long format is used. To change the default to the short format the package must be imported with the \verb|short| option: \begin{lstlisting} \usepackage[short]{optidef} \end{lstlisting} \section{Alignment of Equations} \label{sec:alignment} \begin{enumerate} \item Alignment at the beginning of the words \textit{minimize} and \textit{subject to}: \begin{mini} {w}{f(w)+ R(w+6x)}{}{} \addConstraint{g(w)}{=0} \end{mini} \item (Optional) Alignment at the $=,~>,~<$ signs of the constraints. \begin{mini*}[1] {w}{f(w)+ R(w+6x)}{}{} \addConstraint{g(w)+h(w)}{=0} \addConstraint{l(w)}{=5w.} \end{mini*} \item (Optional) Alignment of the longest constraint and the objective function: \begin{mini*} {w}{f(w)+ R(w+6x)}{}{} \addConstraint{g(w)+h(w)}{=0} \addConstraint{l(w)}{=5w.} \end{mini*} \item (Optional) Third alignment point on the constraints to set some constraint features. A clear example could be the constraints names: \begin{mini*} {w}{f(w)+ R(w+6x)}{}{} \addConstraint{g(w)+h(w)}{=0,}{\text{(Topological Constraint)}} \addConstraint{l(w)}{=5w,\quad}{\text{(Boundary Constraint)}} \end{mini*} or the index of the constraints: \begin{mini*} {w,u}{f(w)+ R(w+6x)}{}{} \addConstraint{g(w_k)+h(w_k)}{=0,}{k=0,\ldots,N-1} \addConstraint{l(w_k)}{=5u,\quad}{k=0,\ldots,N-1} \end{mini*} \end{enumerate} \section{Output Formats for the Constraints} \label{sec:format} There are four basic output formats for the location of the constraints. They are controlled by the environment parameter \verb|constraintFormat|. \subsection{Standard Format} It is the default format and if \verb|constraintFormat| left blank it is used. Alternatively can be also set by selecting \verb|constraintFormat|=0. By default the constraints are aligned with the objective function, to the right of \textit{subject to} and with a second alignment point at the $=,~\leq,~\geq$: \begin{mini} {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{} \addConstraint{g(w)+h(w)}{=0} \addConstraint{t(w)}{=0.} \end{mini} \subsection{Alternative 1} Selected by \verb|constraintFormat|=1. It locates the constraints below \textit{subject to} and keeps them aligned at the inequality/equality signs: \begin{mini}[1] {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{} \addConstraint{g(w)+h(w)}{=0} \addConstraint{t(w)}{=0.} \end{mini} \subsection{Alternative 2} Selected by \verb|constraintFormat|=2. It aligns all the constraints with the objective function. \begin{mini}[2] {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{} \addConstraint{g(w)+h(w)}{=0} \addConstraint{t(w)}{=0.} \end{mini} \subsection{Alternative 3} Selected by \verb|constraintFormat|=3. It aligns all the constraints below \textit{subject to}: \begin{mini}[3] {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{} \addConstraint{g(w)+h(w)}{=0} \addConstraint{t(w)}{=0.} \end{mini} \section{Default comma at the end of the constraint} \label{sec:comma} By default, the algorithms adds a comma at the end of any constraint that is not the last one. This feature was implemented due to correctness of mathematical notation. However, this behavior can be removed by adding the option \verb|nocomma| when importing the package: \begin{lstlisting} \usepackage[nocomma]{optidef} \end{lstlisting} \section{Examples} \subsection{Example 1 - mini environment} The code: \begin{verbatim} \begin{mini} {w}{f(w)+ R(w+6x)} {\label{eq:Example1}}{} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \end{verbatim} \noindent outputs: \begin{mini} {w}{f(w)+ R(w+6x)} {\label{eq:Ex11}}{} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \subsection{Example 2 - mini* environment} On the other hand: \begin{verbatim} \begin{mini*} {w}{f(w)+ R(w+6x)} {}{} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6,} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini*} \end{verbatim} \noindent it is almost the same but removing the reference: \begin{mini*} {w}{f(w)+ R(w+6x)} {}{} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini*} \subsection{Example 3 - mini! environment} \noindent Finally, the multireferencing environment outputs: \begin{verbatim} \begin{mini!} {w}{f(w)+ R(w+6x) \label{eq:ObjectiveExample1}} {\label{eq:Example1}}{} \addConstraint{g(w)}{=0 \label{eq:C1Example3}} \addConstraint{n(w)}{= 6 \label{eq:C2Example1}} \addConstraint{L(w)+r(x)}{=Kw+p \label{eq:C3Example1}} \addConstraint{h(x)}{=0. \label{eq:C4Example1}} \end{mini!} \end{verbatim} \begin{mini!} {w}{f(w)+ R(w+6x)\label{eq:ObjectiveExample3}} {\label{eq:Example3}} {} \addConstraint{g(w)}{=0 \label{eq:C1Example3}} \addConstraint{n(w)}{= 6 \label{eq:C2Example3}} \addConstraint{L(w)+r(x)}{=Kw+p \label{eq:C3Example3}} \addConstraint{h(x)}{=0.\label{eq:C4Example3}} \end{mini!} \subsection{Example 4 - Problem Result} \noindent Adding the problem result: \begin{verbatim} \begin{mini} {w}{f(w)+ R(w+6x)} {\label{eq:Example1}} {J(w^*)=} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \end{verbatim} \noindent outputs: \begin{mini} {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{J(w^*)~=~} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \subsection{Example 5 - Short Format} \noindent Adding the short format parameter: \begin{verbatim} \begin{mini}|s| {w}{f(w)+ R(w+6x)} {\label{eq:Example1}} {} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \end{verbatim} \noindent outputs: \begin{mini}|s| {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \subsection{Example 6 - Alternative 1 for Constraints} \noindent If including a 1 as optional parameter, the first constraint will appear aligned to the left right below \textit{subject to}. \begin{verbatim} \begin{mini}[1] {w}{f(w)+ R(w+6x)} {\label{eq:Example1}} {} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \end{verbatim} \noindent outputs: \begin{mini}[1] {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \subsection{Example 7 - Alternative 2 for Constraints} \noindent If including a 2 as optional parameter, the constraint will appear to the right of \textit{subject to} but a single alignment point. \begin{verbatim} \begin{mini}[2] {w}{f(w)+ R(w+6x)} {\label{eq:Example1}} {} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \end{verbatim} \noindent outputs: \begin{mini}[2] {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \subsection{Example 8 - Alternative 3 for Constraints} \noindent If including a 3 as optional parameter, the first constraint will appear aligned to the left right below \textit{subject to} and with a single alignment point. \begin{verbatim} \begin{mini}[3] {w}{f(w)+ R(w+6x)} {\label{eq:Example1}} {} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \end{verbatim} \noindent outputs: \begin{mini}[3] {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{mini} \subsection{Example 9 - Extra Alignment in the Constraints} \label{ex:extra} Adding optional alignment to add constraint names: \begin{verbatim} \begin{mini*} {w}{f(w)+ R(w+6x)} {}{} \addConstraint{g(w)}{=0,}{ \quad \text{(Dynamic constraint)}} \addConstraint{n(w)}{= 6,}{ \quad \text{(Boundary constraint)}} \addConstraint{L(w)+r(x)}{=Kw+p,}{ \quad \text{(Random constraint)}} \addConstraint{h(x)}{=0,}{ \quad \text{(Path constraint).}} \end{mini*} \end{verbatim} \subsection{Example 10 - The \textit{argmini} Environment} Similar to the \verb|mini|, \verb|mini*| and \verb|mini!| environments, the environments \verb|argmini|, \verb|argmini*| and \verb|argmini!| are very similar environments that use the same syntax but the output is slightly different: \begin{verbatim} \begin{argmini} {w}{f(w)+ R(w+6x)} {\label{eq:Example1}}{w^*=} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{argmini} \end{verbatim} \noindent outputs: \begin{argmini} {w}{f(w)+ R(w+6x)} {\label{eq:Ex1}}{w^*~=~} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{argmini} \subsection{Example 11 - The \textit{maxi} and \textit{argmaxi} Environments} Exactly the same syntax and definition as the previous environments, but now for defining maximization environments. The following code serves for illustration: \begin{verbatim} \begin{maxi} {w}{f(w)+ R(w+6x)} {g(w)}{=0} {\label{eq:Example1}}{} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{maxi} \end{verbatim} \noindent outputs: \begin{maxi} {w}{f(w)+ R(w+6x)} {\label{eq:Example1}}{} \addConstraint{g(w)}{=0} \addConstraint{n(w)}{= 6} \addConstraint{L(w)+r(x)}{=Kw+p} \addConstraint{h(x)}{=0.} \end{maxi} \subsection{Example 12 - All Possible Parameters} \begin{verbatim} \begin{mini*}|s|[1] {w}{f(w)+ R(w+6x)} {}{w^*=} \addConstraint{g(w)}{=0,}{ \quad \text{(Dynamic constraint)}} \addConstraint{n(w)}{= 6,}{ \quad \text{(Boundary constraint)}} \addConstraint{L(w)+r(x)}{=Kw+p,}{ \quad \text{(Random constraint)}} \addConstraint{h(x)}{=0,}{ \quad \text{(Path constraint).}} \end{mini*} \end{verbatim} \begin{mini!}|s|[2] {w}{f(w)+ R(w+6x)\label{eq:ObjectiveExample3}} {\label{eq:Example3}} {w^*=} \addConstraint{g(w)}{=0 \label{eq:C1Example3}} \addConstraint{n(w)}{= 6 \label{eq:C2Example3}} \addConstraint{L(w)+r(x)}{=Kw+p \label{eq:C3Example3}} \addConstraint{h(x)}{=0.\label{eq:C4Example3}} \end{mini!} \section{Long Optimization Variables} The standard appearance for long optimization variables is as follows: \begin{mini!} {x_0,u_0,x_1,\hdots,u_{N-1},x_N} {\sum_{k=0}^{N-1} L(x_k,u_k)\!\!+\!\!E(x_N)\label{OCPobj}} {\label{eq:OCP}}{} \addConstraint{x_{k+1}-f(x_k,u_k)}{= 0, \label{dOCP:modelc}\quad k=0,\dots,N-1} \addConstraint{h(x_k,u_k)}{\leq 0, \quad k=0,\dots,N-1} \addConstraint{r(x_0,x_N)}{= 0. \label{dOCP:boundary}} \end{mini!} \noindent A possible way to reduce the large variable spacing is to stack them with the command: \begin{verbatim} \substack{x_0,u_0,x_1,\hdots,\\u_{N-1},x_N} \end{verbatim} \begin{mini!} {\substack{x_0,u_0,x_1,\hdots,\\ u_{N-1},x_N}} {\sum_{k=0}^{N-1} L(x_k,u_k)\!\!+\!\!E(x_N)\label{OCPobj}} {\label{eq:OCP}}{} \addConstraint{x_{k+1}-f(x_k,u_k)}{= 0, \label{dOCP:modelc}\quad k=0,\dots,N-1} \addConstraint{h(x_k,u_k)}{\leq 0, \quad k=0,\dots,N-1} \addConstraint{r(x_0,x_N)}{= 0. \label{dOCP:boundary}} \end{mini!} \section{Code definition} \begin{lstlisting} % optidef - Version 2.2 % %Copyright 2016 J. Lago Garcia % %This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this license or (at your option) any later version. %The latest version of this license is in http://www.latex-project.org/lppl.txt and version 1.3 or later is part of all distributions of LaTeX version 2005/12/01 or later. % %This work has the LPPL maintenance status 'maintained'. The Current Maintainer of this work is J. Lago Garcia. % %E-mail: jesus.lago.garcia@venus.uni-freiburg.de % %This work consists of the file optidef.sty. \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{optidef}[2016/10/22 - version=2.2, Package for defining optimization problems] \RequirePackage{environ} \RequirePackage{mathtools} \RequirePackage{xifthen} \RequirePackage{etoolbox} \RequirePackage{xparse} \RequirePackage{calc} %%%%%%%%%%%%%%%%%%%%%%% % DEFINING PACKAGE OPTIONS %%%%%%%%%%%%%%%%%%%%%%% % Default \newcommand{\defaultOCPConstraint}{,} \newcommand{\defaultProblemFormat}{l} \DeclareOption{short}{ \renewcommand{\defaultProblemFormat}{s} } \DeclareOption{long}{ \renewcommand{\defaultProblemFormat}{l} } \DeclareOption{nocomma}{ \renewcommand{\defaultOCPConstraint}{} } \ProcessOptions\relax %%%%%%%%%%%%%%%%%%%%%%% % VARIABLES DEFINITION %%%%%%%%%%%%%%%%%%%%%%% % Toogle to indicate if during the addConstraint command the first constraint should be built together with "subject to" \newtoggle{bodyCon} \toggletrue{bodyCon} % If the previous constraints has 3 elements, we avoid setting \span\span at the beginning of the next constraint. If there is no previous third element, \span\span must be included for correct alignment \newtoggle{previousThird} \togglefalse{previousThird} \newcommand{\spanit}{} % Variable used to define the subject to word for short and long versions \newcommand{\bodySubjectTo}{Unset Subject to} % Variable used for defining if the long problem format or the short problem format is used \newcommand{\localProblemFormat}{l} % Variable to storage which type of of local problem is being solved \newcommand{\localProblemType}{minimize} % Defining variable to storage problem variable \newcommand{\localOptimalVariable}{} \newlength\stextwidth %%%%%%%%%%%%%%%%%%%%%%% % OBJECTIVE COMMAND DEFINITION %%%%%%%%%%%%%%%%%%%%%%% \newcommand{\bodyobj}[4] { \ifthenelse{\isempty{#4}} { &\underset{\displaystyle #1}{\mathrlap{\mathrm{#3}}\phantom{\mathrm{subject~to}}} \quad #2\span\span\span\span } { #4~ &\underset{\displaystyle #1}{\mathrlap{\mathrm{#3}}\phantom{\mathrm{subject~to}}} \quad #2\span\span\span\span } } %% LONG VERSION "minimize" instead of "min" \newcommand{\bodyobjLong}[4] { \ifthenelse{\isempty{#4}} { &\mathmakebox[\widthof{$\underset{\displaystyle #1}{\mathrm{subject~to}}$}]{\underset{\displaystyle #1}{\mathrm{#3}}} \quad #2\span\span\span\span } { #4~ &\mathmakebox[\widthof{$\underset{\displaystyle #1}{\mathrm{subject~to}}$}]{\underset{\displaystyle #1}{\mathrm{#3}}} \quad #2\span\span\span\span } } %% SHORT VERSION "min" instead of "minimize" \newcommand{\bodyobjShort}[4] { \ifthenelse{\isempty{#4}} { &\underset{\displaystyle #1}{\mathrm{#3}} \quad #2\span\span\span\span } { #4 ~ &\underset{\displaystyle #1}{\mathrm{#3}} \quad #2\span\span\span\span } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % DEFINITION DIFFERENT TYPE OF BODY CONSTRAINTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% A BODY CONSTRAINT IS THE INITIAL CONSTRAINT DEFINED WITH THE 'SUBJECT TO', DEPENDING ON THE TYPE OF PROBLEM A DIFFERENT VERSION IS USED % Main command. Dynamically redefined at every new problem definition. \DeclareDocumentCommand{\bodyconst}{m G{}} { \ifthenelse{\equal{#2}{}}{ \\ &\underset{\displaystyle \phantom{\localOptimalVariable}}{\mathrm{subject~to}} \quad & #2 }{ \\ &\underset{\displaystyle \phantom{\localOptimalVariable}}{\mathrm{subject~to}} \quad  & #2 } } \newcommand{\bodySubjectToDefinition}{ %## If the short version of "subject to", i.e. "s.t.", should be used the command \bodySubjectTo should be modified \ifthenelse{\equal{\localProblemFormat}{s}} {%% \global\def\bodySubjectTo{\mathmakebox[\widthof{$\underset{\displaystyle \phantom{\localOptimalVariable}}{\mathrm{\localProblemType}}$}][c]{\mathmakebox[\widthof{$\mathrm{\localProblemType}$}][l]{\mathrm{\kern 0.1em s.t.}}}} }{%% \global\def\bodySubjectTo{\mathmakebox[\widthof{$\underset{\displaystyle \phantom{\localOptimalVariable}}{\mathrm{\,subject~to}}$}][c]{\mathmakebox[\widthof{$\mathrm{\localProblemType}$}][l]{\mathrm{subject~to}}}} }%% % } % Standard version. \DeclareDocumentCommand{\bodyconstRight}{m G{} G{}} {%%% \bodySubjectToDefinition %## Set the first constraint according to the format used for "subject to" \ifthenelse{\equal{#3}{}}{%% \ifthenelse{\equal{#2}{}}{% \\ & \bodySubjectTo \quad & #2 }{% \\ &\bodySubjectTo \quad  & #2 }% \togglefalse{previousThird} }{%% \ifthenelse{\equal{#2}{}}{% \\ &\bodySubjectTo \quad & #2 & }{% \\ &\bodySubjectTo \quad  & #2 & }% \toggletrue{previousThird} }%% }%%% % Single alignment point but next to subject to \DeclareDocumentCommand{\bodyconstOneAlign}{m G{} G{}} { \bodySubjectToDefinition %## Set the first constraint according to the format used for "subject to" \ifthenelse{\equal{#3}{}}{ \\ &\bodySubjectTo\quad & #2 \togglefalse{previousThird} }{ \\ &\bodySubjectTo\quad & #2 & \toggletrue{previousThird} } } % Contraints below subject to and with a single alignment point \DeclareDocumentCommand{\bodyconstOneAlignBelow}{m G{} G{}} { \bodySubjectToDefinition %## Set the first constraint according to the format used for "subject to" \ifthenelse{\equal{#3}{}}{ \\ &\bodySubjectTo \span\span\span\span \\ && #2 \togglefalse{previousThird} }{ \\ &\bodySubjectTo \span\span\span\span \\ && #2 & \toggletrue{previousThird} } } % Contraints below subject to but with double alignment point \DeclareDocumentCommand{\bodyconstBelow}{m G{} G{}} { \bodySubjectToDefinition %## Set the first constraint according to the format used for "subject to" \ifthenelse{\equal{#3}{}}{ \ifthenelse{\equal{#2}{}}{ \\ &\bodySubjectTo\span\span\span\span \\ && #2 }{ \\ &\bodySubjectTo \span\span\span\span \\ & & #2 } \togglefalse{previousThird} }{ \ifthenelse{\equal{#2}{}}{ \\ &\bodySubjectTo \span\span\span\span \\ && #2 & }{ \\ &\bodySubjectTo\span\span\span\span \\ & & #2 & } \toggletrue{previousThird} } } % Contraints below subject to for the case of having a reference/label for each individual equation \DeclareDocumentCommand{\bodyconstBelowMult}{m G{} G{}} { \bodySubjectToDefinition %## Set the first constraint according to the format used for "subject to" \ifthenelse{\equal{#3}{}}{ \ifthenelse{\equal{#2}{}}{ \\ &\bodySubjectTo\span\span\span\span \nonumber \\ && #2 }{ \\ &\bodySubjectTo \span\span\span\span \nonumber \\ & & #2 } \togglefalse{previousThird} }{ \ifthenelse{\equal{#2}{}}{ \\ &\bodySubjectTo\span\span\span\span \nonumber \\ && #2 & }{ \\ &\bodySubjectTo \span\span\span\span \nonumber \\ & & #2 & } \toggletrue{previousThird} } } % Contraints below subject to and with a single alignment point for the case of having a reference/label for each individual equation \DeclareDocumentCommand{\bodyconstOneAlignBelowMult}{m G{} G{}} { \bodySubjectToDefinition %## Set the first constraint according to the format used for "subject to" \ifthenelse{\equal{#3}{}}{ \\ &\bodySubjectTo\span\span\span\span \nonumber \\ && #2 \togglefalse{previousThird} }{ \\ &\bodySubjectTo\span\span\span\span \nonumber \\ && #2 && #3 \toggletrue{previousThird} } } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % DEFINITION DIFFERENT TYPE OF ADDING CONSTRAINTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Main command. Dynamically redefined at every problem definiton. \DeclareDocumentCommand{\addConstraint}{m G{} G{}}{ % "If clause" selecting whether a third parameter (#3) defining extra constraint information is used \ifthenelse{\equal{#3}{}}{ % Second "If clause" selecting whether two or 1 elements for the constraints are used \ifthenelse{\equal{#2}{}}{ \iftoggle{bodyCon}{ \bodyconst{#1} \togglefalse{bodyCon} }{ \defaultOCPConstraint\\&\quad & #2\span\span \togglefalse{bodyCon} } }{ \iftoggle{bodyCon}{ \bodyconst{#1}{#2} \togglefalse{bodyCon} }{ \defaultOCPConstraint\\&\quad  & #2\span\span \togglefalse{bodyCon} } } \togglefalse{previousThird} }{ \iftoggle{bodyCon}{ \bodyconst{#1}{#2}{#3} \togglefalse{bodyCon} }{ \ifthenelse{\equal{#2}{}}{ \defaultOCPConstraint\\&\quad & #2 && #3 }{ \defaultOCPConstraint\\&\quad  & #2 && #3 } \togglefalse{bodyCon} } \toggletrue{previousThird} } } % Standard version of adding constraints \DeclareDocumentCommand{\standardAddConstraint}{m G{} G{}}{ \iftoggle{previousThird} {\renewcommand{\spanit}{}} {\renewcommand{\spanit}{\span\span}} \iftoggle{bodyCon}{ \bodyconstRight{#1}{#2}{#3} \togglefalse{bodyCon} }{ \ifthenelse{\equal{#2}{}}{ \ifthenelse{\equal{#3}{}}{ \defaultOCPConstraint\spanit\\&\quad & #2 \togglefalse{previousThird} }{ \defaultOCPConstraint\spanit\\&\quad & #2 && #3 \toggletrue{previousThird} } }{ \ifthenelse{\equal{#3}{}}{ \defaultOCPConstraint\spanit\\&\quad  & #2 \togglefalse{previousThird} }{ \defaultOCPConstraint\spanit\\&\quad  & #2 && #3 \toggletrue{previousThird} } } \togglefalse{bodyCon} } } % Adding constraints below subject to \DeclareDocumentCommand{\BelowAddConstraint}{m G{} G{}}{ \iftoggle{bodyCon}{ \bodyconstBelow{#1}{#2}{#3} \togglefalse{bodyCon} }{ \ifthenelse{\equal{#2}{}}{ \ifthenelse{\equal{#3}{}}{ \defaultOCPConstraint\spanit\\&& #2 \togglefalse{previousThird} }{ \defaultOCPConstraint\spanit\\&& #2 && #3 \toggletrue{previousThird} } }{ \ifthenelse{\equal{#3}{}}{ \defaultOCPConstraint\spanit\\ &  \togglefalse{previousThird} }{ \defaultOCPConstraint\spanit\\ &  && #3 \toggletrue{previousThird} } } \togglefalse{bodyCon} } } % Adding constraints with a single alignment point but next to subject to \DeclareDocumentCommand{\oneAlignAddConstraint}{m G{} G{}}{ \iftoggle{bodyCon}{ \bodyconstOneAlign{#1}{#2}{#3} \togglefalse{bodyCon} }{ \ifthenelse{\equal{#3}{}}{ \defaultOCPConstraint\spanit\\&\quad & #2 \togglefalse{previousThird} }{ \defaultOCPConstraint\spanit\\&\quad & #2 && #3 \toggletrue{previousThird} } \togglefalse{bodyCon} } } % Adding constraints for a single alignment point and with the constraints below \DeclareDocumentCommand{\oneAlignBelowAddConstraint}{m G{} G{}}{ \iftoggle{bodyCon}{ \bodyconstOneAlignBelow{#1}{#2}{#3} \togglefalse{bodyCon} }{ \ifthenelse{\equal{#3}{}}{ \defaultOCPConstraint\spanit\\& & #2\togglefalse{previousThird} }{ \defaultOCPConstraint\spanit\\& & #2 && #3 \toggletrue{previousThird} } \togglefalse{bodyCon} } } % Adding constraints below "subject to" for multiple references \DeclareDocumentCommand{\BelowAddConstraintMult}{m G{} G{}}{ \iftoggle{bodyCon}{ \bodyconstBelowMult{#1}{#2}{#3} \togglefalse{bodyCon} }{ \ifthenelse{\equal{#3}{}}{ \ifthenelse{\equal{#2}{}}{ \defaultOCPConstraint\spanit\\&& #2 }{ \defaultOCPConstraint\spanit\\ &  } \togglefalse{previousThird} }{ \ifthenelse{\equal{#2}{}}{ \defaultOCPConstraint\spanit\\&& #2 && #3 }{ \defaultOCPConstraint\spanit\\ & && #3} \toggletrue{previousThird} } \togglefalse{bodyCon} } } % Adding constraints for a single alignment point and with the constraints below for multiple references \DeclareDocumentCommand{\oneAlignBelowAddConstraintMult}{m G{} G{}}{ \iftoggle{bodyCon}{ \bodyconstOneAlignBelowMult{#1}{#2} \togglefalse{bodyCon} }{ \ifthenelse{\equal{#3}{}}{ \defaultOCPConstraint\spanit\\& & #2 \togglefalse{previousThird} }{ \defaultOCPConstraint\spanit\\& & #2 && #3 \toggletrue{previousThird} } \togglefalse{bodyCon} } } %%%%%%%%%%%%%%%%%%%% % SELECTING TYPE OF FORMAT %%%%%%%%%%%%%%%%%%%% \newcommand{\selectConstraint}[1]{ \ifthenelse{\equal{#1}{1}}{ \let\addConstraint\BelowAddConstraint }{ \ifthenelse{\equal{#1}{2}}{ \let\addConstraint\oneAlignAddConstraint }{ \ifthenelse{\equal{#1}{3}}{ \let\addConstraint\oneAlignBelowAddConstraint }{ \let\addConstraint\standardAddConstraint} } } } % Selecting for multiple references \newcommand{\selectConstraintMult}[1]{ \ifthenelse{\equal{#1}{1}}{ \let\addConstraint\BelowAddConstraintMult }{ \ifthenelse{\equal{#1}{2}}{ \let\addConstraint\oneAlignAddConstraint }{ \ifthenelse{\equal{#1}{3}}{ \let\addConstraint\oneAlignBelowAddConstraintMult }{ \let\addConstraint\standardAddConstraint} } } } %%%%%%%%%%%%%%%%%%% % SETTING DEFAULT FORMAT %%%%%%%%%%%%%%%%%%% % Originally, \toggletrue{bodyCon} was inside this function, however, spacing issues after environment made me remove it. \newcommand{\setStandardMini}{ \let\addConstraint\standardAddConstraint } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % COMMANDS TO DEFINE ALL REQUIRED PROPERTIES TO CHOOSE SHORT/LONG FORMAT %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\setFormatShort}[1]{\global\def\localProblemFormat{s} \let\bodyobj\bodyobjShort \renewcommand{\localProblemType}{#1}} \newcommand{\setFormatLong}[1]{\global\def\localProblemFormat{l} \let\bodyobj\bodyobjLong \renewcommand{\localProblemType}{#1}} \newcommand{\breakObjectiveOneConstraint}[1]{&&\\} %%%%%%%%%%%%%%%%%%%%% %MINIMIZATION ENVIRONMENTS %%%%%%%%%%%%%%%%%%%% % BASE ENVIRONMENTS % Base environment for the three possible types of referencing: 1 label, no label or multilabel % Base environment defined using NewEnviron package because of \BODY command \NewEnviron{BaseMini}[6]{% \selectConstraint{#1} \renewcommand{\localOptimalVariable}{#2} \begin{equation} #4 \begin{alignedat}{5} \bodyobj{#2}{#3}{#6}{#5} \BODY \end{alignedat} \end{equation} \setStandardMini } \NewEnviron{BaseMiniStar}[5]{% \selectConstraint{#1} \renewcommand{\localOptimalVariable}{#2} \begin{alignat*}{5} \bodyobj{#2}{#3}{#5}{#4} \BODY \end{alignat*} \setStandardMini } \NewEnviron{BaseMiniExclam}[6]{% \selectConstraintMult{#1} \renewcommand{\localOptimalVariable}{#2} \begin{subequations} #4 \begin{alignat}{5} \bodyobj{#2}{#3}{#6}{#5} \BODY \end{alignat} \end{subequations} \setStandardMini } % INDIVIDUAL AND SPECIFIC ENVIRONMENTS (mini, maxi, argmini*...) % Specific environments defined with xparse package due to arguments options %MINIMIZATION ENVIRONMENTS % In the below definitions, \toggletrue{bodyCon} has to be added once the definition of the environment is finished. I tried to do inside the environment itself using \setStandardMini, but it produced some ugly text displacemente. % Single reference probems \DeclareDocumentEnvironment{mini}{D||{\defaultProblemFormat} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{min} \BaseMini{#2}{#3}{#4}{#5}{#6}{min}} % Long version problem {\setFormatLong{minimize} \BaseMini{#2}{#3}{#4}{#5}{#6}{minimize}} }{\endBaseMini\toggletrue{bodyCon}} \DeclareDocumentEnvironment{argmini}{D||{\defaultProblemFormat} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{arg~min} \BaseMini{#2}{#3}{#4}{#5}{#6}{arg~min}} % Long version problem {\setFormatLong{arg~min} \BaseMini{#2}{#3}{#4}{#5}{#6}{arg~min}} }{\endBaseMini\toggletrue{bodyCon}} % No reference \DeclareDocumentEnvironment{mini*}{D||{\defaultProblemFormat} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{min} \BaseMiniStar{#2}{#3}{#4}{#6}{min}} % Long version problem {\setFormatLong{minimize} \BaseMiniStar{#2}{#3}{#4}{#6}{minimize}} }{\endBaseMiniStar\toggletrue{bodyCon}} \DeclareDocumentEnvironment{argmini*}{D||{l} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{arg~min}\BaseMiniStar{#2}{#3}{#4}{#6}{arg~min}} % Long version problem {\setFormatLong{arg~min} \BaseMiniStar{#2}{#3}{#4}{#6}{arg~min}} }{\endBaseMiniStar\toggletrue{bodyCon}} % Multiple reference \DeclareDocumentEnvironment{mini!}{D||{\defaultProblemFormat} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{min} \BaseMiniExclam{#2}{#3}{#4}{#5}{#6}{min}} % Long version problem {\setFormatLong{minimize} \BaseMiniExclam{#2}{#3}{#4}{#5}{#6}{minimize}} }{\endBaseMiniExclam\toggletrue{bodyCon}} \DeclareDocumentEnvironment{argmini!}{D||{\defaultProblemFormat} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{arg~min}\BaseMiniExclam{#2}{#3}{#4}{#5}{#6}{arg~min}} % Long version problem {\setFormatLong{arg~min} \BaseMiniExclam{#2}{#3}{#4}{#5}{#6}{arg~min}} }{\endBaseMiniExclam\toggletrue{bodyCon}} %MAXIMIZATION ENVIRONMENTS % Single reference probems \DeclareDocumentEnvironment{maxi}{D||{\defaultProblemFormat} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{max} \BaseMini{#2}{#3}{#4}{#5}{#6}{max}} % Long version problem {\setFormatLong{maximize} \BaseMini{#2}{#3}{#4}{#5}{#6}{maximize}} }{\endBaseMini\toggletrue{bodyCon}} \DeclareDocumentEnvironment{argmaxi}{D||{\defaultProblemFormat} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{arg~max} \BaseMini{#2}{#3}{#4}{#5}{#6}{arg~max}} % Long version problem {\setFormatLong{arg~max} \BaseMini{#2}{#3}{#4}{#5}{#6}{arg~max}} }{\endBaseMini\toggletrue{bodyCon}} % No reference \DeclareDocumentEnvironment{maxi*}{D||{\defaultProblemFormat} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{max} \BaseMiniStar{#2}{#3}{#4}{#6}{max}} % Long version problem {\setFormatLong{maximize} \BaseMiniStar{#2}{#3}{#4}{#6}{maximize}} }{\endBaseMiniStar\toggletrue{bodyCon}} \DeclareDocumentEnvironment{argmaxi*}{D||{l} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{arg~max}\BaseMiniStar{#2}{#3}{#4}{#6}{arg~max}} % Long version problem {\setFormatLong{arg~max} \BaseMiniStar{#2}{#3}{#4}{#6}{arg~max}} }{\endBaseMiniStar\toggletrue{bodyCon}} % Multiple reference \DeclareDocumentEnvironment{maxi!}{D||{\defaultProblemFormat} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{max} \BaseMiniExclam{#2}{#3}{#4}{#5}{#6}{max}} % Long version problem {\setFormatLong{maximize} \BaseMiniExclam{#2}{#3}{#4}{#5}{#6}{maximize}} }{\endBaseMiniExclam\toggletrue{bodyCon}} \DeclareDocumentEnvironment{argmaxi!}{D||{\defaultProblemFormat} O{0} m m m m} {\ifthenelse{\equal{#1}{s}} % Short version problem {\setFormatShort{arg~max}\BaseMiniExclam{#2}{#3}{#4}{#5}{#6}{arg~max}} % Long version problem {\setFormatLong{arg~max} \BaseMiniExclam{#2}{#3}{#4}{#5}{#6}{arg~max}} }{\endBaseMiniExclam\toggletrue{bodyCon}} \end{lstlisting} \end{document}