Main Content

fmincon 背景中的代码生成

什么是代码生成?

代码生成指使用 MATLAB® Coder™ 将 MATLAB 代码转换为 C 代码。代码生成需要 MATLAB Coder 许可证。

通常,您使用代码生成在未运行 MATLAB 的硬件上部署代码。例如,您可以在机器人上部署代码,使用 fmincon 来优化移动或规划。

有关示例,请参阅为 fmincon 生成代码。有关其他优化求解器中的代码生成,请参阅为 fsolve 生成代码为 lsqcurvefit 或 lsqnonlin 生成代码为 quadprog 生成代码

代码生成要求

  • fmincon 支持使用 codegen (MATLAB Coder) 函数或 MATLAB Coder 生成代码。您必须拥有 MATLAB Coder 许可证才能生成代码。

  • 目标硬件必须支持标准双精度浮点计算或标准单精度浮点计算。

  • 代码生成目标与 MATLAB 求解器不使用相同的数学核心函数库。因此,代码生成解可能不同于求解器解,尤其是对于病态问题。

  • 生成的所有代码必须为 MATLAB 代码。特别是,您不能将自定义黑盒函数用作 fmincon 的目标函数。您可以使用 coder.ceval 计算用 C 或 C++ 编码的自定义函数。但是,自定义函数必须在 MATLAB 函数中调用。

  • 在生成代码时,fmincon 不支持 problem 参量。

    [x,fval] = fmincon(problem) % Not supported
  • 您必须使用函数句柄(而不是字符串或字符名称)来指定目标函数和任何非线性约束函数。

    x = fmincon(@fun,x0,A,b,Aeq,beq,lb,ub,@nonlcon) % Supported
    % Not supported: fmincon('fun',...) or fmincon("fun",...)
  • 所有 fmincon 输入矩阵(如 AAeqlbub)都必须是满矩阵,而不能是稀疏矩阵。您可以使用 full 函数将稀疏矩阵转换为满矩阵。

  • lbub 参量的条目数必须与 x0 参量相同,或必须为空 []

  • 如果您的目标硬件不支持无限边界,请使用 optim.coder.infbound

  • 对于涉及嵌入式处理器的高级代码优化,您还需要 Embedded Coder® 许可证。

  • 您必须包括适用于 fmincon 的选项,并使用 optimoptions 指定这些选项。选项中必须包括 Algorithm 并将其设置为 'sqp''sqp-legacy'

    options = optimoptions('fmincon','Algorithm','sqp');
    [x,fval,exitflag] = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options);
  • 代码生成支持以下选项:

    • Algorithm - 必须为 'sqp''sqp-legacy'

    • ConstraintTolerance

    • FiniteDifferenceStepSize

    • FiniteDifferenceType

    • MaxFunctionEvaluations

    • MaxIterations

    • ObjectiveLimit

    • OptimalityTolerance

    • ScaleProblem

    • SpecifyConstraintGradient

    • SpecifyObjectiveGradient

    • StepTolerance

    • TypicalX

  • 生成的代码只会对选项进行有限的错误检查。更新选项的推荐方法是使用 optimoptions,而不是圆点表示法。

    opts = optimoptions('fmincon','Algorithm','sqp');
    opts = optimoptions(opts,'MaxIterations',1e4); % Recommended
    opts.MaxIterations = 1e4; % Not recommended
  • 不要从文件中加载选项。否则会导致代码生成失败。请在代码中创建选项。

  • 通常,如果您指定了不受支持的选项,在代码生成过程中会以静默方式忽略该选项。但是,如果使用圆点表示法指定绘图函数或输出函数,代码生成可能引发错误。为确保可靠性,请仅指定支持的选项。

  • 由于不支持输出函数和绘图函数,fmincon 不会返回退出标志 –1。

  • fmincon 生成的代码中返回的 output 结构体不包含 bestfeasible 字段。

单精度代码生成

要为单精度浮点硬件生成代码,请遵循以下规范。

  • 确保 fmincon 调用中的所有参数都具有单精度值。这包括所有空值和无限值。例如,如果您在三维问题中的边界是 lb = [0,-Inf,0]ub = [1,100,Inf],请按以下方式设置参数。

    lb = [single(0),-optim.coder.infbound("single"),single(0)];
    ub = [single([1,100]),optim.coder.infbound("single")];
  • 请确保传递给 fmincon 的所有空参量均为单精度值。例如,

    Aeq = single([]); % Or single.empty
    beq = single([]); % Or single.empty
  • 确保所有非线性函数(目标函数和约束函数)返回单精度类型值。例如,

    function f = objfun(x)
    % Must be able to accept x as single.
    % Computations must also produce a single or be cast
    expx = x.^2 + exp(x);          % Produces a single
    f = cast(foo(expx),'like',x);  % foo is unknown, so cast to single
    end
    
    function [c,ceq] = nonlcon(x)
    ceq = single.empty;
    c = exp(-exp(-x)) - single(1/2); % Produces a single
    end

生成的代码不是多线程的

默认情况下,在 MATLAB 环境之外使用的生成代码使用非多线程的线性代数库。因此,此类代码的运行速度可能比 MATLAB 环境中的代码慢得多。

如果您的目标硬件有多个核,您可以通过使用自定义的多线程 LAPACK 和 BLAS 库来获得更好的性能。要将这些库合并到您的生成代码中,请参阅Speed Up Linear Algebra in Generated Standalone Code by Using LAPACK Calls (MATLAB Coder)

另请参阅

| (MATLAB Coder) | |

相关主题