问题描述
我已经编写了一个函数来使用scipy.integrate.quad
计算函数的Laplace变换。它不是一个非常复杂的函数,目前在Erlang分布的概率密度函数上表现不佳。
我将我的所有工作都包括在下面。我首先计算拉普拉斯变换,然后计算逆向,以便将其与原始p.d.f进行比较。的Erlang。为此,我使用mpmath
。 mpmath.invertlaplace
并不是问题,因为它设法将封闭形式的Laplace变换转换回原始p.d.f。相当完美。
请帮助我理解数值拉普拉斯变换存在的问题。我收到以下错误,但无法解决。
IntegrationWarning: The occurrence of roundoff error is detected,which prevents the requested tolerance from being achieved. The error may be underestimated. a=0,b=np.inf,limit=limit)[0]
情节
代码
import numpy as np
import matplotlib.pyplot as plt
import math as m
import mpmath as mp
import scipy.stats as st
from scipy.integrate import quad
def get_laplace(func,limit=10000):
'''
Returns laplace transfrom function
'''
def laplace(s):
'''Numerical laplace transform'''
# Seperate into real and imaginary parts
x = np.real(s)
y = np.imag(s)
def real_func(t):
return m.exp(-x*t)*m.cos(y*t)*func(t)
def imag_func(t):
return m.exp(-x*t)*m.sin(y*t)*func(t)
real_integral = quad(real_func,a=0,limit=limit)[0]
imag_intergal = quad(real_func,limit=limit)[0]
return complex(real_integral,-imag_intergal)
return laplace
def L_erlang(s,lam,k):
'''
Closed form laplace transform of Erlang or Gamma distribution.
'''
return (lam/(lam+s))**k
if __name__ == '__main__':
# Setup Erlang probability density function
k = 5
lam = 1
pdf = st.erlang(a=k,scale=1/lam).pdf
# Laplace transforms
Lnum = get_laplace(pdf) # numerical approximation
L = lambda s: L_erlang(s,k) # closed form
# Use mpmath library to perform inverse laplace
# Invserse transfrom on numerical laplace function
invLnum = lambda t: mp.invertlaplace(Lnum,t,method='dehoog',dps=5,degree=3)
# Invserse transfrom on closed-form laplace function
invL = lambda t: mp.invertlaplace(L,degree=3)
# Grid to visualise
T = np.linspace(0.1,10,10)
# Get values of inverse transforms
lnum = np.array([invLnum(t) for t in T])
l = np.array([invL(t) for t in T])
# Plot
plt.plot(T,lnum,label='from numerical laplace')
plt.plot(T,l,label='from closed-form laplace')
plt.plot(T,pdf(T),label='original pdf',linestyle='--')
plt.legend(loc='best')
plt.show()
更新
在喝了两杯非常浓的咖啡之后,我设法看到了明显的错误并使代码正常工作。实际上,这很尴尬。看看这行代码:
imag_intergal = quad(real_func,limit=limit)[0]
嗯,real_func
嘿?因此应显示为:
imag_intergal = quad(imag_func_func,limit=limit)[0]
一个人得到了这个可爱的情节:
结论
那么,为什么要经历所有的麻烦才能对我们拥有封闭形式解决方案的东西进行数字Laplace变换。那是因为兴趣在于其他地方。对于条件未来寿命分布,我们没有类似于危险函数的封闭表达式。让我们称之为h
。然后,对于在erl = st.erlang(a=k,scale=1/lam)
个时间单位内处于活动状态的Erlang分布tau
,我们有h = lambda t: erl.pdf(t+tau)/erl.sf(tau)
。该分布可用作半马尔可夫模型(SMP)中的保持时间。要分析SMP的瞬态行为,请使用Laplace变换。通常只使用pdf,但是现在我可以使用危险函数了。它非常酷,因为它意味着人们可以在不假设所有新事物的情况下对瞬态行为进行建模。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)