调用IPOPT约束的非线性解算器。
基本的函数调用
[x, info] = IPOPT(x0,funcs,options)
第一个输入是一个矩阵或矩阵的单元数组。它声明求解器的起点。
回调函数
第二个输入必须是包含各种MATLAB例程函数句柄的结构。有关MATLAB中使用函数和函数句柄的更多信息,请在MATLAB提示符中输入HELP function和HELP FUNCTION_HANDLE。
function f = objective (x) (必须)
计算当前点的目标函数。例如,Hock & Schittkowski (H&S)测试问题#71(包含4个优化变量)的目标函数的定义将是
1 2
function f = objective (x) f = x(1)*x(4)*sum(x(1:3)) + x(3);
funcs.gradient (required) (必须)
计算目标在当前点的梯度。它接受一个输入,当前迭代x。对于H&S测试问题#71,梯度回调函数的定义是
1 2 3 4 5
function g = gradient (x) g = [ x(1)*x(4) + x(4)*sum(x(1:3)) x(1)*x(4) x(1)*x(4) + 1 x(1)*sum(x(1:3)) ];
funcs.constraints (可选)
只有当变量有约束时才需要此函数。它在当前点计算约束函数。它接受一个输入x。返回值是一个长度等于约束数量的向量(它必须与options.cl和options.cu的长度相同)。对于H&S测试问题#71,回调函数定义为
1 2
function c = constraints (x) c = [ prod(x); sum(x.^2) ];
funcs.jacobian(可选)
只有当变量有约束时才需要此函数。求出约束在当前点处的雅可比矩阵。它有一个输入x,输出必须总是一个M × N的稀疏矩阵,其中M是约束的数量,N是变量的数量。在MATLAB中构造稀疏矩阵的更多信息,请输入HELP SPARSE。H&S测试问题#71的回调函数的定义是
1 2
function J = jacobian (x) sparse([ prod(x)./x; 2*x ]);
请注意,返回值是一个稀疏矩阵
funcs.jacobianstructure(可选)
只有当变量有约束时才需要此函数。它不需要任何输入。返回值是一个稀疏矩阵,其中一个条目是非零的当且仅当约束的雅可比矩阵在任意点是非零。H&S测试问题#71的回调函数简单地以稀疏矩阵格式返回一个2 x 4的全1矩阵:
1 2
function J = jacobianstructure() J = sparse(ones(2,4));
funcs.hessian(可选)
计算拉格朗日量在当前点的Hessian矩阵。它必须指定,除非您选择使用有限内存的准牛顿近似的Hessian函数(见下文)。回调函数有三个输入:当前点(x),目标上的尺度因子(sigma),以及拉格朗日乘数(lambda),长度等于约束数量的向量。函数应该计算
1
sigma*H + lambda(1)*G1 + ... + lambda(M)*GM
其中M为约束数,H为目标的Hessian矩阵,G为约束函数的Hessian矩阵。输出必须总是一个N x N的稀疏下三角矩阵,其中N是变量的数量。也就是说,如果X是输出值,那么X必须与TRIL(X)相同。下面是H&S测试问题#71的Hessian回调例程的实现:
1 2 3 4 5 6 7 8 9 10
function H = hessian (x, sigma, lambda) H = sigma*[ 2*x(4) 0 0 0; x(4) 0 0 0; x(4) 0 0 0; 2*x(1)+x(2)+x(3) x(1) x(1) 0 ]; H = H + lambda(1)*[ 0 0 0 0; x(3)*x(4) 0 0 0; x(2)*x(4) x(1)*x(4) 0 0; x(2)*x(3) x(1)*x(3) x(1)*x(2) 0 ]; H = sparse(H + lambda(2)*diag([2 2 2 2]));
funcs.hessianstructure(可选)
此函数的作用与funcs.jacobianstructure相同,但对于Hessian矩阵。同样,如果您使用有限内存的准牛顿近似Hessian函数,则不需要此函数。它不需要任何输入,并且必须返回一个稀疏的下三角矩阵。对于H&S测试问题#71,MATLAB回调程序是相当直接的:
1 2
function H = hessianstructure() H = sparse(tril(ones(4)));
funcs.iterfunc(可选)
每个算法迭代调用一次的附加回调函数。它有三个输入:第一个是算法的当前迭代,第二个是目标函数的当前值,第三个是包含字段x、inf_pr、inf_du、mu、d_norm、regularization_size、alpha_du、alpha_pr和ls_trials的结构体。这个函数应该总是返回true,除非您希望IPOPT因为任何原因而提前终止。如果您想将第三个输入与auxdata功能一起用于iterfunc,您将需要修改ipopt_auxdata.m的适当部分。
选项
选项通过第三个输入传递。下面是您可以选择指定的字段的描述。
options.lb
指定变量的下界。它必须和x0有相同的元素数。将一个条目设置为-Inf,表示不指定下界。
options.ub
指定变量的上界。它必须和x0有相同的元素数。将一个条目设置为Inf,表示不指定上限。
options.cl, options.cu
设置约束的下界和上界。每个向量的长度应该等于约束的数量。与前面一样,通过将条目设置为-Inf或+Inf来删除绑定。等式约束通过设置cl(i) = cu(i)来实现。
options.auxdata
可以选择通过函数调用向上面列出的MATLAB回调例程传递额外的辅助数据。例如,objective回调函数现在接受两个输入,x和auxdata。在IPOPT优化过程中,辅助数据可能不会发生变化。辅助数据保持与它们在初始调用中拥有的相同值。如果需要随时间变化的变量,可能需要考虑全局变量(HELP global类型).查看example子目录中的lasso.m,演示了如何将辅助数据传递给各种回调函数。从Ipopt 3.11版本开始,必须调用ipopt_auxdata(x0,funcs,options)来使用auxdata功能。
options.zl, options.zu, options.lambda
这些字段指定拉格朗日乘数的初始值,这对于“热启动”内部点解算器特别有用。它们分别指定对应于变量下界、变量上界和约束的拉格朗日乘数。
options.ipopt
最后,您还可以通过这个字段更改IPOPT的设置。例如,要关闭IPOPT输出,使用内存有限的BFGS近似于Hessian,并打开导数检查器,执行以下操作:
1 2 3
options.ipopt.print_level = 0; options.ipopt.hessian_approximation = 'limited-memory'; options.ipopt.derivative_test = 'first-order';
要了解更多详细信息,请参见IPOPT网站上的文档。
输出
如果解算器成功地收敛到一个固定点或终止时没有出现不可恢复的错误,函数IPOPT输出候选解x。在所有其他情况下,都会抛出一个错误。它还输出一些额外的信息:
info.zl, info.zu, info.lambda
解处拉格朗日乘数的值。有关拉格朗日乘数的更多信息,请参阅“选项”。
info.status
终止时,该字段将采用以下值之一(有关更最新的列表,请参阅IPOPT c++源目录中的ipreturncode .h头文件):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
0解决 1已解决到可接受级别 2检测到不可行的问题 3搜索方向太小 4发散迭代 5用户请求停止 -1超过最大迭代次数 -2恢复阶段失败 -3步骤计算中错误 -10自由度不足 -11无效的问题定义 -12无效的选项 -13检测到无效数字 -100不可恢复的异常 -101抛出非ipopt异常 -102内存不足 -199内部错误
info.iter, info.cpu
Ipopt运行所花费的迭代次数和CPU时间(以秒为单位)