输出函数和绘图函数语法
什么是输出函数和绘图函数?
有关输出函数和绘图函数的示例,请参阅 Optimization Toolbox 的输出函数 和 绘图函数。
OutputFcn
选项指定优化函数在每次迭代时调用的一个或多个函数。通常,您可能使用输出函数来绘制每次迭代的点或显示算法的优化量。使用输出函数您可以查看优化数量,但不能设置。您还可以根据设置的条件停止求解器的执行;请参阅 输出函数或绘图函数的结构。
类似地,PlotFcn
选项指定优化函数在每次迭代时调用的一个或多个函数,并且可以停止求解器。绘图函数和输出函数之间的区别有两个方面:
大多数求解器都具有预定义的绘图函数,使您能够轻松获得典型绘图。
绘图函数将输出发送到具有Pause和Stop按钮的窗口,使您能够提早停止求解器而不会丢失信息。
小心
intlinprog
输出函数和绘图函数与其他求解器的不同。请参阅intlinprog 输出函数和绘图函数语法。
要设置输出函数或绘图函数,请执行以下操作:
将函数写为函数文件或局部函数。
使用
optimoptions
将OutputFcn
或PlotFcn
的值设置为函数句柄,即前面带有@符号的函数名称。例如,如果输出函数是outfun.m
,则命令options = optimoptions(@solvername,'OutputFcn',@outfun);
指定
OutputFcn
作为outfun
的句柄。要指定多个输出函数或绘图函数,请使用语法options = optimoptions('solvername','OutputFcn',{@outfun, @outfun2});
要使用制表符补全来帮助选择内置绘图函数名称,请使用引号而不是函数句柄。
使用
options
作为输入参量调用优化函数。
传递额外参数 解释如何将参数或数据传递给输出函数或绘图函数(如果需要)。
输出函数或绘图函数的结构
输出函数或绘图函数的函数定义行具有以下形式:
stop = outfun(x,optimValues,state)
其中
x
是算法在当前迭代中计算的点。optimValues
是包含当前迭代中的数据的结构体。optimValues 中的字段详细介绍了此结构体。state
是算法的当前状态。算法的状态列出了可能的值。stop
是一个标志,它是true
还是false
,取决于优化程序是否应该停止(true
)或继续(false
)。有关详细信息,请参阅Stop 标签。
优化函数在每次迭代中将输入参量的值传递给 outfun
。
optimValues 中的字段
下表列出了 optimValues
结构的各个字段。特定的优化函数仅返回其中一些字段的值。对于每个字段,表的“函数返回”列列出了返回该字段的函数。
相应的输出参数
optimValues
的某些字段对应于优化函数的输出参量。在优化算法的最后一次迭代之后,该字段的值等于相应的输出参量。例如,optimValues.fval
对应于输出参量 fval
。因此,如果您使用输出函数调用 fmincon
并返回 fval
,则 optimValues.fval
的最终值等于 fval
。下表的描述列指示具有对应输出参量的字段。
命令行显示
当您调用优化函数并将 options
的 Display
字段设置为 'iter'
时,optimValues
的某些字段的值会显示在命令行中,如 迭代输出 中所述。例如 optimValues.fval
显示在 f(x)
列中。下表的命令行显示列指示您可以在命令行中显示的字段。
一些 optimValues
字段仅适用于特定算法:
AS -
active-set
D -
trust-region-dogleg
IP -
interior-point
LM -
levenberg-marquardt
Q -
quasi-newton
SQP -
sqp
TR -
trust-region
TRR -
trust-region-reflective
某些求解器或算法中存在某些 optimValues
字段,但总是填充空值或零值,因此毫无意义。这些字段包括:
constrviolation
- 用于fminunc
TR
和fsolve
TRR
。procedure
- 用于fmincon
TRR
和SQP
,以及fminunc
。
optimValues 字段
OptimValues 字段 (optimValues.field) | 描述 | 由以下函数返回 | 命令行显示 |
---|---|---|---|
| 多目标问题的成就因素。有关详细信息,请参阅目标达成方法。 | 无 | |
| 当前优化迭代中的共轭梯度迭代次数。 |
|
请参阅迭代输出。 |
| 最大约束违反值。 |
|
请参阅迭代输出。 |
| 退化程度的测度。如果某个点满足以下条件,则该点退化:
请参阅退化。 |
| 无 |
| 搜索方向上的方向导数。 |
|
请参阅迭代输出。 |
| 一阶最优性(取决于算法)。最终值等于优化函数输出 |
|
请参阅迭代输出。 |
| 函数计算的累计次数。最终值等于优化函数输出 |
|
请参阅迭代输出。 |
| 当前点的函数值。最终值等于优化函数输出 对于 |
|
请参阅迭代输出。 |
| 目标函数的当前梯度 - 如果您提供的话,可以是解析梯度,也可以是有限差分近似。最终值等于优化函数输出 |
| 无 |
| 迭代次数 - 从 |
|
请参阅迭代输出。 |
| 当前迭代中的 Levenberg-Marquardt 参数 | |
|
| 实际步长除以最初预测的步长 |
请参阅迭代输出。 | |
| 最大函数值 | fminimax | 无 |
| 如果算法在计算牛顿步时检测到负曲率,则为 否则为 |
| 无 |
| 程序消息。 |
|
请参阅迭代输出。 |
| 目标函数的变化与二次近似的变化之比。 |
| 无 |
| 残差向量。 |
请参阅迭代输出。 | |
| 残差平方的 2-范数。 |
请参阅迭代输出。 | |
| 搜索方向。 |
| 无 |
| 当前信赖区步骤的状态。如果当前信赖区步骤成功则返回 true,如果信赖区步骤不成功则返回 false。 | | 无 |
| 当前步长( |
|
请参阅迭代输出。 |
| 信赖区域半径。 |
|
请参阅迭代输出。 |
退化
字段 degenerate
的值用于衡量当前优化点 x
的退化程度,其定义如下。首先,定义一个向量 r
,其大小与 x
相同,其中 r(i)
是从 x(i)
到下界和上界的第 i 个条目 lb
和 ub
的最小距离。即,
r = min(abs(ub-x, x-lb))
那么 degenerate
的值就是向量 r + abs(grad)
的最小项,其中 grad
是目标函数的梯度。如果存在索引 i
,且以下两个条件均为真,则 degenerate
的值为 0:
grad(i) = 0
x(i)
等于下限或上界的第 i 个条目。
算法的状态
下表列出了 state
的可能值:
状态 | 描述 |
---|---|
| 算法在第一次迭代前处于初始状态。 |
| 该算法处于迭代中一些计算量很大的部分。在这种状态下,输出函数可以中断优化的当前迭代。此时 |
| 算法位于迭代末尾。 |
| 算法在最后一次迭代后处于最终状态。 |
'interrupt'
状态仅出现在 fmincon
'active-set'
算法以及 fgoalattain
、fminimax
和 fseminf
求解器中。在那里,该状态可能出现在二次规划子问题解或线搜索之前。
以下代码说明了输出函数如何使用 state
的值来决定在当前迭代中执行哪些任务:
switch state case 'iter' % Make updates to plot or guis as needed case 'interrupt' % Probably no action here. Check conditions to see % whether optimization should quit. case 'init' % Setup for plots or guis case 'done' % Cleanup of plots, guis, or final plot otherwise end
Stop 标签
输出参量 stop
是 true
或 false
的标签。该标志告诉优化函数优化是否应该停止(true
)或继续(false
)。下面的示例演示了使用 stop
标签的典型方法。
根据 optimValues 中的数据停止优化
输出函数或绘图函数可以根据 optimValues
中的当前数据在任何迭代中停止优化。例如,以下代码将 stop
设置为 true
,当方向导数的大小小于 .01
时,停止优化:
function stop = outfun(x,optimValues,state) stop = false; % Check whether directional derivative norm is less than .01. if norm(optimValues.directionalderivative) < .01 stop = true; end
根据 GUI 输入停止优化
如果您设计一个 GUI 来执行优化,则可以在用户单击 GUI 上的 Stop 按钮时让输出函数停止优化。以下代码显示了如何执行此操作,假设 Stop 按钮回调将值 true
存储在名为 hObject
的 handles
结构的 optimstop
字段中:
function stop = outfun(x,optimValues,state) stop = false; % Check if user has requested to stop the optimization. stop = getappdata(hObject,'optimstop');