从scipy优化根寻找算法

时间:2018-05-22 14:59:54

标签: python optimization scipy numba

我使用root中的scipy.optimize函数和方法" excitingmixing"在我的代码中,因为其他方法,如标准牛顿,不会收敛到我正在寻找的根。

但是,我想使用numba优化我的代码,scipy不支持scipy包。我试着查看"激动人心的混音"文档中的算法自己编程:

https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.root.html

我没有找到任何有用的东西,除了方法"使用调谐对角线雅可比近似"的非常有用的陈述。

如果有人可以告诉我有关该算法的信息,或者对如何以其他方式优化import numpy as np from scipy import optimize from numba import jit @jit(nopython = True) def func(x): [a, b, c, d] = x da = a*(1-b) db = b*(1-c) dc = c dd = 1 return [da, db, dc, dd] @jit(nopython = True) def getRoot(x0): solution = optimize.root(func, x0, method="excitingmixing") return(solution.x) root = getRoot([0.1,0.1,0.2,0.4]) print(root) 函数有所了解,我会很高兴。

这里要求的是一个最小的代码示例:

{{1}}

2 个答案:

答案 0 :(得分:1)

您可以查看scipy的源代码以查看excitingmixing选项的实现:

https://github.com/scipy/scipy/blob/c948e96ebb3454f6a82e9d14021cc601d7ce7a85/scipy/optimize/nonlin.py#L1272

您可能不想在numba中重新实现整个根查找算法。我可以测试的更好的策略是使用numba来优化传递给scipy方法的函数。你仍然需要花费一些scipy调用函数的开销,但如果瓶颈在评估函数,你可能会看到性能提升,并且可以使用numba jitted版本更快地完成。我发现最好只用numba进行试验并使用timeit方法进行测试。

答案 1 :(得分:0)

我写了一个小包装 Minpack,叫做 NumbaMinpack,可以在 numba 编译函数中调用:https://github.com/Nicholaswogan/NumbaMinpack

如果牛顿的方法失败了,您应该尝试 lmdif 方法。

from NumbaMinpack import lmdif, hybrd, minpack_sig
from numba import njit, cfunc
import numpy as np

@cfunc(minpack_sig)
def myfunc(x, fvec, args):
    fvec[0] = x[0]**2 - args[0]
    fvec[1] = x[1]**2 - args[1]
    
funcptr = myfunc.address # pointer to myfunc

x_init = np.array([10.0,10.0]) # initial conditions
neqs = 2 # number of equations
args = np.array([30.0,8.0]) # data you want to pass to myfunc
@njit
def test():
    # solve with lmdif
    sol = lmdif(funcptr, x_init, neqs, args)
    # OR solve with hybrd
    sol = hybrd(funcptr, x_init, args) 
    return sol
test() # it works!