我使用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}}
答案 0 :(得分:1)
您可以查看scipy的源代码以查看excitingmixing
选项的实现:
您可能不想在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!