Numpy "двойное" вещание - возможно ли?

Можно ли использовать "двойное" вещание для удаления цикла в следующем коде? Другими словами, для трансляции по всему массиву времени T а также массивы одинакового размера freqs а также phases,

freqs = np.arange(100)
phases = np.random.randn(len(freqs))
T = np.arange(0, 500)

signal = np.zeros(len(T))
for i in xrange(len(signal)):
    signal[i] = np.sum(np.cos(freqs*T[i] + phases))

2 ответа

Решение

Вы можете изменить T в виде 2d-массива путем добавления к нему новой оси, которая будет запускать трансляцию при умножении / добавлении с 1d-массивом, а затем при последующем использовании numpy.sum свернуть эту ось:

np.sum(np.cos(freqs * T[:,None] + phases), axis=1)
#                      add new axis        remove it with sum

Тестирование:

(np.sum(np.cos(freqs * T[:,None] + phases), axis=1) == signal).all()
# True

Одна идея, которая только что пришла ко мне (но которая может быть вычислительно дорогой?), Состоит в том, чтобы построить аргументы в виде матрицы:

phases = phases.reshape((len(phases), 1))
argumentMatrix = np.outer(freqs, T) + phases
cosineMatrix = np.cos(argumentMatrix)
signal = np.sum(cosineMatrix, axis=0) # sum, collapsing columns
Другие вопросы по тегам