【问题标题】:RMS value of a function函数的 RMS 值
【发布时间】:2020-04-26 17:23:27
【问题描述】:

现在是完整的代码/问题

我想估计函数 v 的随机波动 - 因此我想计算它的 RMS 值:

import numpy as np
import matplotlib.pyplot as plt




def HHmodel(I,length, area):

        v = []
        m = []
        h = []
        z = []
        n = []
        squares = []
        vsquare = (-60)*(-60)
        sumsquares = 0
        rms = []
        a= []
        dt = 0.05
        t = np.linspace(0,100,length)


        #constants
        Cm = area#microFarad
        ENa=50 #miliVolt
        EK=-77  #miliVolt
        El=-54 #miliVolt
        g_Na=120*area #mScm-2
        g_K=36*area #mScm-2
        g_l=0.03*area #mScm-2

        def alphaN(v):
            return 0.01*(v+50)/(1-np.exp(-(v+50)/10))

        def betaN(v):
            return 0.125*np.exp(-(v+60)/80)

        def alphaM(v):
            return 0.1*(v+35)/(1-np.exp(-(v+35)/10))

        def betaM(v):
            return 4.0*np.exp(-0.0556*(v+60))

        def alphaH(v):
            return 0.07*np.exp(-0.05*(v+60))

        def betaH(v):
            return 1/(1+np.exp(-(0.1)*(v+30)))

        #Initialize the voltage and the channels :
        v.append(-60)
        rms.append(1)
        m0 = alphaM(v[0])/(alphaM(v[0])+betaM(v[0]))
        n0 = alphaN(v[0])/(alphaN(v[0])+betaN(v[0]))
        h0 = alphaH(v[0])/(alphaH(v[0])+betaH(v[0]))

        #t.append(0)
        m.append(m0)
        n.append(n0)
        h.append(h0)

        #solving ODE using Euler's method:
        for i in range(1,len(t)):
            m.append(m[i-1] + dt*((alphaM(v[i-1])*(1-m[i-1]))-betaM(v[i-1])*m[i-1]))
            n.append(n[i-1] + dt*((alphaN(v[i-1])*(1-n[i-1]))-betaN(v[i-1])*n[i-1]))
            h.append(h[i-1] + dt*((alphaH(v[i-1])*(1-h[i-1]))-betaH(v[i-1])*h[i-1]))
            gNa = g_Na * h[i-1]*(m[i-1])**3
            gK=g_K*n[i-1]**4
            gl=g_l
            INa = gNa*(v[i-1]-ENa)
            IK = gK*(v[i-1]-EK)
            Il=gl*(v[i-1]-El)
            v.append(v[i-1]+(dt)*((1/Cm)*(I[i-1]-(INa+IK+Il))))
            #v.append(v[i-1]+(dt)*((1/Cm)*(I-(INa+IK+Il))))
        meansquare = np.sqrt((np.square(v).sum()))
        return v,area,meansquare




spikeEvents = []  #timing each spike
length = 1000*5  #the time period

fluctuations = []
output = []



for j in range(1, 10):
    barcode = np.zeros(length)
    noisyI = np.random.normal(0,9,length)
    area = 1.0+0.1*j
    res = HHmodel(noisyI,length,area)
    output.append(res[2])




print('Done.')

目标应该是 v 的波动随着 a 的大小以某种方式增加 - 我在这里认为 rms 幅度是一个合理的度量

BR

编辑:

 for i in range(1,len(t)):
            m.append(m[i-1] + dt*((alphaM(v[i-1])*(1-m[i-1]))-betaM(v[i-1])*m[i-1]))
            n.append(n[i-1] + dt*((alphaN(v[i-1])*(1-n[i-1]))-betaN(v[i-1])*n[i-1]))
            h.append(h[i-1] + dt*((alphaH(v[i-1])*(1-h[i-1]))-betaH(v[i-1])*h[i-1]))
            gNa = g_Na * h[i-1]*(m[i-1])**3
            gK=g_K*n[i-1]**4
            gl=g_l
            INa = gNa*(v[i-1]-ENa)
            IK = gK*(v[i-1]-EK)
            Il=gl*(v[i-1]-El)
            v.append(v[i-1]+(dt)*((1/Cm)*(I[i-1]-(INa+IK+Il))))
            z.append(v[i-1]-np.mean(v))
            #v.append(v[i-1]+(dt)*((1/Cm)*(I-(INa+IK+Il))))
        mean = sum(np.square(v))/len(v)
        squared_diffs =[(item-mean)**2 for item in v]
        ms_diff = sum(squared_diffs)/len(squared_diffs)
        rms_diff =np.sqrt(ms_diff)
        return v,area,rms_diff

编辑2: 绘制范围 (1,10) 中的 j - 蓝色:在编辑 1 中计算的 rmsvalue,黄色 1/sqrt(j)

edit3:

在范围(1,100)内绘制 j - 但波动的“大小”应该增加,而不是减少并在某处居中

【问题讨论】:

  • 你为什么要在所有索引上做奇怪的范围和-1?
  • 我不能说太多,因为我不是 100% 你想要达到的目标。但是在你的循环中,meansquarelen(t) 划分,尽管循环在除最后一次之外的所有迭代中都没有运行到len(t)
  • 如果您的值存储在v 列表中,我建议您在循环外进行平方。因此,在循环中只需将值附加到v,然后在循环终止后,您可以将平方和计算为np.square(v).sum(),这可能会有所帮助。
  • 创建v后,然后:rms = np.sqrt(np.mean(v**2))
  • 但是 v**2 很棘手,因为 v 是一个列表?

标签: python numpy


【解决方案1】:

一些小笔记:

  • 所以,基本上你的“函数”v 是对某个函数的一次性离散评估,而不是真正的函数,但这在这里并不真正相关。

  • 1234563
  • 还不清楚为什么在迭代 i 中您计算 v[i] 但您计算的相应平方值是 v[i-1] 平方。应该在相同的循环迭代中使用相同的索引,否则您可能最终会丢失一个元素。

我会说结果没有用的原因是均方根并没有真正用于函数的输出(在这种情况下,RMS 只是某种不太有用的平均值,它为异常值提供了额外的权重) ;而 RMS 通常用于该函数输出的误差或方差。 RMS 误差或方差告诉您在函数的原始单位中,平均函数值与平均值相差多远?)。请注意,如果您希望 v 的值保持不变,这才是真正重要的指标。

鉴于这一切,很难从你的问题中说出你的意图是什么以及你实际上试图用这些信息做什么,所以我猜你真正关心的是 v 的值与均值。在这种情况下,您可以使用与 v 平均值的 RMS 差值,计算如下:

for i in range(1,len(t)):
        #calculate v[i] here, omitted for simplicity

    # get mean value
    mean = sum(squares)/len(squares)

    # you want to get the squared value of the difference, not the value itself
    squared_diffs = [(item - mean)**2 for item in v)]


    # get mean squared diff
    ms_diff = sum(squared_diffs) / len(squared_diffs)

    # return root of mean squared diff
    rms_diff = np.sqrt(ms_diff)

    return v,area,rms_diff

同样,这仅在您期望v 的输出为常数时才有用。如果不是,您将尝试为函数拟合不同的模型(线性、二次等),然后计算 RMS 误差。如果您指出此计算的目标,问题会更清楚。

【讨论】:

  • 嗨 Derek - 这个模型被称为霍奇金赫胥黎模型(用于神经元模拟) - 我想计算随机离子电流电压波动(理论上它们应该取决于膜本身的表面积- v 是跨膜的电压,可以通过求解我帖子中的微分方程来计算。现在我想求解 ODE 以增加膜的尺寸(在循环中进行)并希望看到随机波动正在增加。
  • 是的,没关系。基本上,v 是时间的函数(因此计算各种 t 的值),但 v 也由 a 参数化。所以 v 随时间波动。现在,如果我错了,请纠正我,但您真正关心的是波动的平均幅度,而不是 v 的平均幅度。
  • 所以,你需要做的第一件事是,在a为常数的情况下,一旦你计算了每个时间步的v,你需要估计那个时间步v的波动大小。现在,到目前为止,我一直假设 v 以某个值(均值)为中心,并由此上下波动,您不关心 v 的符号,只关心波动的大小。或者,v 的最小值可能为 0,而您只关心 v 大于 0 的大小。如果是这种情况,只需取 v 的平均值。
  • 但如果不是这种情况,并且您确实只关心 v 的波动幅度,而不管符号如何,那么您应该将每个时间步的波动大小估计为均值和v 在那个时间步的值。
  • 嗨 Derek - 感谢您的回答!我不太确定“估计每个时间步的波动大小在该时间步的平均值和 v 的值之间”是什么意思,是的,它大约是波动的平均幅度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-21
  • 2017-04-10
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
  • 2014-06-14
  • 1970-01-01
相关资源
最近更新 更多