Быстрое преобразование Фурье
Бы́строе преобразова́ние Фурье́ (БПФ; англ. Fast Fourier Transform – FFT), класс алгоритмов, объединённых общим названием, позволяющих вычислить дискретное преобразование Фурье (ДПФ) любого размера выполнив арифметических операций над комплексными числами. Идеи ускорения ДПФ восходят к работам К. Ф. Гаусса 1805 г., позднее многократно переоткрывались. Основополагающая современная работа по ускорению ДПФ появилась в 1965 г. (Cooley. 1965). Эта статья ссылается на работу (Good. 1958), описывающую алгоритм, который сегодня называют алгоритмом Гуда – Томаса (англ. Good – Thomas Prime Factor algorithm). Работа второго автора этого алгоритма, известного физика и прикладного математика Л. Томаса, опубликована в 1963 г. (Thomas. 1963).
Алгоритм Гуда – Томаса
Если и наибольший общий делитель и равен то алгоритм Гуда – Томаса с помощью китайской теоремы об остатках (см. Дедекиндово кольцо) сводит вычисление ДПФ размера к вычислениям ДПФ размера и вычислениям ДПФ размера
Алгоритм основан на широко известном алгебраическом факте о том, что если и наибольший общий делитель и равен то циклическая группа изоморфна прямому произведению циклических групп и И эта теорема, и алгоритм Гуда – Томаса обобщаются на случай, когда n разлагается в произведение нескольких попарно взаимно простых множителей.
Учитывая, что наивное вычисление ДПФ размера требует примерно операций над комплексными числами, при выполнении, согласно алгоритму Гуда – Томаса, наивных ДПФ размера плюс наивных ДПФ размера будет произведено примерно операций над комплексными числами. При условии это число операций равно что существенно меньше, чем примерно операций, необходимых для наивного вычисления ДПФ размера по определению.
Алгоритм Кули – Тьюки дискретного преобразования Фурье
В работе Дж. Кули и Дж. Тьюки (Cooley. 1965) фактически доказывается, что если то путём выполнения умножений комплексных чисел можно свести вычисление размера к:
вычислениям ДПФ размера плюс
умножениям на степени первообразного корня плюс
вычислениям ДПФ размера
Это рассуждение не требует взаимной простоты и и его можно применять рекурсивно, что позволяет ускорить вычисление ДПФ размера в случаях, когда является произведением большого числа небольших множителей, например имеет вид или – натуральное число.
Алгоритм Кули – Тьюки быстрого преобразования Фурье (n – степень числа 2 с натуральным показателем)
В этом случае ДПФ последовательно упрощается сведением ДПФ чётного размера к двум ДПФ половинного размера путём выполнения всего лишь операций над комплексными числами. Конструкция такого сведения была опубликована ещё в 1942 г. и носит название леммы Ланцоша – Даниельсона. Если имеет вид то, итерируя эту конструкцию, можно построить рекурсивный алгоритм, который выполняет ДПФ размера затрачивая не более арифметических операций.
Рекурсивная реализация алгоритма Кули – Тьюки (n – степень числа 2 с натуральным показателем)
Следуя доказательству леммы Ланцоша – Даниельсона, можно реализовать такой алгоритм рекурсивной подпрограммой на псевдокоде, параметрами которой будут аргумент n типа цел (англ. integer) и модифицируемый аргумент A[0 . . n-1] – массив чисел типа компл (англ. complex) с индексами от до :
алг БПФрекурс(арг цел n, аргрез компл A[0 . . n-1])
Подпрограмма получает в качестве аргумента целое число в качестве модифицируемого аргумента – массив A из комплексных чисел, содержащий исходные данные находит числа по формулам где и записывает результат в массив A.
Для программа БПФрекурс оставляет входной массив без изменений.
Выполнение программы БПФрекурс при проводится в несколько этапов. Сначала создаётся массив W размера который заполняется множителями бабочек Фурье, фигурирующими в доказательстве леммы Ланцоша – Даниельсона. Далее проводится т. н. прореживание входных данных по времени: в памяти создаются два новых массива размера каждый, которые заполняются элементами исходного массива с чётными и нечётными индексами. Затем к каждому из этих массивов размера применяется программа БПФрекурс, в результате чего каждый массив заменяется на своё дискретное преобразование Фурье. Наконец, с помощью выполнения бабочек Фурье с заранее вычисленными множителями результаты двух ДПФ размера объединяются в ДПФ исходного массива размера
алг БПФрекурс(арг цел n, аргрез компл A[0 . . n-1])
дано | n = 2**k и k >= 0
нач цел i
если n = 1 то выход все
компл w = (cos(-2*pi/n), sin(-2*pi/n))
создать компл W[0 . . n/2-1]
W[0] := 1
нц для i от 1 до n/2-1 W[i] := W[i-1]*w кц
создать компл Ачет [0 . . n/2-1]
создать компл Анечет [0 . . n/2-1]
нц для i от 0 до n/2-1
Ачет[i] := A[2*i]
Анечет[i] := A[2*i + 1]
кц
БПФрекурс(n/2, Aчет[0 . . n/2-1])
БПФрекурс(n/2, Aнечет[0 . . n/2-1])
нц для i от 0 до n/2-1
| параллельное присваивание:
A[i], A[i + n/2] := Aчет[i] + W[i]*Aнечет[i], Aчет[i] - W[i]*Aнечет[i]
кц
кон
Индукцией по нетрудно проверить, что выполнение данной рекурсивной программы требует проведения не более операций над комплекcными числами.
Этот псевдокод можно использовать и для теоретико-числового БПФ, заменив тип компл на тип числ (со значениями в используемой числовой системе, например в кольце вычетов по простому модулю, см. Факторкольцо).
Быстрые алгоритмы для проведения ДПФ размера n существуют для любых значений в том числе и для простых Например, алгоритм Блюстейна выполняет ДПФ произвольного размера с помощью алгоритма быстрой свёртки (быстрого умножения многочленов) и для любого вычисляет ДПФ размера выполняя арифметических операций над комплексными числами.
Нерекурсивная реализация алгоритма Кули – Тьюки (n – степень числа 2 с натуральным показателем)
Описанный выше рекурсивный алгоритм Кули – Тьюки требует выделения памяти для хранения промежуточных результатов. Легко заметить, что этот алгоритм проводит много пересылок элементов различных массивов до того, как над ними начнут выполняться какие-либо действия. Этой лишней работы позволяет избежать итеративная реализация БПФ Кули – Тьюки для случая, когда имеет вид где – натуральное число.
Изобразим графически дерево входных массивов рекурсивного БПФ Кули – Тьюки для случая располагая каждую пару вновь создаваемых массивов ниже того массива, из которого они были получены, и размещая при этом в каждом случае подмассив чётных элементов левее массива нечётных элементов.
Рис. 1. Дерево входных массивов рекурсивного БПФ для
Зададим индексы элементов в первой и последней строках рисунка 1 в двоичном видеМы видим, что для элементы в последней строке подвергнуты т. н. битреверсной перестановке и расположены в т. н. битреверсном порядке: двоичная запись индекса элемента в последней строке является перевернутой двоичной записью соответствующего элемента в исходной строке. Аналогичное утверждение верно для при любом
Зададим теперь дерево выходных массивов алгоритма БПФрекурс. Вспомнив, что рекурсивный алгоритм БПФ записывает выходной массив на место входного массива, мы видим, что дерево выходных массивов можно получить, зеркально отразив дерево входных массивов относительно воображаемой горизонтальной линии (на рисунке 2 изображена пунктиром) и заменив каждый входной массив на результат его дискретного преобразования Фурье, который мы будем обозначать
Рис. 2. Деревья входных и выходных массивов рекурсивного БПФ.
Исходя из рисунка 2, можно построить эффективную нерекурсивную реализацию алгоритма Кули – Тьюки, которая проводит все вычисления без использования дополнительных ресурсов памяти (англ. in place), последовательно модифицируя единственный входно-выходной массив длины
алг БПФитер(арг цел n, аргрез компл A[0 . . n-1])
дано | n = 2**k и k >= 1
нач цел i, j, чет, нечет, k = log2(n); компл w
создать компл W[0 . . n/2-1]
W[0]:=1
нц для i от 1 до n/2-1
W[i] := W[i-1]*(cos(-2*pi/n), sin(-2*pi/n))
кц
цел s | номер этапа пробегает 0, 1,…, k-1
цел l=1 | длина подмассива равна 2**s и пробегает 1,2,4,…,n/2
цел n=n/2 | число пар подмассивов равно n/2**(s+1) и пробегает n/2,n/4,…,4,2,1
нц для s от 0 до k-1
нц для j от 0 до n-1
чет := j*2*l; нечет := чет + l
нц для i от 0 до l-1
w := W[n*i]
| параллельное присваивание:
A[чет+i], A[нечет+i]:=A[чет+i]+w*A[нечет+i], A[чет+i]-w*A[нечет+i]
кц
кц
n := n/2
l := 2*l
кц
кон
Предполагается, что на вход этой программы подаётся массив, содержащий вектор входных данных уже переупорядоченный в битреверсном порядке: A[] = где – двоичные цифры представления индекса, т. е. В результате выполнения программы в массиве A размещается вектор
Алгоритм БПФитер проводит этапов модификации массива A с номерами от до На этапе элементы массива А разбиваются на пар соседствующих подмассивов длины и каждая пара подмассивов сливается in place в один массив удвоенной длины с помощью выполнения бабочек Фурье, согласно конструкции, описанной в лемме Ланцоша – Даниельсона. Множители бабочек выбираются из массива W с шагом На каждом из этапов выполняется бабочек Фурье, и общее число арифметических операций в нерекурсивной реализации не превосходит
Эффективность компьютерных программ, вычисляющих БПФ
Практиков интересует трудоёмкость и время выполнения ДПФ на конкретных компьютерах для конкретных значений Это время зависит не только от используемого в программе алгоритма, но и от аппаратных особенностей компьютера, на котором выполняется программа. Среди свободно распространяемых программ, эффективно выполняющих БПФ, широкую известность получила программа FFTW (от англ. The Fastest Fourier Transform in The West) (Frigo. 1998). Эта программа в начале своего выполнения тестирует особенности компьютера, на котором она выполняется, и выбирает вариант алгоритма, учитывающий эти особенности.
До сих пор не известно, можно ли вычислить классическое ДПФ размера выполнив (в обозначениях «о малое») арифметических операций.