我得到了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-> infinity(我見過這些方法只去一個有限的數量:Python與MATLAB計算積分到無限與不同的結果,替代(即擴大Gauss-Legendre積分到-x->無窮大)?
Different intervals for Gauss-Legendre quadrature in numpy而b=np.Inf
結果NaN
還不能確定如何設置從返回的節點和權重的整合,雖然我一直在讀的轉型,但只有A和b有限範圍:https://pomax.github.io/bezierinfo/legendre-gauss.html要麼或者如果有人知道可以處理這個問題的Python庫 - 我不太喜歡quad
雖然不是矢量化的,並且很可能會在Cython中編寫代碼,因爲我必須快速集成600,000個函數(即鏈接到th上面的C++庫鏈接)。這裏真奇怪的是,我設法得到了相同的結果,將vol
輸入向上移動大於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
爲.M則可以在輸入腳本命令窗口):
function value = integrand(x, flag, F,K,vol,T2,T1)
d1 = (log(x ./ (x+K)) + 0.5 .* (vol.^2) .* (T2-T1)) ./ (vol .* sqrt(T2 - T1));
d2 = d1 - vol.*sqrt(T2 - T1);
mu = log(F) - 0.5 .*vol .^2 .* T1;
sigma = vol .* sqrt(T1);
value = lognpdf(x, mu, sigma) .* (flag .* x.*normcdf(flag .* d1) - flag .* (x+K).*normcdf(flag .* d2));
end
%腳本部分
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使用四產生相同的結果時,這些輸入被傳遞,而不是(移位的ABO ve變量):
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]