Cython и numpy скорость

Мой любимый способ - использовать библиотеку Благословения (полное раскрытие: я ее написал). Например:

from blessings import Terminal

t = Terminal()
print t.red('This is red.')
print t.bold_bright_red_on_black('Bright red on black')

Для печати цветных кубиков наиболее надежным способом является печать пробелов с фоновыми цветами. Я использую эту технику, чтобы нарисовать индикатор выполнения в прогрессивный нос :

print t.on_green(' ')

Вы также можете печатать в определенных местах:

with t.location(0, 5):
    print t.on_yellow(' ')

Если у вас есть чтобы использовать другие возможности терминала в ходе вашей игры, вы также можете сделать это. Вы можете использовать стандартное форматирование строк Python, чтобы сделать его читабельным:

print '{t.clear_eol}You just cleared a {t.bold}whole{t.normal} line!'.format(t=t)

Хорошая особенность Blessings в том, что он старается работать со всеми видами терминалов, а не только с (в подавляющем большинстве распространенным) цветом ANSI из них. Он также сохраняет нечитаемые escape-последовательности в вашем коде, оставаясь при этом лаконичным в использовании. Веселись!

16
задан Vebjorn Ljosa 29 July 2009 в 18:14
поделиться

3 ответа

Изменить:
Теперь есть scipy.signal.fftconvolve , который был бы предпочтительным подходом к реализации подхода свертки на основе БПФ, который я описываю ниже. Я оставлю исходный ответ, чтобы объяснить проблему скорости, но на практике используйте scipy.signal.fftconvolve .

Исходный ответ:
Использование БПФ и ] теорема свертки даст вам значительный выигрыш в скорости за счет преобразования задачи из O (n ^ 2) в O (n log n). Это особенно полезно для длинных наборов данных, таких как ваш, и может дать прирост скорости на 1000 с или намного больше, в зависимости от длины. Это также легко сделать: просто БПФ обоих сигналов умножьте и обратное БПФ произведите. numpy.correlate не использует метод БПФ в процедуре взаимной корреляции, и его лучше использовать с очень маленькими ядрами.

Вот пример

from timeit import Timer
from numpy import *

times = arange(0, 100, .001)

xdata = 1.*sin(2*pi*1.*times) + .5*sin(2*pi*1.1*times + 1.)
ydata = .5*sin(2*pi*1.1*times)

def xcorr(x, y):
    return correlate(x, y, mode='same')

def fftxcorr(x, y):
    fx, fy = fft.fft(x), fft.fft(y[::-1])
    fxfy = fx*fy
    xy = fft.ifft(fxfy)
    return xy

if __name__ == "__main__":
    N = 10
    t = Timer("xcorr(xdata, ydata)", "from __main__ import xcorr, xdata, ydata")
    print 'xcorr', t.timeit(number=N)/N
    t = Timer("fftxcorr(xdata, ydata)", "from __main__ import fftxcorr, xdata, ydata")
    print 'fftxcorr', t.timeit(number=N)/N

, который показывает время работы за цикл (в секундах, для 10 000 длинных сигналов)

xcorr 34.3761689901
fftxcorr 0.0768054962158

Понятно, что метод fftxcorr намного быстрее.

Если вы нанесете на график результаты, вы: Вы увидите, что они очень похожи при почти нулевом временном сдвиге. Обратите внимание, однако, что по мере удаления xcorr будет уменьшаться, а fftxcorr - нет. Это потому, что немного неоднозначно, что делать с частями сигнала, которые не перекрываются при смещении сигналов. xcorr рассматривает его как ноль, а БПФ рассматривает формы сигнала как периодические, но если это проблема, ее можно исправить с помощью заполнения нулями.

Вы увидите, что они очень похожи почти на нулевой временной сдвиг. Обратите внимание, однако, что по мере удаления xcorr будет уменьшаться, а fftxcorr - нет. Это связано с тем, что немного неоднозначно, что делать с частями сигнала, которые не перекрываются при смещении сигналов. xcorr рассматривает его как ноль, а БПФ рассматривает формы сигнала как периодические, но если это проблема, ее можно исправить с помощью заполнения нулями.

Вы увидите, что они очень похожи при почти нулевом временном сдвиге. Обратите внимание, однако, что по мере удаления xcorr будет уменьшаться, а fftxcorr - нет. Это связано с тем, что немного неоднозначно, что делать с частями сигнала, которые не перекрываются при смещении сигналов. xcorr рассматривает его как ноль, а БПФ рассматривает формы сигналов как периодические, но если это проблема, ее можно исправить с помощью заполнения нулями.

37
ответ дан 30 November 2019 в 16:19
поделиться

Уловка с подобными вещами состоит в том, чтобы найти способ разделять и властвовать .

В настоящее время вы перемещаетесь в каждую позицию и проверяете каждую точку в каждой позиции - фактически операция O (n ^ 2).

Вам нужно уменьшить проверку ] каждую точку и сравнение каждой позиции с чем-то, что меньше работает для определения несоответствия.

Например, у вас может быть более короткое «это даже близко?» фильтр, проверяющий первые несколько позиций. Если корреляция выше некоторого порога, затем продолжайте идти, иначе сдайтесь и двигайтесь дальше.

Вы могли бы иметь «чек на каждую 8-ю позицию», который вы умножаете на 8. Если это слишком мало, пропустите его и двигайтесь дальше. Если это достаточно много, проверьте все значения, чтобы увидеть, нашли ли вы максимумы.

Проблема заключается в времени, необходимом для выполнения всех этих умножений - ( f [ (i + j)] * g [j] ) По сути, вы заполняете большую матрицу всеми этими продуктами и выбираете строку с максимальной суммой. Вы не хотите подсчитывать «все» продукты. Достаточно продуктов, чтобы быть уверенным, что вы нашли максимальную сумму.

Проблема с нахождением максимума в том, что вам нужно просуммировать все , чтобы увидеть, является ли оно наибольшим. Если вы можете превратить это в проблему минимизации, это Проще отказаться от вычисления продуктов и сумм, когда промежуточный результат превышает пороговое значение.

(Я думаю, что это может сработать. Я не пробовал.)

Если вы использовали max (g) -g [ j] для работы с отрицательными числами вам нужно искать самые маленькие, а не самые большие. Вы можете вычислить корреляцию для первой позиции. Все, что в сумме дает большее значение, можно было немедленно остановить - больше никаких умножений или сложений для этого смещения, переходите к другому.

2
ответ дан 30 November 2019 в 16:19
поделиться
  • вы можете извлечь диапазон (size2) из ​​внешнего цикла
  • вы можете использовать sum () вместо цикла для вычисления current_correlation
  • вы можете хранить корреляции и задержки в списке и затем используйте max (), чтобы получить самый большой
2
ответ дан 30 November 2019 в 16:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: