如何并行计算?

时间:2019-03-19 22:11:59

标签: python numpy parallel-processing ode

我正在尝试在距离矩阵上计算一个普通ODE(常微分方程),但是我不知道如何并行化我的代码。

from scipy.integrate import quad
from math import exp
import numpy as np
import matplotlib.pyplot as plt

#I have my distance matrix and I wanna count how many points are distanced
# from point i with distance r at maximum 
def v(dist, r, i):
    return 1/N*(np.count_nonzero(np.select([dist[i,:]<r],[dist[i,:]]))+1)
#integral of rho from r to infinity
def rho_barre(rho, r):
    return quad(rho, r, np.inf)
# integral over r of a certain integrand
def grad_F(i, j, rho, v, v_r, dist):
    return quad(lambda r : ((v(dist, r, i)+v(dist, r, j))/2-v_r)*rho_barre(rho, max(r, dist[i,j])), 0, np.inf) 

#parameters
delta_T = 0.1
rho = (lambda x: exp(-x))
v_r =0

for t in range (1000):
    for i in range(N):
        for j in range(N):
            d_matrix[i,j] = d_matrix[i,j] + delta_T* grad_F(i,j,rho, v, v_r, d_matrix)

首先,我遇到以下错误can't multiply sequence by non-int of type 'float',但我不明白为什么。然后,我知道python中的三个循环太多了,我想知道我们如何才能在Python中使其更快。

1 个答案:

答案 0 :(得分:2)

听起来您有几个不同的问题。让我看看我是否可以更抽象地回答,您可以将其拼凑起来

平行

一种在Python中并行工作的非常简单的方法是multiprocessing

如果您多次应用同一功能,而不是:

res = [myfun(arg) for arg in args]

您可以这样做:

import multiprocessing as mp
with mp.Pool() as pool:
    res = pool.map(myfun,args)

有限制。 myfunargs都必须是可腌制的(lambda不是 ,因此您需要在代码中解决该问题)

嵌套循环

通常,python循环很慢。使用NumPy时,如果可以的话,最好将其“矢量化”。

因此,不必花时间对[i,j]的每个d_matrix元素进行检查,而是看看是否可以同时处理它们。因此,计算一个矩阵 grad_F(而不是一个函数)并将其添加。您仍然需要时间循环,但您可以通过一个非常快速的动作解决d_matrix

其他提示:

您可以预先计算rho_barre吗?也许使用scipy.integrate.cumtrapz来计算?

此外,尝试编写更少的单行代码。使用新函数代替lambda。它将使您更容易理解代码!