凸関数の数値劣勾配を計算しようとしています。私のテスト対象はウルフ関数です。超正確である必要はないので、(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) のようなものに移動すると、約 の第 2 成分を持つ劣勾配が得られます16
。
デルタが小さいと丸め誤差が発生する可能性があることは承知していますが、デルタを増やしても改善されません。
私の 2 回目の試行は 1 次元の5 ポイントのステンシル1e-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
誰でもこれが何であるか分かりますか?