Более быстрое возведение в степень сложных массивов в 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%.

Другие вопросы по тегам