将 MATLAB quadgk 积分转换为 Scipy 具有长函数的 quad 积分(传递 lambda 函数的任何替代方法?)
Converting a MATLAB quadgk integration to Scipy quad with a long function to integrate (any alternative to passing a lambda function?)
好的,我有这个 MATLAB 代码,它将 quadgk
在其积分期间生成的 x 值传递给 integrand
函数:
optionvalue(i) = exp(-r .* T2) .* quadgk(@(x) integrand(x,flag, F, K, vol, T2, T1), 0, Inf, 'AbsTol',tolerance);
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));
所以现在我转到 SciPy 试图复制上面的内容,但我在传递 x
的值时卡住了。 SciPy 显示函数 quad
必须采用 lambda 函数 - 我怎么能把这么长的 integrand
函数转换成那种格式(或其他一些使其工作的方式)?几乎就像我必须将其重写为 f(x)
类型并删除传递给函数本身的 x
变量。到目前为止,这是 Python 的内容:
from scipy import integrate
from scipy.stats import norm, lognorm
# Define function and interval
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)
return lognorm.pdf(x, mu, sigma) * (flag * x*norm.cdf(flag * d1) - flag * (x+K)*norm.cdf(flag * d2))
quad, quad_err = integrate.quad(integrand, 0, np.Inf, args=(x, flag, F, K, vol, T2, T1))
感谢帮助!
SciPy shows that the function quad has to take a lambda function - how the heck can I put that long integrand function into that format (or some other way to make it work)?
我希望我们不要称它们为 lambda 函数——这让使用 lambda
语法的结果看起来有些特别,但实际上并没有。
quad
接受一个 函数 —— 使用哪种语法构造它并不重要。
>>> def f(x): return x**2
>>> quad(f, 0, 1)[0]
0.3333333333333333
>>> quad(lambda x: x**2, 0, 1)[0]
0.3333333333333333
>>> g = lambda x: x**2 # no point to naming this, but anyway
>>> quad(g, 0, 1)[0]
0.3333333333333333
或者,也许更像你的情况,
>>> def h(x, a): return (x+a)**2
>>> quad(h, 0, 1, args=5)[0]
30.33333333333333
>>> quad(lambda x: (x+5)**2, 0, 1)[0]
30.33333333333333
比我想象的更容易 运行 这个函数,只要在调用 quad
时省略 Python 中的 x
变量,它会在其例程中自动传递它.即
args=(flag, F, K, vol, T2, T1))
它假定 x
输入变量在:
def integrand(x, flag, F, K, vol, T2, T1):
不通过 args=()
传递参数的语句
好的,我有这个 MATLAB 代码,它将 quadgk
在其积分期间生成的 x 值传递给 integrand
函数:
optionvalue(i) = exp(-r .* T2) .* quadgk(@(x) integrand(x,flag, F, K, vol, T2, T1), 0, Inf, 'AbsTol',tolerance);
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));
所以现在我转到 SciPy 试图复制上面的内容,但我在传递 x
的值时卡住了。 SciPy 显示函数 quad
必须采用 lambda 函数 - 我怎么能把这么长的 integrand
函数转换成那种格式(或其他一些使其工作的方式)?几乎就像我必须将其重写为 f(x)
类型并删除传递给函数本身的 x
变量。到目前为止,这是 Python 的内容:
from scipy import integrate
from scipy.stats import norm, lognorm
# Define function and interval
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)
return lognorm.pdf(x, mu, sigma) * (flag * x*norm.cdf(flag * d1) - flag * (x+K)*norm.cdf(flag * d2))
quad, quad_err = integrate.quad(integrand, 0, np.Inf, args=(x, flag, F, K, vol, T2, T1))
感谢帮助!
SciPy shows that the function quad has to take a lambda function - how the heck can I put that long integrand function into that format (or some other way to make it work)?
我希望我们不要称它们为 lambda 函数——这让使用 lambda
语法的结果看起来有些特别,但实际上并没有。
quad
接受一个 函数 —— 使用哪种语法构造它并不重要。
>>> def f(x): return x**2
>>> quad(f, 0, 1)[0]
0.3333333333333333
>>> quad(lambda x: x**2, 0, 1)[0]
0.3333333333333333
>>> g = lambda x: x**2 # no point to naming this, but anyway
>>> quad(g, 0, 1)[0]
0.3333333333333333
或者,也许更像你的情况,
>>> def h(x, a): return (x+a)**2
>>> quad(h, 0, 1, args=5)[0]
30.33333333333333
>>> quad(lambda x: (x+5)**2, 0, 1)[0]
30.33333333333333
比我想象的更容易 运行 这个函数,只要在调用 quad
时省略 Python 中的 x
变量,它会在其例程中自动传递它.即
args=(flag, F, K, vol, T2, T1))
它假定 x
输入变量在:
def integrand(x, flag, F, K, vol, T2, T1):
不通过 args=()