Одна очевидная вещь, которую вы можете сделать, это заменить строку
r_test_fast = reshape_vector(r_test)
на
r_test_fast = r_test.reshape((3,1))
Вероятно, не будет иметь большого значения в производительности, но в любом случае это имеет смыслиспользовать встроенные функции NumPy вместо изобретения колеса.
Вообще говоря, как вы, наверное, уже заметили, трюк с оптимизацией NUMPY состоит в том, чтобы выразить алгоритм с помощью NUMPY операций с целым массивом или, по крайней мере,с кусочками вместо итерации по каждому элементу в коде Python.То, что предотвращает этот вид «векторизации», это так называемые циклические зависимости, то есть циклы, где каждая итерация зависит от результата предыдущей итерации.Если коротко взглянуть на ваш код, у вас нет такой вещи, и должна быть возможность векторизовать ваш код просто отлично.
РЕДАКТИРОВАТЬ: Одно решение
У меня нетпроверил, что это правильно, но должно дать вам представление о том, как к нему подойти.
Сначала возьмем функцию cartesian (), которую мы будем использовать .Тогда
def calculate_dipole_vect(mus, r_i, mom_i):
# Treat each mu sequentially
Bs = []
omega = []
for mu in mus:
rel = mu - r_i
r_norm = np.sqrt((rel * rel).sum(1))
r_unit = rel / r_norm[:, np.newaxis]
A = 1e-7
num = A*(3*np.sum(mom_i * r_unit, 0)*r_unit - mom_i)
den = r_norm ** 3
B = np.sum(num / den[:, np.newaxis], 0)
Bs.append(B)
omega.append(gamma_mu * np.sqrt(np.dot(B, B)))
return Bs, omega
# Transpose to get more "natural" ordering with row-major numpy
r_i = r_i.T
mom_i = mom_i.T
t_start = time.clock()
r_frac = cartesian((np.arange(n[0]) / float(n[0]),
np.arange(n[1]) / float(n[1]),
np.arange(n[2]) / float(n[2])))
r_test = np.dot(r_frac, a)
B, omega = calculate_dipole_vect(r_test, r_i, mom_i)
print 'Total time for vectorized: %f s' % (time.clock() - t_start)
Что ж, в моем тестировании это на самом деле немного медленнее, чем основанный на циклах подход, с которого я начинал.Дело в том, что в оригинальной версии этого вопроса он уже был векторизован с помощью операций с целыми массивами над массивами формы (20000, 3), поэтому любая дальнейшая векторизация на самом деле не приносит дополнительных преимуществ.Фактически, это может ухудшить производительность, как указано выше, возможно, из-за больших временных массивов.