在python

时间:2017-05-11 21:23:53

标签: python loops scipy nested numerical-integration

我目前正致力于计算python中的数值积分,这实际上是四个嵌套数值积分。每个积分都是不同变量的函数,但我遇到的问题是极限取决于其嵌套在其中的积分(最外层积分具有适当的浮点范围)。

例如,假设我的函数f(a,b,c,d)具有极限amin,amax,bmin,bmax,cmin,cmax,dmin,dmax。 amin和amax是浮动的。 bmin和max是a的函数,cmin和cmax是b的函数,dmin和dmax是c的函数。如果scipy.integrate.quad()只是一个for循环,那么对于每个步骤,都可以将a(或b,c或d)的值传递给限制,使它们成为浮点数。

有没有办法用scipy.integrate.quad做到这一点?到目前为止,我已经尝试过简单的嵌套:

def int4(func,min1,max1,min2,max2,min3,max3,min4,max4):
    finalfunc = scint.quad(scint.quad(scint.quad(scint.quad(func,min1,max1),min2,max2),min3,max3),min4,max4)
    return finalfunc

在这种情况下,我仍然得到我在 ValueError之前遇到的相同错误:给出的无效限制这似乎是因为我有没有被整合的符号。我也试过使用nquad,但我遇到了同样的错误。

这是我目前尝试迭代向外集成的过程,只是在最后做数字:

def int4(func,var1,var2,var3,min1,max1,min2,max2,min3,max3,min4,max4):
    func2 = sym.integrate(func,(var1,min1,max1)
    func3 = sym.integrate(func2,(var2,min2,max2))
    func4 = sym.integrate(func3,(var3,min3,max3))
    finalfunc = scint.quad(func4,min4,max4) 
    return finalfunc

难点在于min1,max1是var2的函数,而实际使用的函数I似乎没有解析解。

如果我从最外层集成而不是最内层集成,它也会有所帮助吗?

感谢Kazemakase,他的回答有助于解决我的问题!我使用稍微修改过的代码解决了这个问题,因此我将此处作为对未来具有类似问题的其他人的参考。

import numpy as np
import scipy.integrate as si

def func(x1, x2, x3, x4):
    return x1**2 - x2**3+x3*x2 - x4*x3**3  

def int1():
    """integrates `int2` over x1"""
    a1, b1 = -1, 3
    def int2(x1):
        """integrates `func` over x2 at given x1.""" 
        #partial_func1 = lambda x2: func(x1, x2)
        b2 = 1 - np.abs(x1)
        a2 = -np.abs(x1**3)
        def int3(x2):
            a3 = x2
            b3 = -a3
            def int4(x3):
                partial_func = lambda x4: func(x1, x2, x3, x4)
                a4 = 1+np.abs(x3)
                b4 = - a4
                return si.quad(partial_func,a4,b4)[0]
            return si.quad(int4, a3, b3)[0]
        return si.quad(int3, a2, b2)[0]     
    return si.quad(int2, a1, b1)[0]

result = int1()  # -22576720.048151683

1 个答案:

答案 0 :(得分:1)

嵌套对quad的调用是正确的方法。但是,简单是不够的。传递给quad的每个参数都需要是一个函数 - 而不是之前调用的结果。以下是将f = x1**2 - x2**3整合到菱形区域abs(x1) + abs(x2) <= 1上的示例。

我们需要能够x2-/+(1 - abs(x1))之间x1之间+/-1之间的import numpy as np import scipy.integrate as si def func(x1, x2): return x1**2 - x2**3 def int2(x1): """integrates `func` over x2 at given x1.""" partial_func = lambda x2: func(x1, x2) b2 = 1 - np.abs(x1) a2 = -b2 return si.quad(partial_func, a2, b2)[0] def int1(): """integrates `int2` over x1""" a1, b1 = -1, 1 return si.quad(int2, a1, b1)[0] result = int1() # 0.33333333333333337 进行整合。

def range1(x2):
    b1 = 1 - np.abs(x2)
    a1 = -b1
    return a1, b1    

result, err = si.nquad(func, [range1, (-1, 1)])
# (0.33333333333333337, 7.401486830834376e-15)

您可以使用nquad代替为每个积分显式编写函数,而不是为您执行换行。它需要每个变量的积分范围,它也可以是一个函数,取决于集成的其他变量:

SELECT ta.*
FROM @Table_A ta 
INNER JOIN @Table_B tb ON ta.Field1 = tb.Field1
WHERE ta.Field3 > 10
AND 
(
   ta.Field2 = tb.Field2
   OR
   NOT EXISTS (
                SELECT 1 FROM @Table_A ta2
                INNER JOIN @Table_B tb2 ON ta2.Field1 = tb2.Field1 AND ta2.Field2 = tb2.Field2
                WHERE ta2.Field1 = ta.Field1
            )    
)