非线性最小二乘中的代码生成:背景
什么是代码生成?
代码生成指使用 MATLAB® Coder™ 将 MATLAB 代码转换为 C 代码。代码生成需要 MATLAB Coder 许可证。
通常,您使用代码生成在未运行 MATLAB 的硬件上部署代码。例如,您可以在机器人上部署代码,使用 lsqnonlin 来优化移动或规划。
有关示例,请参阅为 lsqcurvefit 或 lsqnonlin 生成代码。有关其他优化求解器中的代码生成,请参阅为 fmincon 生成代码、为 quadprog 生成代码、为 lsqlin 生成代码或为 fsolve 生成代码。
代码生成的要求
lsqcurvefit和lsqnonlin支持使用codegen(MATLAB Coder) 函数或 MATLAB Coder 生成代码。您必须拥有 MATLAB Coder 许可证才能生成代码。目标硬件必须支持标准双精度浮点计算。您不能为单精度或定点计算生成代码。
代码生成目标与 MATLAB 求解器不使用相同的数学核心函数库。因此,代码生成解可能不同于求解器解,尤其是对于病态问题。
生成的所有代码必须为 MATLAB 代码。特别是,您不能将自定义黑盒函数用作
lsqcurvefit或lsqnonlin的目标函数。您可以使用coder.ceval计算用 C 或 C++ 编码的自定义函数。但是,自定义函数必须在 MATLAB 函数中调用。lsqcurvefit和lsqnonlin的代码生成当前不支持线性或非线性约束。在生成代码时,
lsqcurvefit和lsqnonlin不支持problem参量。[x,fval] = lsqnonlin(problem) % Not supported您必须使用函数句柄(而不是字符串或字符名称)来指定目标函数。
x = lsqnonlin(@fun,x0,lb,ub,options) % Supported % Not supported: lsqnonlin('fun',...) or lsqnonlin("fun",...)
所有输入矩阵
lb和ub都必须是满矩阵,而不能是稀疏矩阵。您可以使用full函数将稀疏矩阵转换为满矩阵。lb和ub参量的条目数必须与x0参量相同,或必须为空[]。如果您的目标硬件不支持无限边界,请使用
optim.coder.infbound。对于涉及嵌入式处理器的高级代码优化,您还需要 Embedded Coder® 许可证。
您必须包括适用于
lsqcurvefit或lsqnonlin的选项,并使用optimoptions指定这些选项。选项中必须包括Algorithm并将其设置为'levenberg-marquardt'。options = optimoptions('lsqnonlin','Algorithm','levenberg-marquardt'); [x,fval,exitflag] = lsqnonlin(fun,x0,lb,ub,options);
代码生成支持以下选项:
Algorithm- 必须为'levenberg-marquardt'FiniteDifferenceStepSizeFiniteDifferenceTypeFunctionToleranceMaxFunctionEvaluationsMaxIterationsSpecifyObjectiveGradientStepToleranceTypicalX
生成的代码只会对选项进行有限的错误检查。更新选项的推荐方法是使用
optimoptions,而不是圆点表示法。opts = optimoptions('lsqnonlin','Algorithm','levenberg-marquardt'); opts = optimoptions(opts,'MaxIterations',1e4); % Recommended opts.MaxIterations = 1e4; % Not recommended
不要从文件中加载选项。否则会导致代码生成失败。请在代码中创建选项。
通常,如果您指定了不受支持的选项,在代码生成过程中会以静默方式忽略该选项。但是,如果使用圆点表示法指定绘图函数或输出函数,代码生成可能引发错误。为确保可靠性,请仅指定支持的选项。
由于不支持输出函数和绘图函数,求解器不会返回退出标志 –1。
生成的代码不是多线程的
默认情况下,在 MATLAB 环境之外使用的生成代码使用非多线程的线性代数库。因此,此类代码的运行速度可能比 MATLAB 环境中的代码慢得多。
如果您的目标硬件有多个核,您可以通过使用自定义的多线程 LAPACK 和 BLAS 库来获得更好的性能。有关将这些库纳入生成的代码中的详细信息,请参阅Speed Up Linear Algebra in Generated Standalone Code by Using LAPACK Calls (MATLAB Coder)。
另请参阅
lsqnonlin | lsqcurvefit | codegen (MATLAB Coder) | optimoptions | optim.coder.infbound