【问题标题】:Speeding up odeint calculation加速 odeint 计算
【发布时间】:2017-08-23 19:43:16
【问题描述】:

我正在使用 scipy 的 odeint 运行一个相当大的 ODE 系统。为了保持系统的连贯性、易读性和简短性,我将其中的大部分内容划分为类以相互调用。从可读性的角度来看,它似乎工作正常,但是由于对 python 对象的重复调用,它显着减慢了实际的 ODE 求解器。我四处寻找优化代码的方法,以保持一定程度的可读性,同时提高计算效率(使用 Numba 或在将其转换为可识别 numpy 的 lambda 函数之前使用 Sympy),但是到目前为止我还不是很成功.我想知道在这种情况下哪些策略会有所帮助。我提供了下面代码的简单版本。先感谢您。

class NaL():
    g = 0
    def I(self, v, E): return self.g * (v - E) #Leak current

class Neuron():
    C_m = 1.0 #membrane capacitance
    V = 0  # Voltage
    m, h = 0, 0  #activating variables
    def I_Na(self): #Sodium Currents
        return self.NaT.I(self.V, self.m, self.h)+ self.NaL.I(self.V)  
    def __init__(self):
        self.NaT = NaT()
        self.NaL = NaL()
        self.NaT.g = 3000
        self.NaL.g = 20

I1 = Neuron()

def Run(X,t):
    I1.V, I1.m, I1.h = X 
    dydt = [(0 - I1.I_Na()) / I1.C_m, #dV/dt for neuron
            I1.NaT.dmdt(I1.V, I1.m), #dm/dt for sodium channel
            I1.NaT.dhdt(I1.V, I1.h) #dh/dt for sodium channel
           ]
    return dydt
X = odeint(Run, [-70, 0.0050, 0.9961], t)

【问题讨论】:

标签: python scipy ode odeint


【解决方案1】:

集成的瓶颈几乎可以肯定是评估派生词Run,因为在集成的每个步骤中都必须多次调用它。现在,由于所有的类成员和函数调用,你有相当大的 Python 开销。

对此的一个解决方案是真正使用您的模块JiTCODE,而不是定义积分器要使用的函数,而是象征性地定义微分方程(使用 SymPy)。然后将它们翻译成 C 代码,编译成 Python 函数,然后用于集成。这样,您的类和类函数仅在实际集成之前被调用几次,并且如果您在没有类和类似的情况下定义了您的派生类,那么集成的效率将是一样的。 (此外,您可能会通过编译获得相当大的速度提升,特别是如果您有很多神经元。)

就目前而言,您将示例转换为 JiTCODE 很简单:

from jitcode import jitcode, provide_basic_symbols

t, y = provide_basic_symbols()

class NaL():
    […]

class Neuron():
    […]

I1 = Neuron()

I1.V, I1.m, I1.h = y(0), y(1), y(2)

Run = [
    (0 - I1.I_Na()) / I1.C_m,
    I1.NaT.dmdt(I1.V, I1.m),
    I1.NaT.dhdt(I1.V, I1.h)
]

t = range(100)

ODE = jitcode(Run)
ODE.set_initial_value([-70,0.0050,0.9961], t[0])
X = np.vstack(ODE.integrate for time in t[1:])

此代码现在无法运行,原因与您的示例代码无法运行相同。请注意,您的类中涉及动态变量的所有算术都变成了符号。通过加法和乘法,这是开箱即用的,但如果你有 math.sinsympy.sin 之类的东西,你必须用 sympy.sin 替换它。

【讨论】:

    猜你喜欢
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多