Matlab中的数值梯度 - 舍入问题

时间:2013-07-23 17:42:47

标签: matlab gradient rounding numerics

我正在尝试计算凸函数的数字次梯度。我的考试科目是Wolfe function。它不需要超精确,所以我在两个方向上尝试了正常的有限差分:(f(x-h)-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

我知道低增量可能会引入舍入错误,但随着增加增量,它不会变得更好。

我的第二次尝试是一维five-point stencil,但即使是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

任何人都知道这是关于什么的?

1 个答案:

答案 0 :(得分: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

正如您所看到的,x<=0的渐变的第二个分量是16*sign(y),因此在y==0时为零,+-16

顺便说一句,它看起来不像[-1 0]处的确切最小值,而是[-0.7598 0] = [-(1/9)^(1/8) 0]