我正在尝试计算凸函数的数值次梯度。我的测试对象是沃尔夫函数。它不需要非常精确,所以我尝试了两个方向的正常有限微分:(f(xh)-f(x+h))/2h。在代码中:
delta = 1e-10;
subgradient = zeros(length(xToEvaluate),1);
for i = 1 : length(xToEvaluate)
deltaX = xToEvaluate;
deltaX(i) = xToEvaluate(i) + delta;
f1 = funct( deltaX );
deltaX(i) = xToEvaluate(i) - delta;
f2 = funct( deltaX );
subgradient(i,1) = (f1 - f2) / (2 * delta);
end
在函数的确切最小值处,在 (-1 ,0) 处,我得到了一些幅度为 的东西1e-7
,非常好。当我移动到 (-1, 0.1) 或 (-1, 1e-6) 之类的东西时,我得到一个次梯度,第二个分量约为16
。
我知道低增量可能会引入舍入误差,但随着我增加增量,它并没有变得更好。
我的第二次尝试是一个一维五点模板,但即使有 deltas of around1e-3
奇怪的16
不断弹出......
delta = 1e-3;
subgradient = zeros(length(xToEvaluate),1);
for i = 1 : length(xToEvaluate)
xPlusTwo = xToEvaluate;
xPlusOne = xToEvaluate;
xMinusTwo = xToEvaluate;
xMinusOne = xToEvaluate;
xPlusTwo(i) = xToEvaluate(i) + 2*delta;
xPlusOne(i) = xToEvaluate(i) + delta;
xMinusTwo(i) = xToEvaluate(i) - 2*delta;
xMinusOne(i) = xToEvaluate(i) - delta;
subgradient(i,1) = (-funct(xPlusTwo) + 8*funct(xPlusOne) - 8*funct(xMinusOne) + funct(xMinusTwo)) / (12*delta);
end
有人知道这是怎么回事吗?