我得到了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->;无穷大(我见过这些方法,它们只适用于有限的数:
Different intervals for Gauss-Legendre quadrature in numpy而{quad
没有矢量化,很可能会像我一样用Cython编写代码必须快速集成600000个功能(即链接到上面的C++库链接)。这里真正奇怪的是,我通过向上移动vol
input 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,然后才能在命令窗口中输入脚本):
%脚本部分
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]
好吧,这很有趣。除非
epsabs
变量设置得荒谬地高,否则积分就会崩溃。我已经成功地使用epsabs=-1e1000
在MATLAB和Python之间复制结果。虽然可能很慢,但至少能起作用。在相关问题 更多 >
编程相关推荐