优化基础的代码生成
生成代码Fmincon
此示例显示了如何生成代码Fmincon
optimization solver. Code generation requires aMATLAB®CODER™license. For details of code generation requirements, seeFmincon背景中的代码生成。
该示例使用以下简单的目标函数。要在您自己的测试中使用此目标函数,请将代码复制到名称的文件Rosenbrockwithgrad.m
。Save the file on your MATLAB path.
功能[f,g] = rosenbrockwithgrad(x)%计算目标ff = 100*(x(2)-x(1)^2)^2 +(1 -x(1))^2;如果nargout> 1需要梯度%g = [-400*(x(2) - x(1)^2)*x(1) - 2*(1 - x(1)); 200*(x(2) - x(1)^2)];结尾
使用Rosenbrockwithgrad
目标函数,创建一个名称的文件test_rosen.m
包含此代码:
功能[x,fval] = test_rosen opts = optimoptions('fmincon',,,,'算法',,,,'SQP');[x fval] = fmincon(@RosenBrockwithGrad,[ - 1,1],[],[],[],[],[],[ - 3,-3],[3,3],[3,3],[],[],opts)
生成代码test_rosen
file.
代码根-Config:Mextest_rosen
一段时间后,代码根
创建一个名称的MEX文件test_rosen_mex.mexw64
(根据您的系统,文件扩展名将有所不同)。您可以通过输入来运行生成的C代码test_rosen_mex
。The results are the following or similar:
x = 1.0000 1.0000 fval = 1.3346e-11 ans = 1.0000 1.0000
修改效率示例
遵循一些建议实时应用程序的优化代码生成,,,,set the configuration of the generated code to have fewer checks and to use static memory allocation.
cfg = coder.config('Mex');cfg.integritychecks = false;cfg.saturateonintegeroverflow = false;cfg.dynamicmemoryallocation ='离开';
收集问题的界限[-3,3]
至[-2,2]
。另外,设置比默认值宽松的最优性公差1E-6
。
功能[x,fval] = test_rosen2 opts = optimoptions('fmincon',,,,'算法',,,,'SQP',,,,...“最佳耐受性”,1E-5);[x fval eflag output] = fmincon(@RosenBrockWithGrad,[ - 1,1],[],[],[],[],[],[],,,,,...[-2,-2],[2,2],[],opts)
生成代码test_rosen2
file.
代码根-configCFGtest_rosen2
运行结果代码。
test_rosen2_mex
x = 1.0000 1.0000 fval = 2.0057e-11 eflag = 2 output = struct with fields: iterations: 40 funcCount: 155 algorithm: 'sqp' constrviolation: 0 stepsize: 5.9344e-08 lssteplength: 1 ans = 1.0000 1.0000
该解决方案几乎与以前的解决方案一样好,FVAL
输出2e-11
与以前相比1E-11
。
尝试将允许迭代的数量限制为先前计算中采用的迭代次数的一半。
功能[x,fval] = test_rosen3 options = optimoptions('fmincon',,,,'算法',,,,'SQP',,,,...“最大”,20);[x fval eflag output] = fmincon(@RosenBrockWithGrad,[ - 1,1],[],[],[],[],[],[],,,,,...[-2,-2],[2,2],[],选项)
跑test_rosen3
在Matlab。
test_rosen3
x = 0.2852 - 0.0716 fval= 0.5204 eflag = 0 output = struct with fields: iterations: 20 funcCount: 91 algorithm: 'sqp' message: '↵Solver stopped prematurely.↵↵fmincon stopped because it exceeded the iteration limit,↵options.MaxIterations = 2.000000e+01.↵↵' constrviolation: 0 stepsize: 0.0225 lssteplength: 1 firstorderopt: 1.9504 ans = 0.2852 0.0716
由于这种严重的迭代限制,Fmincon
没有达到好的解决方案。准确性和速度之间的权衡很难管理。
为了节省功能评估并可能提高准确性,请通过设置示例的内置衍生物指定目标gradient
option totrue
。
功能[x,fval] = test_rosen44 options = optimoptions('fmincon',,,,'算法',,,,'SQP',,,,...“指定目标gradient”,真的);[x fval eflag output] = fmincon(@RosenBrockWithGrad,[ - 1,1],[],[],[],[],[],[],,,,,...[-2,-2],[2,2],[],选项)
生成代码test_rosen4
使用与test_rosen2
。
代码根-configCFGtest_rosen4
运行结果代码。
test_rosen4_mex
x = 1.0000 1.0000 fval = 3.3610e-20 eflag = 2输出=带字段的结构:迭代:40 funccount:113算法:'sqp'限制:0步骤:0步骤:9.6356e-08 lssteplength:1 ans = 1.0000 1.0000 1.0000 1.0000 1.0000。
相比test_rosen2
,迭代次数在40时相同,但功能评估的数量较低。113
代替155
。结果具有更好的(较低)的目标函数值3 e-20
相比2e-11
。