在 xparse 命令中使用数组环境

在 xparse 命令中使用数组环境

我想定义一个用于优化问题的宏。下面给出了我的尝试。我想知道为什么\optimizationproblema可以工作,但\optimizationproblemb不能(当我尝试使用后者时,我收到“错位对齐标签”错误)。显然我的约束不被视为属于数组\optimizationproblemb?如果有更好的方法来解决定义宏的问题,那也很好。我想保持用法大致相同(即,

\optimizationproblem{minimize}{x}{f(x)}{g(x) <= 0}

应该表示最小化 f(x) 在 x 上的服从 g(x) <= 0;我还需要某种方法来抑制无约束问题的“服从”部分[我\IfValueTF在实际代码中使用了一个测试]),但我并不真正关心实现。

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

    \NewDocumentCommand{\optimizationproblema}{mmmm}
    {
        \begin{array}{c@{\ }c@{\ }l}
            \displaystyle\operatorname*{#1}_{#2} & :
                & #3 \\
            \mathrm{subject \ to} & : &
                \begin{array}[t]{@{}r@{\ }c@{\ }l@{\qquad}l}
                    #4
                \end{array}
        \end{array}
    }

    \NewDocumentCommand{\optimizationproblemb}{momo}
    {
        \begin{array}{c@{\ }c@{\ }l}
            \displaystyle\operatorname*{#1}_{#2} & :
                & #3 \\
            \mathrm{subject \ to} & : &
                \begin{array}[t]{@{}r@{\ }c@{\ }l@{\qquad}l}
                    #4
                \end{array}
        \end{array}
    }

    \NewDocumentCommand{\constraint}{mmm}
    {
        #1 & #2 & #3 \\
    }

\begin{document}

\[
    \optimizationproblema
    {
        minimize
    }
    {
        x \in \mathbf{R}^{n}
    }
    {
        c^{T} x
    }
    {
        \constraint{A x}{=}{b}
        \constraint{x}{\geq}{0}
    }
\]

%\[
%   \optimizationproblemb
%   {
%       minimize
%   }
%   [
%       x \in \mathbf{R}^{n}
%   ]
%   {
%       c^{T} x
%   }
%   [
%       \constraint{A x}{=}{b}
%       \constraint{x}{\geq}{0}
%   ]
%\]

\end{document}

非常感谢@egreg 的帮助。我还有两个功能想要实现,我想知道我是否可以从社区获得更多帮助。特别是,我想支持框约束和枚举约束。在 egreg 使用 LaTeX3 给出解决方案之前,我的约束命令是一个带有签名 mmmggo 的宏。前三个参数表示标准约束;第四和第五个参数表示框约束中的附加信息;第六个参数表示枚举约束的枚举。我尝试让这些功能正常工作,如下所示(失败的部分已被注释掉)。关于我做出某些选择的动机,有几点说明:我想让约束在使用中可读,这就是为什么我更喜欢使用下面给出的约束命令格式化约束的原因;如果没有枚举任何约束,我想阻止打印用于设置枚举的 \qquad,以保持问题的水平居中。我认为框约束问题基本已解决(我总是可以在第三个参数中包含框约束的附加信息,如下所示)。但是,我非常希望能够 (1) 将枚举作为可选参数,(2) 在不使用枚举约束时抑制用于设置枚举的 \qquad(以保持优化问题的水平居中)。

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

    \ExplSyntaxOn
        % allocate the variables for an optimization problem
        \tl_new:N \l_optprob_operator_tl
        \tl_new:N \l_optprob_variable_tl
        \tl_new:N \l_optprob_objective_tl
        \tl_new:N \l_optprob_constraints_tl

        % define the keys
        \keys_define:nn{optprob}
        {
            operator   .tl_set:N = \l_optprob_operator_tl,
            variable   .tl_set:N = \l_optprob_variable_tl,
            objective  .tl_set:N = \l_optprob_objective_tl,
            constraint .code:n   = \optprob_add_constraint:nnnnnn #1,
            % constraint .code:n   = \constraint{#1}
        }

        \NewDocumentCommand{\optimizationproblem}{m}
        {
            % clear the variables
            \tl_clear:N \l_optprob_operator_tl
            \tl_clear:N \l_optprob_variable_tl
            \tl_clear:N \l_optprob_objective_tl
            \tl_clear:N \l_optprob_constraints_tl

            % get the keys
            \keys_set:nn{optprob}{#1}

            % print the optimization problem
            \tl_if_empty:NTF \l_optprob_objective_tl
            {
                % feasibility problem
                \begin{array}[t]{@{}r@{}>{{}}c<{{}}@{}l@{}l}
                    \l_optprob_constraints_tl
                \end{array}
            }
            {
                % optimization problem
                \begin{array}{c@{{}\mathrel{:}{}}l}
                    \displaystyle\operatorname*{\l_optprob_operator_tl}\sb{\l_optprob_variable_tl} &
                        \l_optprob_objective_tl \\[2ex]
                    \tl_if_empty:NF \l_optprob_constraints_tl
                    {
                        % constrained optimization problem
                        \textnormal{subject~to} &
                            \begin{array}[t]{@{}r@{}>{{}}c<{{}}@{}l@{}l}
                                \l_optprob_constraints_tl
                            \end{array}
                    }
                \end{array}
            }
        }

        \NewDocumentCommand{\constraint}{mmmggo}
        {
            \IfValueTF{#4}
            {
                \IfValueTF{#6}
                {
                    #1 & #2 & #3 #4 #5 & \qquad #6 \\
                }
                {
                    #1 & #2 & #3 #4 #5 \\
                }
            }
            {
                \IfValue{#6}
                {
                    #1 & #2 & #3 & \qquad #6 \\
                }
                {
                    #1 & #2 & #3 \\
                }
            }
        }

        % helper function to process the constraints
        \cs_new_protected:Npn \optprob_add_constraint:nnnnnn #1 #2 #3 #4
        {
            \tl_put_right:Nn \l_optprob_constraints_tl {#1 & #2 & #3 & \qquad #4 \\}
        }
    \ExplSyntaxOff

\begin{document}

\[
    \optimizationproblem
    {
        operator   = minimize,
        variable   = x \in \mathbf{R}^{n},
        objective  = c^{T} x,
        constraint = {A_{i} x}{=}{b_{i}}{i = 1 , \ldots , m},
        % constraint = {A_{i} x}{=}{b_{i}}[i = 1 , \ldots , m],
        constraint = {F_{j} x}{\leq}{g_{j}}{j = 1 , \ldots , m},
        % constraint = {F_{j} x}{\geq}{g_{j}}[j = 1 , \ldots , m],
        constraint = {0}{\leq}{x \leq 1}{},
        % constraint = {0}{\leq}{x}{\leq}{1},
    }
\]

\end{document}

答案1

可选参数的实现xparse不希望在最后一个参数之前有空格,以避免在调用后跟要打印的括号时出现问题。

所以如果你打电话

\[
\optimizationproblemb
  {minimize}
  [x \in \mathbf{R}^{n}]
  {c^{T} x}% <-------------- Don't forget this!!!
  [\constraint{A x}{=}{b}
   \constraint{x}{\geq}{0}]
\]

你不会遇到任何问题。但是我不明白为什么约束应该是可选的。

在这种情况下,我建议使用键值语法:

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

\ExplSyntaxOn
% Allocate some variables
\tl_new:N \l_stirling_operator_tl
\tl_new:N \l_stirling_domain_tl
\tl_new:N \l_stirling_function_tl
\tl_new:N \l_stirling_constraints_tl
\tl_new:N \l_stirling_sidecondition_tl

% Define the keys
\keys_define:nn { stirlingopt }
 {
  operator   .tl_set:N = \l_stirling_operator_tl,
  domain     .tl_set:N = \l_stirling_domain_tl,
  function   .tl_set:N = \l_stirling_function_tl,
  constraint .code:n   = \stirling_add_constraint:nnn #1,
 }

\NewDocumentCommand{\optimizationproblem}{m}
 {
  % Clear the variables
  \tl_clear:N \l_stirling_operator_tl
  \tl_clear:N \l_stirling_domain_tl
  \tl_clear:N \l_stirling_function_tl
  \tl_clear:N \l_stirling_constraints_tl
  % Set the keys from the argument
  \keys_set:nn { stirlingopt } { #1 }
  % Print
  \begin{array}{c@{{}\mathrel{:}{}}l}
   \displaystyle
     \operatorname*{\l_stirling_operator_tl}\sb{\l_stirling_domain_tl} &
     \l_stirling_function_tl
  \tl_if_empty:NF \l_stirling_constraints_tl
   { % this will be executed only if constraints are specified
    \\[2ex]
    \textnormal{subject~to} &
      \begin{array}[t]{@{}r@{}>{{}}c<{{}}@{}l@{}}
        \l_stirling_constraints_tl
      \end{array}
   }
  \end{array}
 }
% A helper macro for the constraints
\cs_new_protected:Npn \stirling_add_constraint:nnn #1 #2 #3
 {
  \tl_put_right:Nn \l_stirling_constraints_tl { #1 & #2 & #3 \\ }
 }
\ExplSyntaxOff

\begin{document}
\[
\optimizationproblem{
 operator=minimize,
 domain=x\in\mathbf{R}^{n},
 function=c^{T}x,
 constraint={Ax}{=}{b},
 constraint={x}{\geq}{0},
}
\]
\end{document}

在此处输入图片描述

请注意,键的顺序无关紧要;当然约束将按照它们表达的顺序添加。

一个人可以没有任何限制,例如

\[
\optimizationproblem{
 operator=minimize,
 domain=x\in\mathbf{R}^{n},  
 function=c^{T}x,
}
\]

结果是

在此处输入图片描述

我对数组的排版方式做了一些更改,以获得更好的间距。

相关内容