You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为经典Hodgkin-Huxley膜电位ODE添加高斯白噪声?

给Hodgkin-Huxley模型添加高斯白噪声的实现思路

首先直接回答你的问题:直接将高斯白噪声项加入膜电位的微分方程dx[0]中是一种可行的近似实现方式,不过需要注意白噪声在连续时间系统里的特性,以及数值求解时的细节。

为什么这个近似可行?

高斯白噪声在连续时间下对应维纳过程(布朗运动)的导数,而标准的odeint是用来求解确定性常微分方程(ODE)的。当你的时间步长足够小(像你代码里用了10000个点覆盖200ms,步长0.02ms,已经比较小),直接把离散的高斯噪声样本加到dx[0]里,能近似模拟膜电位受到的随机扰动。

修改后的代码示例

你只需要生成和时间数组T长度一致的噪声,然后在derivatives函数里把噪声项加到dx[0]中即可。注意要根据需求调整噪声的标准差(std),避免噪声过大掩盖HH模型本身的电活动:

import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint

# runtime in milliseconds
t_0 = 0.0
t_1 = 200.0
print("The interval of runtime is:")
print(t_0, t_1)

# Potassium (alpha_n, beta_n) and Sodium (alpha_m, beta_m, alpha_h, beta_h) ion-channel rate functions
def alpha_n(V):
    return (0.01*(10.0-V))/(np.exp((10.0-V)/10.0)-1.0)
def alpha_m(V):
    return (0.1*(25.0-V))/(np.exp((25.0-V)/10.0)-1)
def beta_n(V):
    return 0.125*np.exp(-V/80.0)
def beta_m(V):
    return 4.0*np.exp(-V/18.0)
def alpha_h(V):
    return 0.07*np.exp(-V/20.0)
def beta_h(V):
    return (1.0)/((np.exp((30.0-V)/10.0))+1)

# mostly used parameters
V_NA = 50.0    # Sodium potential (mV)
V_K = -77.0    # Potassium Potential
V_L = -54.4    # Leak Potential
g_k = 36.0     # Potassium channel conductance
g_NA = 120.0   # Sodium channel conductance
g_L = 0.3      # Leak channel conductance
C = 1.0        # Membrane capacitance

# equally distributed time values
T = np.linspace(t_0,t_1,10000)
# 生成高斯白噪声:均值0,标准差可调整,这里用0.5作为示例
noise = np.random.normal(loc=0.0, scale=0.5, size=len(T))

# stimulus function
def stim(t):
    if 0.0 < t < 1.0:
        return 150.0
    elif 35.0 < t < 36.0 :
        return 5000.0
    return 0.0

# steady-state values
def n_infty(V = 0.0):
    return alpha_n(V)/(alpha_n(V)+beta_n(V))
def m_infty(V = 0.0):
    return alpha_m(V)/(alpha_m(V)+beta_m(V))
def h_infty(V = 0.0):
    return alpha_h(V)/(alpha_h(V)+beta_h(V))
def tau_m(V = 0.0):
    return 1.0/(alpha_m(V)+beta_m(V))
def tau_n(V = 0.0):
    return 1.0/(alpha_n(V)+beta_n(V))
def tau_h(V = 0.0):
    return 1.0/(alpha_h(V)+beta_h(V))

# 修改derivatives函数,加入噪声项
def derivatives(x, z, noise):
    # 找到当前时间z对应的噪声索引
    idx = np.argmin(np.abs(T - z))
    dx = np.zeros((4,))
    V = x[0]
    m = x[1]
    n = x[2]
    h = x[3]
    # 把噪声项加到膜电位的微分方程中
    dx[0] = (stim(z)-g_NA*np.power(m,3.0)*h*(V-V_NA)-g_k*np.power(n,4.0)*(V-V_K)-g_L*(V-V_L) + noise[idx])/C
    dx[1] = (m_infty(V)-m)/tau_m(V)
    dx[2] = (n_infty(V)-n)/tau_n(V)
    dx[3] = (h_infty(V)-h)/tau_h(V)
    return dx

# 初始条件
X = np.array([0.0,m_infty(),n_infty(),h_infty()])
# 调用odeint时传递noise参数
V_x = odeint(derivatives, X, T, args=(noise,))

# 绘图:只画膜电位(第一列)
plt.plot(T, V_x[:,0])
plt.xlabel('Time in ms')
plt.ylabel('Membrane Potential in mV')
plt.title('Hodgkin-Huxley Model with Gaussian White Noise')
plt.show()

更严谨的处理方式:随机微分方程(SDE)

如果你需要更准确地模拟随机扰动,应该把HH模型作为随机微分方程(SDE)来求解,因为白噪声本质上是连续时间的随机过程,odeint不是专门的SDE求解器。你可以使用sdeint库(需要先安装:pip install sdeint),它专门用于求解随机微分方程。

示例代码框架大概是这样:

import sdeint

# 定义确定性部分(原HH方程的导数)
def f(x, t):
    V, m, n, h = x
    dV = (stim(t)-g_NA*m**3*h*(V-V_NA)-g_k*n**4*(V-V_K)-g_L*(V-V_L))/C
    dm = (m_infty(V)-m)/tau_m(V)
    dn = (n_infty(V)-n)/tau_n(V)
    dh = (h_infty(V)-h)/tau_h(V)
    return np.array([dV, dm, dn, dh])

# 定义噪声部分:这里假设只有膜电位受到噪声,噪声强度为sigma
sigma = 0.5
def G(x, t):
    return np.array([sigma, 0, 0, 0])  # 只有V的方程有噪声项

# 求解SDE
V_x_sde = sdeint.itoint(f, G, X, T)

注意事项

  • 噪声的标准差(scale参数)要合理设置:如果太大,会导致膜电位的随机波动掩盖原本的动作电位;太小的话,扰动效果不明显。
  • 用odeint加离散噪声时,时间步长越小,近似效果越好,因为离散噪声样本更接近连续白噪声的特性。
  • 如果你需要重复实验,记得设置随机种子(np.random.seed(42)),这样每次生成的噪声是一致的,方便对比结果。

内容的提问来源于stack exchange,提问作者user10674336

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:24:44