2015-05-02 90 views
2

scipy.optimize.minimize函數基本上實現了等價於MATLAB的'fminunc'函數,用於查找函數的局部最小值。scipy.optimize.minimize:一起計算hessian和梯度

在scipy中,漸變和Hessian的函數是分開的。

res = minimize(rosen, x0, method='Newton-CG', 
...    jac=rosen_der, hess=rosen_hess, 
...    options={'xtol': 1e-30, 'disp': True}) 

不過,我有它的Hessian和梯度份額相當多的計算的功能,我想計算Hessian和梯度在一起,以提高效率。在fminunc,目標函數可以寫返回多個值,即:

function [ q, grad, Hessian ] = rosen(x) 

是否有一個函數傳遞到scipy.optimize.minimize,可以計算出這些元素結合在一起的好辦法?

回答

2

你可以去找一個緩存解決方案,但是第一個numpy數組是不可散列的,其次你只需要緩存一些值,這取決於算法是否在x上往返。如果算法只從一個點移動到下一個,你可以緩存只有這樣,最後計算出的點,你f_hesf_jac是剛剛拉姆達接口較長函數計算兩個:

import numpy as np 

# I choose the example f(x,y) = x**2 + y**2, with x,y the 1st and 2nd element of x below: 
def f(x): 
    return x[0]**2+x[1]**2 

def f_jac_hess(x): 
    if all(x==f_jac_hess.lastx): 
     print('fetch cached value') 
     return f_jac_hess.lastf 
    print('new elaboration') 
    res = array([2*x[0],2*x[1]]),array([[2,0],[0,2]]) 

    f_jac_hess.lastx = x 
    f_jac_hess.lastf = res 

    return res 

f_jac_hess.lastx = np.empty((2,)) * np.nan 

f_jac = lambda x : f_jac_hess(x)[0] 
f_hes = lambda x : f_jac_hess(x)[1] 

現在第二通話將緩存保存的值:

>>> f_jac([3,2]) 
new elaboration 
Out: [6, 4] 
>>> f_hes([3,2]) 
fetch cached value 
Out: [[2, 0], [0, 2]] 

然後調用它:

minimize(f,array([1,2]),method='Newton-CG',jac = f_jac, hess= f_hes, options={'xtol': 1e-30, 'disp': True}) 
+1

謝謝,我懷疑SOLN將涉及某種GL的obal變量。似乎重寫_minimize_trust_ncg()函數以接收函數生成器中的所有三個函數(如fminunc)會很有用也很簡單。 – ejang