加速二重积分的数值计算

问题描述 投票:0回答:1

我正在尝试加速以下计算代码:

我只需要为 x > y 从 0 到 1 计算此函数(但需要非常高的离散化,如 dt = 0.001)。我已经矢量化了我的解决方案,但它仍然不够快(确实需要 10 倍的改进)。有任何想法吗? (尝试过类似 cython 的东西,但由于矢量化的性质,仍然很慢)

def solveF(x, f, lam):
    nx = len(x)
    res = np.zeros((nx, nx))
    for i in range(0, nx):
        for j in range(0, nx):
            if i > j:
                res[i][j] = f*np.exp(lam*(x[i]-x[j]))
    return res

def fastKernelCalc(f, x, dx):
    nx = len(x) 
    kappa = np.zeros((nx, nx))
    f2 = f.transpose()
    for i in range(nx):
        t1 = time.time()
        for j, xj in enumerate(x):
            kernel = 0
            if i-j>0 and j!=0:
                kernel -= sum(np.diagonal(f, offset=j-i)[0:j])*dx
                for k in range(0, j):
                    kernel += sum(f2[k][k:k+i-j]*kappa[i-j+k][k:k+i-j])*dx*dx
            kappa[i][j] = kernel
    return kappa

X = 1
dx = 0.001
nx = int(round(X/dx))+1
spatial = np.linspace(0, X, nx)
f = solveF(spatial, 5, 5)
kernel= fastKernelCalc(f, spatial, dx)
python numerical-methods numerical-integration approximation
1个回答
0
投票

我的第一个想法是,如果速度是最重要的,那么您应该使用 C 或 Fortran 来处理数字内容。 Python 很棒,但速度不快。

弹出的东西:

在 solveF 的双循环中,你可以这样做

    for j in range(0,i)

因为如果 j > i 你什么都不做。这不会为您节省很多时间,因为没有进行任何计算,但这是可以改进的。

你能不能重写你的方程,这样你就不用计算 f 的转置了?如果 f 很大,这可能是计算密集型的。

我不是 Python 专家,所以这可能很愚蠢,但我会避免使用“求和”和“对角线”。有时(对此持保留态度)这个通用函数必须进行大量检查以确保可以完成操作。

如果这是最重要的,并且值得付出努力,我会在代码的不同部分添加计时器,以确定哪部分是瓶颈。如果有瓶颈。

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.