Python Numdifftools Hessian来自自己的有限差分实现的不同结果?

时间:2019-06-07 17:22:52

标签: python difference hessian

我正在计算标量字段的Hessian,并尝试使用numdifftools。这似乎可行,但是速度很慢,所以我使用有限的差异编写了自己的方法。

这是我的黑森州代码:

def hessianComp ( func, x0, epsilon=1.e-5):
    f1 = scipy.optimize.approx_fprime( x0, func, epsilon=epsilon) 

    # Allocate space for the hessian
    n = x0.shape[0]
    hessian = np.zeros ( ( n, n ) )
    # The next loop fill in the matrix
    xx = x0
    for j in range( n ):
        xx0 = xx[j] # Store old value
        xx[j] = xx0 + epsilon # Perturb with finite difference
        # Recalculate the partial derivatives for this new point
        f2 = scipy.optimize.approx_fprime( xx, func, epsilon=epsilon) 
        hessian[:, j] = (f2 - f1)/epsilon # scale...
        xx[j] = xx0 # Restore initial value of x0        
    return hessian

我使用以下代码在测试函数上都尝试了

def testfunction(x):
    return(x[0]**2 + x[1]**2)

out1 = hessianComp(testfunction, np.array([2.,2.]))
out2 = numdifftools.Hessian(testfunction)([2., 2.])

返回

out1 = array([[2.00000017, 0.        ],
             [0.        , 2.00000017]])

out2 = array([[2.00000000e+00, 1.04776726e-14],
             [1.04776726e-14, 2.00000000e+00]])

因此对于我的测试功能,它似乎给出了正确的结果。但是,如果我尝试在计算Hessian的实际函数上执行此操作,则不会获得相同的结果。我要为其计算Hessian的函数是一个标量字段:

def lambda2Field(x):
    out = solve_ivp(doubleGyreVar, t_span=(0, T), y0=[x[0], x[1], 1, 0, 0, 1],t_eval=[0, T], rtol = 1e-10, atol=1e-10)
    output = out.y
    J = output[2:,-1].reshape(2,2,order="F")
    CG = np.matmul(J.T , J)
    lambdas, xis = np.linalg.eig(CG)
    lambda_2 = np.max(np.abs(lambdas))
    return lambda_2

out1 = hessianComp(lambda2Field, np.array([2.,2.]))
out2 = numdifftools.Hessian(lambda2Field)([2., 2.])

并给出以下内容:

out1 = array([[-1.53769104e+18, -2.20719407e+21],
             [-2.20719407e+21,  1.39720111e+27]])

out2 = array([[-1.53767292e+18,  2.27457455e-07],
             [ 2.27457455e-07, -9.43198781e+16]])

有趣的是,只有我的黑森州矩阵的第一个元素(1,1)是相同的。其他元素相差很大。有人可以帮我了解这可能来自哪里吗?

谢谢!

0 个答案:

没有答案