У меня есть следующий код:
# positions: np.ndarray of shape(N,d)
# fitness: np.ndarray of shape(N,)
# mass: np.ndarray of shape(N,)
iteration = 1
while iteration <= maxiter:
K = round((iteration-maxiter)*(N-1)/(1-maxiter) + 1)
for i in range(N):
displacement = positions[:K]-positions[i]
dist = np.linalg.norm(displacement, axis=-1)
if i<K:
dist[i] = 1.0 # prevent 1/0
force_i = (mass[:K]/dist)[:,np.newaxis]*displacement
rand = np.random.rand(K,1)
force[i] = np.sum(np.multiply(rand,force_i), axis=0)
Итак, у меня есть массив, в котором хранятся координаты N
частиц в d
измерениях.Мне нужно сначала вычислить евклидово расстояние между частицей i
и первыми K
частицами, а затем вычислить «силу», связанную с каждой из K
частиц.Затем мне нужно сложить более K
частиц, чтобы найти полную силу, действующую на частицу i
, и повторить для всех N
частиц.Это только части кода, но после некоторого профилирования эта часть является наиболее критичной по времени.
Так что мой вопрос в том, как я могу оптимизировать приведенный выше код.Я постарался максимально векторизовать его, и я не уверен, есть ли еще возможности для улучшения.Результаты профилирования говорят, что {method 'reduce' of 'numpy.ufunc' objects}
, fromnumeric.py:1778(sum)
и linalg.py:2103(norm)
занимают самое продолжительное время для запуска.Первый умирает для массива вещания?Как я могу оптимизировать эти три вызова функций?