Как распараллелить вычисление? - PullRequest
2 голосов
/ 20 марта 2019

Я пытаюсь вычислить обыкновенное ОДУ (обыкновенное дифференциальное уравнение) на матрице расстояний, но я не знаю, как распараллелить мой код.

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 Ответ

2 голосов
/ 20 марта 2019

Похоже, у вас есть несколько разных вопросов.Позвольте мне посмотреть, смогу ли я ответить более абстрактно, и вы можете собрать воедино

Параллельно

Один очень простой и простой способ параллельной работы в Python - это multiprocessing

ЕслиВы применяете одну и ту же функцию много раз, вместо:

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

вы можете сделать:

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

Существуют ограничения.И myfun, и args должны быть замачиваемы (что lambda равно , а не , поэтому вы захотите указать это в своем коде)

Вложенные циклы

InВообще, петельные петли медленные.При работе с NumPy лучше «векторизовать», если вы можете.

Поэтому вместо того, чтобы просыпаться по каждому [i,j] элементу d_matrix, посмотрите, сможете ли вы поработать с ними всеми одновременно.Поэтому вычислите матрицу grad_F (а не функцию) и добавьте ее.Вам все еще понадобится ваша временная петля, но вы сможете решить d_matrix за одно, очень быстрое действие.

Другие советы:

Можете ли вы заранее вычислить rho_barre.Может быть, использовать scipy.integrate.cumtrapz для вычисления этого?

Кроме того, попробуйте написать меньше однострочников.Используйте новые функции вместо лямбд.Это облегчит понимание вашего кода!

...