将MATLAB quadgk集成转换为具有长函数的Scipy quad进行集成(传递lambda函数的任何替代方法?)

时间:2016-05-19 21:12:10

标签: python matlab scipy numerical-integration

好的,我有这个MATLAB代码,它在integrand函数中传递了quadgk在集成过程中生成的x的值:

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))

感谢帮助!

2 个答案:

答案 0 :(得分:2)

  

SciPy表明函数quad必须采用lambda函数 - 如何将长整数函数放入该格式(或其他一些使其工作的方式)?

我希望我们不要将它们称为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

答案 1 :(得分:2)

比我想象的更容易运行这个函数,只是在调用x时省略Python中的quad变量,它会在其例程中自动传递它。即。

args=(flag, F, K, vol, T2, T1))

它假设{:1}中的x输入变量

def integrand(x, flag, F, K, vol, T2, T1):

声明,而不通过args=()

传递该论点