Я посмотрел на код, и я думаю, что этот цикл for
:
af = zeros([theta.shape[0],phi.shape[0]])
for i in range(self.size[0]*self.size[1]):
af = af + ( w[i]*e**(-1j*(k * x_pos[i]*sin(theta)*cos(phi) + k * y_pos[i]* sin(theta)*sin(phi)+ k * z_pos[i] * cos(theta))) )
неверен во многих отношениях. Вы смешиваете измерения, вы не можете циклически таким образом.
И, кстати, чтобы в полной мере использовать numpy
эффективность, никогда не зацикливаться на массивах. Это значительно замедляет выполнение.
Я пытался переработать эту часть.
Во-первых, я советую вам не использовать from numpy import *
, это плохая практика (см. здесь ). Используйте import numpy as np
. Я снова ввел аббревиатуру np
, чтобы вы могли понять, что происходит от numpy
.
Случай, не зависящий от частоты
В этом первом фрагменте предполагается, что w
- это одномерный массив длины 4:Я пренебрегаю частотной зависимостью w
, чтобы показать вам, как вы можете получить то, что вы уже получили без цикла for
и используя вместо этого мощность numpy
.
af_points = w[:,np.newaxis,np.newaxis]*np.e**(-1j*
(k * x_pos[:,np.newaxis,np.newaxis]*np.sin(theta)*np.cos(phi) +
k * y_pos[:,np.newaxis,np.newaxis]*np.sin(theta)*np.sin(phi) +
k * z_pos[:,np.newaxis,np.newaxis]*np.cos(theta)
))
af = np.sum(af_points, axis=0)
Я использую NumPy Broadcast для получения трехмерного массива с именем af_points
, форма которого (4, 200, 200)
. Чтобы сделать это, я использую np.newaxis
, чтобы расширить номер оси массива, чтобы правильно использовать трансляцию. Подробнее здесь на np.newaxis
.
Итак, w[:,np.newaxis,np.newaxis]
- это массив фигур (4, 1, 1). Аналогично для x_pos[:,np.newaxis,np.newaxis]
, y_pos[:,np.newaxis,np.newaxis]
и z_pos[:,np.newaxis,np.newaxis]
. Поскольку углы имеют форму (200, 200), вещание может быть выполнено, а af_points
имеет форму (4, 200, 200). Наконец, сумма получается с помощью np.sum
, суммирования по первой оси для получения массива (200, 200).
Частотно-зависимый регистр
Теперь w
имеет форму (4, 10), где 10 - частотные точки. Идея та же, просто учтите, что частота - это дополнительное измерение в ваших массивах: теперь af_points
будет массивом формы (4, 10, 200, 200), где 10 - это f_points
, который вы определили.
Чтобы это было понятно, я разделил вычисления:
#exp_point is only the exponent, frequency independent. Will be a (4, 200, 200) array.
exp_points = np.e**(-1j*
(k * x_pos[:,np.newaxis,np.newaxis]*np.sin(theta)*np.cos(phi) +
k * y_pos[:,np.newaxis,np.newaxis]*np.sin(theta)*np.sin(phi) +
k * z_pos[:,np.newaxis,np.newaxis]*np.cos(theta)
))
af_points = w[:,:,np.newaxis,np.newaxis] * exp_points[:,np.newaxis,:,:]
af = np.sum(af_points, axis=0)
И теперь af
имеет форму (10, 200, 200).