0

凸関数の数値劣勾配を計算しようとしています。私のテスト対象はウルフ関数です。超正確である必要はないので、(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

誰でもこれが何であるか分かりますか?

4

1 に答える 1

0

その Wolfe 関数の勾配を計算すると、次のようになります。

if x<=0;
    dfx = 9 - 81*x.^8;
    dfy = 16*sign(y);
elseif x>=abs(y);
    dfx = 5*0.5./sqrt(9*x.^2 + 16*y.^2)*9*2.*x;
    dfy  = 5*0.5./sqrt(9*x.^2 + 16*y.^2)*16*2.*y;
else
    dfx = 9;
    dfy  = 16*sign(y);
end

ご覧のとおり、 の勾配の 2 番目の成分は であるためx<=0、の16*sign(y)場合はゼロでありy==0+-16そうでない場合はゼロです。

ところで、正確な最小値が にあるようには見えません[-1 0]が、[-0.7598 0]
= [-(1/9)^(1/8) 0]

于 2013-07-23T21:44:25.750 に答える