在Python中使用数值积分的Laplace变换的精度非常差

问题描述

我已经编写了一个函数来使用scipy.integrate.quad计算函数的Laplace变换。它不是一个非常复杂的函数,目前在Erlang分布的概率密度函数上表现不佳。

我将我的所有工作都包括在下面。我首先计算拉普拉斯变换,然后计算逆向,以便将其与原始p.d.f进行比较。的Erlang。为此,我使用mpmathmpmath.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]

情节

enter image description here

代码

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]

一个人得到了这个可爱的情节:

enter image description here

结论 那么,为什么要经历所有的麻烦才能对我们拥有封闭形式解决方案的东西进行数字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 (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...