scipy 具有非常数极限的三重积分的数值计算

sqserrrh  于 2023-06-06  发布在  其他
关注(0)|答案(2)|浏览(249)

数值计算具有非常数极限的三重积分。
我想用数值方法计算一个二元函数f(x,y)的三重积分,其中x和y都有积分极限[a+t0-t,b+t0-t],第三个积分在t上有积分极限[t0,t0+a]。我已经试过使用scipy.integrate中的tplquad或nquad来跟踪几个例子,但似乎都不起作用。这是我以前的尝试:

from scipy.integrate import quad, dblquad, tplquad, nquad

def f(x, y):
    # Define your function f(x, y) here
    return x + y  # Example function: x + y

def integrate_function(a, b, t0):
    # Define the limits of integration
    x_lower = lambda t: a + t0 - t
    x_upper = lambda t: b + t0 - t
    y_lower = lambda x, t: a + t0 - t
    y_upper = lambda x, t: b + t0 - t
    t_lower = t0
    t_upper = t0 + a

    # Perform the triple integration
    result, _ = tplquad(f, t_lower, t_upper, y_lower, y_upper, x_lower, x_upper)

    return result

# Example usage
a = 1
b = 2
c = 3
t0 = 0
result = integrate_function(a, b, t0)

这会产生错误:

TypeError: integrate_function.<locals>.<lambda>() missing 1 required positional argument: 't'

我目前的尝试是能够使用nquad计算二重积分:

def f(x, y):
    return x*y

def bounds_y(t0, a):
    return [t0, t0+a]

def bounds_x(y,a,b,t0):
    return [a+t0-y, b+t0-y]

def integrate(a,b,t0):
    return nquad(f, [lambda y: bounds_x(y,a,b,t0), bounds_y(t0,a)])

integrate(2,5,0)

当我尝试实现第三个积分时:

def f(x, y, t):
    return 1

def bounds_t(t0, a):
    return [t0, t0+a]

def bounds_x(y,a,b,t0):
    return [a+t0-y, b+t0-y]

def integrate(a,b,t0):
    return nquad(f, [lambda t: bounds_x(t,a,b,t0), lambda t: bounds_x(t,a,b,t0), bounds_t(t0,a)])

integrate(2,5,0)

它给出错误TypeError: integrate.<locals>.<lambda>() takes 1 positional argument but 2 were given

h4cxqtbf

h4cxqtbf1#

显然,这是一个诀窍:

def f(x, y, t):
    return x*y

def bounds_t(t0, a):
    return [t0, t0+a]

def bounds_x(y,a,b,t0):
    return [a+t0-y, b+t0-y]

def integrate(a,b,t0):
    return nquad(f, [lambda t,x: bounds_x(t,a,b,t0), lambda t: bounds_x(t,a,b,t0), bounds_t(t0,a)])

integrate(2,5,0)
4szc88ey

4szc88ey2#

要正确使用nquadtplquad,确实需要仔细阅读文档。以下是通过nquadtplquad解决集成问题的方案:

from scipy.integrate import tplquad, nquad

def f(x, y, t):
    return x * y

def integrate_via_tplquad(a, b, t0):
    t_lower = t0
    t_upper = t0 + a
    y_lower = lambda t: a + t0 - t
    y_upper = lambda t: b + t0 - t
    # Note order of parameters here: (t, y) rather than (y, t)
    x_lower = lambda t, y: a + t0 - t
    x_upper = lambda t, y: b + t0 - t
    result, _ = tplquad(f, t_lower, t_upper, y_lower, y_upper, x_lower, x_upper)
    return result

def integrate_via_nquad(a, b, t0):
    t_bounds = (t0, t0 + a)
    y_bounds = lambda t: (a + t0 - t, b + t0 - t)
    # Order of parameters (y, t) is opposite to that used in tplquad.
    x_bounds = lambda y, t: (a + t0 - t, b + t0 - t)
    result, _ = nquad(f, [x_bounds, y_bounds, t_bounds])
    return result

print("Result via tplquad: ", integrate_via_tplquad(2, 5, 0))
print("Result via nquad: ", integrate_via_nquad(2, 5, 0))

当我在我的机器上运行上面的代码时,我得到:

Result via tplquad:  118.50000000000001
Result via nquad:  118.50000000000001

请注意,正确的参数顺序非常重要,更糟糕的是,tplquadnquad的约定是相反的。如果你不小心把ytx的边界中颠倒过来,你会得到一个错误的答案:

Result via tplquad:  25.499999999999996
Result via nquad:  25.499999999999996

如果使用nquad,也可以直接将abt0作为参数传递给被积函数和绑定函数,而不必使用上面的闭包。这就是它的样子:

def integrand(x, y, t, a, b, t0):
    return x * y

def x_bounds(y, t, a, b, t0):
    return a + t0 - t, b + t0 - t

def y_bounds(t, a, b, t0):
    return a + t0 - t, b + t0 - t

def t_bounds(a, b, t0):
    return t0, t0 + a

print("Result via nquad (2): ", nquad(integrand, [x_bounds, y_bounds, t_bounds], (2, 5, 0)))

我的机器上的结果:

Result via nquad (2):  (118.50000000000001, 1.3156142841808107e-12)

相关问题