Python与MATLAB计算无穷大积分的不同结果,替代方法(即将gausslegendere求积扩展到x>无穷大)?

2024-04-19 10:39:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我得到了MATLAB的quadgk和Python的quad例程对于一个从(-x或0)->无穷大的积分的结果不一致。我相信MATLAB版本是正确的(基于将flag参数从1切换到-1的意义检查),而Python版本给出了错误的结果,在本例中是0。MATLAB生成0.1022。integrands是相同的,我已经将每一步都安排好了,甚至将由MATLAB的quadgk生成的x值插入Python(这导致Python版本生成与MATLAB相同的值,只需将它们传递给integrand函数)。在这一点上,我希望使用另一个例程,而不是SciPy,例如这里的Gauss-Legendre求积https://sourceforge.net/projects/fastgausslegendrequadrature/,但我不确定如何将它从a/b范围扩展到-a->;无穷大(我见过这些方法,它们只适用于有限的数:

https://upload.wikimedia.org/math/a/7/f/Different intervals for Gauss-Legendre quadrature in numpy而{}则产生{}。也不确定如何从返回的节点和权重设置集成,尽管我一直在阅读转换,但只针对a和b有限的范围:https://pomax.github.io/bezierinfo/legendre-gauss.html要么是这样,要么是有人知道一个Python库可以处理这个问题,我真的不喜欢quad没有矢量化,很可能会像我一样用Cython编写代码必须快速集成600000个功能(即链接到上面的C++库链接)。这里真正奇怪的是,我通过向上移动volinput anywhere>;=0.39得到了完全相同的结果,低于这个值Python的结果在0处崩溃。非常混乱。任何帮助都是感激的,它已经多年没有微积分。。。下面是Python代码:

from scipy.stats import norm, lognorm
from scipy.integrate import quad
import numpy as np

def integrand(x, flag, F, K, vol, T2, T1):
    d1 = (np.log(x / (x+K)) + 0.5 * (vol**2) * (T2-T1)) / (vol * np.sqrt(T2 - T1))
    d2 = d1 - vol*np.sqrt(T2 - T1)
    mu = np.log(F) - 0.5 *vol **2 * T1
    sigma = vol * np.sqrt(T1)
    value = lognorm.pdf(x, scale=np.exp(mu), s=sigma) * (flag * x*norm.cdf(flag * d1) - flag * (x+K)*norm.cdf(flag * d2))
    return value

if __name__ == '__main__':
        flag = 1
        F = 54.31
        K = 1.1967
        vol = 0.1328
        T2 = 0.0411
        T1 = 0.0137
        quad(integrand, 0, np.Inf, args=(flag, F, K, vol, T2, T1), epsabs=1e-12)[0]

下面是MATLAB代码(必须将integrand另存为a.M,然后才能在命令窗口中输入脚本):

^{pr2}$

%脚本部分

flag = 1
F = 54.31
K = 1.1967
vol = 0.1328
T2 = 0.0411
T1 = 0.0137
quadgk(@(x) integrand(x,flag, F, K, vol, T2, T1), 0, Inf, 'AbsTol',1e-12)

我应该注意到,当这些输入被传递时,MATLAB和Python使用quad生成相同的结果(上面的变量被转置):

 current_opt = [  -1.0000    1.2075    0.1251    0.4300    0.0685    0.0411     
                1.0000    1.2075    0.0512    0.5600    0.0685    0.0411]  

Tags: 代码import版本normnpsqrtflagd1
1条回答
网友
1楼 · 发布于 2024-04-19 10:39:42

好吧,这很有趣。除非epsabs变量设置得荒谬地高,否则积分就会崩溃。我已经成功地使用epsabs=-1e1000在MATLAB和Python之间复制结果。虽然可能很慢,但至少能起作用。在

相关问题 更多 >