Мой любимый способ - использовать библиотеку Благословения (полное раскрытие: я ее написал). Например:
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-последовательности в вашем коде, оставаясь при этом лаконичным в использовании. Веселись!
Изменить:
Теперь есть 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 рассматривает его как ноль, а БПФ рассматривает формы сигналов как периодические, но если это проблема, ее можно исправить с помощью заполнения нулями.Уловка с подобными вещами состоит в том, чтобы найти способ разделять и властвовать .
В настоящее время вы перемещаетесь в каждую позицию и проверяете каждую точку в каждой позиции - фактически операция O (n ^ 2).
Вам нужно уменьшить проверку ] каждую точку и сравнение каждой позиции с чем-то, что меньше работает для определения несоответствия.
Например, у вас может быть более короткое «это даже близко?» фильтр, проверяющий первые несколько позиций. Если корреляция выше некоторого порога, затем продолжайте идти, иначе сдайтесь и двигайтесь дальше.
Вы могли бы иметь «чек на каждую 8-ю позицию», который вы умножаете на 8. Если это слишком мало, пропустите его и двигайтесь дальше. Если это достаточно много, проверьте все значения, чтобы увидеть, нашли ли вы максимумы.
Проблема заключается в времени, необходимом для выполнения всех этих умножений - ( f [
) По сути, вы заполняете большую матрицу всеми этими продуктами и выбираете строку с максимальной суммой. Вы не хотите подсчитывать «все» продукты. Достаточно продуктов, чтобы быть уверенным, что вы нашли максимальную сумму.
Проблема с нахождением максимума в том, что вам нужно просуммировать все , чтобы увидеть, является ли оно наибольшим. Если вы можете превратить это в проблему минимизации, это Проще отказаться от вычисления продуктов и сумм, когда промежуточный результат превышает пороговое значение.
(Я думаю, что это может сработать. Я не пробовал.)
Если вы использовали max (g) -g [ j]
для работы с отрицательными числами вам нужно искать самые маленькие, а не самые большие. Вы можете вычислить корреляцию для первой позиции. Все, что в сумме дает большее значение, можно было немедленно остановить - больше никаких умножений или сложений для этого смещения, переходите к другому.