Algoritmo FFT de Bruun
O algoritmo de Bruun é um algoritmo de transformada rápida de Fourier (FFT) baseado numa abordagem invulgar de fatorização recursiva de polinómios, proposto para potências de dois por G. Bruun em 1978 e generalizado para tamanhos compostos pares arbitrários por H. Murakami em 1996. Como as suas operações envolvem apenas coeficientes reais até à última etapa de cálculo, foi inicialmente proposto como uma forma de calcular eficientemente a transformada discreta de Fourier (DFT) de dados reais. O algoritmo de Bruun não tem tido um uso generalizado, contudo, uma vez que as abordagens baseadas no algoritmo FFT de Cooley-Tukey comum foram adaptadas com sucesso para dados reais com pelo menos a mesma eficiência. Além disso, existem evidências de que o algoritmo de Bruun possa ser intrinsecamente menos preciso do que o de Cooley-Tukey face à precisão numérica finita.
Recorde-se que a DFT é definida pela fórmula: X k = ∑ n = 0 N − 1 x n e − 2 π i N n k k = 0 , … , N − 1. {\displaystyle X_{k}=\sum _{n=0}^{N-1}x_{n}e^{-{\frac {2\pi i}{N}}nk}\qquad k=0,\dots ,N-1.} Por conveniência, denotemos as N {\displaystyle N} raízes da unidade por ω N n {\displaystyle \omega _{N}^{n}} ( n = 0 , … , N − 1 {\displaystyle n=0,\dots ,N-1} ): ω N n = e − 2 π i N n {\displaystyle \omega _{N}^{n}=e^{-{\frac {2\pi i}{N}}n}} e defina-se o polinómio x ( z ) {\displaystyle x(z)} cujos coeficientes são x n {\displaystyle x_{n}} : x ( z ) = ∑ n = 0 N − 1 x n z n . {\displaystyle x(z)=\sum _{n=0}^{N-1}x_{n}z^{n}.} A DFT pode então ser compreendida como uma redução deste polinómio; isto é, X k {\displaystyle X_{k}} é dado por: X k = x ( ω N k ) = x ( z ) mod ( z − ω N k ) {\displaystyle X_{k}=x(\omega _{N}^{k})=x(z)\mod (z-\omega _{N}^{k})} onde mod denota a operação de resto polinomial (teorema do resto polinomial). A chave para algoritmos rápidos como o de Bruun ou Cooley-Tukey advém do facto de que é possível executar este conjunto de N {\displaystyle N} operações de resto em fases recursivas.
Para calcular a DFT, precisamos de avaliar o resto de x ( z ) {\displaystyle x(z)} módulo N {\displaystyle N} polinómios de grau 1, tal como descrito acima. Avaliar estes restos um a um é equivalente a avaliar a fórmula habitual da DFT diretamente, e requer O ( N 2 ) {\displaystyle O(N^{2})} operações. Contudo, é possível combinar estes restos recursivamente para reduzir o custo, utilizando o seguinte truque: se quisermos avaliar x ( z ) {\displaystyle x(z)} módulo dois polinómios U ( z ) {\displaystyle U(z)} e V ( z ) {\displaystyle V(z)} , podemos primeiro obter o resto módulo o seu produto U ( z ) V ( z ) {\displaystyle U(z)V(z)} , o que reduz o grau do polinómio x ( z ) {\displaystyle x(z)} e torna as operações de módulo subsequentes menos dispendiosas computacionalmente. O produto de todos os monómios ( z − ω N k ) {\displaystyle (z-\omega _{N}^{k})} para k = 0 … N − 1 {\displaystyle k=0\dots N-1} é simplesmente z N − 1 {\displaystyle z^{N}-1} (cujas raízes são claramente as N {\displaystyle N} raízes da unidade). Pretende-se então encontrar uma fatorização recursiva de z N − 1 {\displaystyle z^{N}-1} em polinómios de poucos termos e de grau cada vez menor. Para calcular a DFT, toma-se x ( z ) {\displaystyle x(z)} módulo cada nível desta fatorização, recursivamente, até se chegar aos monómios e ao resultado final. Se cada nível da fatorização dividir cada polinómio num número O ( 1 ) {\displaystyle O(1)} (limitado por uma constante) de polinómios menores, cada um com um número O ( 1 ) {\displaystyle O(1)} de coeficientes não nulos, então as operações de módulo para esse nível demoram um tempo O ( N ) {\displaystyle O(N)} ; uma vez que haverá um número logarítmico de níveis, a complexidade global é O ( N log N ) {\displaystyle O(N\log N)} .
Cooley-Tukey como fatorização polinomial
O algoritmo padrão de Cooley-Tukey de base- r {\displaystyle r} com dizimação na frequência (DIF - decimation-in-frequency) corresponde de perto a uma fatorização recursiva. Por exemplo, o Cooley-Tukey DIF de base-2 fatora z N − 1 {\displaystyle z^{N}-1} em F 1 = ( z N / 2 − 1 ) {\displaystyle F_{1}=(z^{N/2}-1)} e F 2 = ( z N / 2 + 1 ) {\displaystyle F_{2}=(z^{N/2}+1)} . Estas operações de módulo reduzem o grau de x ( z ) {\displaystyle x(z)} em 2, o que corresponde a dividir o tamanho do problema por 2. Contudo, em vez de fatorizar recursivamente F 2 {\displaystyle F_{2}} diretamente, o Cooley-Tukey calcula primeiro x 2 ( z ω N ) {\displaystyle x_{2}(z\omega _{N})} , deslocando todas as raízes (por um fator de rotação ou twiddle factor) para que se possa aplicar a fatorização recursiva de F 1 {\displaystyle F_{1}} a ambos os subproblemas. Isto é, o algoritmo Cooley-Tukey garante que todos os subproblemas também são DFTs, enquanto que isto não é geralmente verdade para uma fatorização recursiva arbitrária (como a de Bruun, abaixo).
O algoritmo básico de Bruun para potências de dois N = 2 n {\displaystyle N=2^{n}} fatora z 2 n − 1 {\displaystyle z^{2^{n}}-1} recursivamente através das regras: z 2 M − 1 = ( z M − 1 ) ( z M + 1 ) {\displaystyle z^{2M}-1=(z^{M}-1)(z^{M}+1)\,} z 4 M + a z 2 M + 1 = ( z 2 M + 2 − a z M + 1 ) ( z 2 M − 2 − a z M + 1 ) {\displaystyle z^{4M}+az^{2M}+1=(z^{2M}+{\sqrt {2-a}}z^{M}+1)(z^{2M}-{\sqrt {2-a}}z^{M}+1)} onde a {\displaystyle a} é uma constante real com | a | ≤ 2 {\displaystyle |a|\leq 2} . Se a = 2 cos ( ϕ ) {\displaystyle a=2\cos(\phi )} , ϕ ∈ ( 0 , π ) {\displaystyle \phi \in (0,\pi )} , então 2 + a = 2 cos ϕ 2 {\displaystyle {\sqrt {2+a}}=2\cos {\tfrac {\phi }{2}}} e 2 − a = 2 cos ( π 2 − ϕ 2 ) {\displaystyle {\sqrt {2-a}}=2\cos({\tfrac {\pi }{2}}-{\tfrac {\phi }{2}})} . Na etapa s {\displaystyle s} , s = 0 , 1 , 2 , n − 1 {\displaystyle s=0,1,2,n-1} , o estado intermédio consiste em 2 s {\displaystyle 2^{s}} polinómios p s , 0 , … , p s , 2 s − 1 {\displaystyle p_{s,0},\dots ,p_{s,2^{s}-1}} de grau 2 n − s − 1 {\displaystyle 2^{n-s}-1} ou inferior, em que: p s , 0 ( z ) = p ( z ) mod ( z 2 n − s − 1 ) e p s , m ( z ) = p ( z ) mod ( z 2 n − s − 2 cos ( m 2 s π ) z 2 n − 1 − s + 1 ) m = 1 , 2 , … , 2 s − 1 {\displaystyle {\begin{aligned}p_{s,0}(z)&=p(z)\mod \left(z^{2^{n-s}}-1\right)&\quad &{\text{e}}\\p_{s,m}(z)&=p(z)\mod \left(z^{2^{n-s}}-2\cos \left({\tfrac {m}{2^{s}}}\pi \right)z^{2^{n-1-s}}+1\right)&m&=1,2,\dots ,2^{s}-1\end{aligned}}}
Generalização para bases arbitrárias
A fatorização de Bruun, e por conseguinte o algoritmo FFT de Bruun, foi generalizada para lidar com comprimentos compostos pares arbitrários, ou seja, dividindo o grau do polinómio por uma base arbitrária (fator), da seguinte forma. Primeiro, define-se um conjunto de polinómios ϕ N , α ( z ) {\displaystyle \phi _{N,\alpha }(z)} para inteiros positivos N {\displaystyle N} e para α {\displaystyle \alpha } em [ 0 , 1 ) {\displaystyle [0,1)} por: ϕ N , α ( z ) = { z 2 N − 2 cos ( 2 π α ) z N + 1 se 0 < α < 1 z 2 N − 1 se α = 0 {\displaystyle \phi _{N,\alpha }(z)={\begin{cases}z^{2N}-2\cos(2\pi \alpha )z^{N}+1&{\text{se }}0<\alpha <1\\\\z^{2N}-1&{\text{se }}\alpha =0\end{cases}}}


