Более быстрое возведение в степень сложных массивов в Python, используя Arrayfire
В соответствии с документацией по массиву, af.pow()
в настоящее время поддерживает только полномочия (и корни...) реальных массивов. Ошибка не выдается, но я обнаружил, что с помощью af.pow()
со сложным вводом может вызвать огромную утечку памяти, особенно если в качестве ввода используются другие функции (например, af.pow(af.ifft(array), 2)
).
Чтобы обойти это, я написал функцию complexPow
ниже. Кажется, это работает для сложных массивов без утечки памяти, и быстрое сравнение показало, что мой complexPow
функция возвращает те же значения, что и numpy.sqrt()
и **
оператор, например.
def complexPow(inData, power):
for i in af.ParallelRange(inData.shape[0]):
theta = af.atan(af.imag(inData[i])/af.real(inData[i]))
rSquared = af.pow(af.real(inData[i]), 2.0) + \
af.pow(af.imag(inData[i]), 2.0)
r = af.pow(rSquared, .5)
inData[i] = af.pow(r, power) * (af.cos(theta*power) + \
1j*af.sin(theta*power))
return inData
Существует ли более быстрый способ параллельного поэлементного возведения в степень, чем этот? Я не нашел ни одного, но испугался, что мне здесь не хватает трюка...
1 ответ
Это немного быстрее без параллели for
цикл:
def complexPow(inData, power):
theta = af.atan(af.imag(inData)/af.real(inData))
r = af.pow(af.pow(af.real(inData), 2.0) +
af.pow(af.imag(inData), 2.0), .5)
inData = af.pow(r, power) * (af.cos(theta*power) + \
1j*af.sin(theta*power))
return inData
Tetsted для 4000 итераций в течение dtype=complex
массив с размерами (1, 2**18)
используя nvidia Quadro K4200, Spyder 3, Python 2.7, Windows 7:
С помощью af.ParallelRange
: 7,64 с (1,91 мс на итерацию).
Метод выше: 5,94 с (1,49 мс на итерацию).
Увеличение скорости: 28%.