Capa: ilustração conceitual gerada por IA de um sinal sintético e de suas componentes de frequência. Ela não representa o computador original nem dados experimentais.
Ouvir as componentes de um sinal
Imagine gravar um acorde musical. O microfone fornece uma sequência de amplitudes, enquanto sua pergunta diz respeito às notas que ela contém. A análise de Fourier estabelece uma conexão matemática entre essas descrições. Questões semelhantes surgem ao estudar vibrações ou padrões em uma imagem.
A transformada discreta de Fourier, ou DFT, toma uma sequência finita e a expressa por meio de componentes de frequência discretas. Uma transformada rápida de Fourier, ou FFT, é uma forma eficiente de calcular essa mesma transformada. Não se trata de um novo tipo de espectro. A documentação técnica do NumPy descreve a entrada como um sinal no domínio do tempo e a saída como sua representação no domínio da frequência. Documentação da DFT
A dificuldade prática está na repetição. Um cálculo direto combina cada ponto de entrada com cada frequência de saída. Ao dobrar o número de pontos, o trabalho aritmético dominante fica quatro vezes maior. Se uma pergunta científica exige milhares de pontos, uma fórmula matematicamente simples pode, portanto, se tornar um obstáculo computacional.
Cooley e Tukey apresentaram uma fatoração geral e uma implementação conveniente para potências de dois, incluindo uma forma de reutilizar o espaço de armazenamento do vetor de entrada. Seu artigo relata um programa para o IBM 7094 e tempos de cálculo, além de uma proposta meramente abstrata. O manuscrito foi recebido em 17 de agosto de 1964 e apareceu na edição de abril de 1965 de Mathematics of Computation. O dia da publicação não foi estabelecido aqui. Artigo original, cópia universitária
Um avanço com uma longa história anterior
A ideia não surgiu do nada em 1965. Os pesquisadores de história Michael Heideman, Don Johnson e Sidney Burrus examinaram textos anteriores e identificaram uma decomposição equivalente na obra de Gauss. Eles inferiram uma data de redação por volta de 1805; o próprio manuscrito não tinha data explícita e foi publicado postumamente em 1866. Seu estudo também discute métodos posteriores, incluindo o trabalho de Danielson e Lanczos de 1942 e a abordagem de fatores primos de Good. As restrições de Good diferem das da fatoração geral de Cooley–Tukey. Investigação histórica e cópia de autor acessível
Em suas recordações de 1993, Cooley e Tukey descrevem o papel de Richard Garwin ao conectar esses trabalhos e incentivar seu desenvolvimento. Também reconhecem descobertas anteriores e explicam por que os grandes cálculos eletrônicos tornaram a abordagem valiosa. É um relato retrospectivo dos participantes, com as limitações próprias da memória. Relato de Cooley e Tukey
O ponto de virada duradouro foi a difusão de um cálculo reutilizável na prática. O relato de Princeton sobre o marco reconhecido pelo IEEE o relaciona à computação científica, ao processamento de sinais, à imagem médica e à transmissão de dados. Essas aplicações também dependem de instrumentos, modelos físicos e outros algoritmos; a FFT contribuiu com um poderoso componente computacional. O reconhecimento posterior sustenta sua importância histórica, sem transformar uma comemoração recente na data da descoberta. Princeton e o marco IEEE
Quatro pontos: entender a reutilização antes da fórmula geral
Vamos usar a sequência adimensional [1, 2, 3, 4]. Este exemplo deliberadamente pequeno é nosso cálculo didático, não dados do artigo de 1965. Seja i a unidade imaginária, com i² = −1. A DFT sem fator de escala e com expoente negativo fornece quatro saídas:
| Índice de frequência | Saída |
|---|---|
| 0 | 10 |
| 1 | −2 + 2i |
| 2 | −2 |
| 3 | −2 − 2i |
A primeira saída soma todas as quatro entradas. As demais combinam pesos positivos, negativos e imaginários. Uma saída complexa contém duas componentes; seu módulo e sua fase descrevem, juntos, uma componente de frequência.
Agora, separe as entradas de índices pares [1, 3] das entradas de índices ímpares [2, 4]. Cada par precisa apenas de sua soma e de sua diferença:
- Par de índices pares: E = [4, −2].
- Par de índices ímpares: O = [6, −2].
Combine esses resultados mais curtos. A primeira borboleta produz 4 + 6 = 10 e 4 − 6 = −2. A segunda começa girando o resultado ímpar por meio de −i, o que dá (−i)(−2) = 2i. Suas duas saídas são −2 + 2i e −2 − 2i.
«Borboleta» é o nome dessa operação emparelhada de soma e diferença. Suas linhas cruzadas representam a organização do cálculo, não uma conexão física entre ondas. Ambas as saídas reutilizam os mesmos resultados intermediários. Em um tamanho maior, cada transformada mais curta pode ser dividida novamente: a reutilização passa a formar uma hierarquia, em vez de um atalho isolado.
Do exemplo ao crescimento do cálculo
Para N valores de entrada, definimos nossa convenção por
Xk=n=0∑N−1xne−2πink/N.
Aqui, n indexa as entradas, k indexa as saídas, e ambos vão de zero a N − 1. Os fatores são rotações complexas de módulo unitário. Nossa transformada direta não tem fator de normalização; uma inversa usa o expoente positivo e um fator 1/N. Existem outras convenções. O artigo original parte de uma soma de Fourier com expoente positivo, portanto os sinais e a normalização devem ser comparados explicitamente. Convenção moderna
Para N par, dividimos a soma entre os índices de entrada pares e ímpares. Escrevemos suas transformadas de comprimento N/2 como Eₖ e Oₖ, e definimos W_N = exp(−2πi/N). Para 0 ≤ k < N/2, a reconstrução é
Xk=Ek+WNkOk,Xk+N/2=Ek−WNkOk.
A segunda igualdade usa a mudança de sinal da rotação na metade do círculo. Portanto, calculamos duas transformadas mais curtas e fazemos um número de combinações proporcional a N. Repetir a divisão para N = 2ᵐ produz m = log₂N níveis.
Cada nível envolve uma quantidade de trabalho proporcional ao comprimento da sequência. Consequentemente, o total cresce como N log₂N. A notação O(N log N) descreve esse crescimento, não uma contagem exata de instruções do processador ou de segundos. Uma construção didática em base 2 se restringe a potências de dois; fatorações gerais de Cooley–Tukey podem usar outros comprimentos compostos.
A velocidade em um computador real também depende da organização dos dados, das transferências pela memória e da implementação. Um número menor de operações aritméticas, por si só, não demonstra uma melhoria específica no tempo decorrido em seu dispositivo.
O que um cálculo mais rápido não pode corrigir
Se medições igualmente espaçadas têm um intervalo Δt em segundos, a frequência de amostragem é 1/Δt hertz e o espaçamento entre as posições de frequência é 1/(NΔt) hertz. Interpretar os índices de saída mais altos exige considerar a ordem escolhida para as frequências positivas e negativas. Convenções de frequência
A amostragem finita continua limitando o que se pode inferir. Aqui, t é o tempo em segundos, f é a frequência do sinal em hertz e fₛ = 1/Δt é a frequência de amostragem em hertz. Por exemplo, as amostras de cos(2πft) em t = n/fₛ não mudam se f for substituído por f + fₛ: a fase acrescentada é 2πn. Nenhum algoritmo mais rápido pode distinguir esses dois sinais apenas a partir dessas amostras. O ruído e os modelos de medição inadequados também continuam sendo problemas de medição.
A aritmética numérica introduz outro limite. Os fatores de rotação complexos geralmente exigem aproximações numéricas, e alterar a ordem das operações pode mudar o arredondamento. A discussão de precisão do FFTW destaca a importância de fatores de rotação precisos e documenta diferenças entre implementações e ambientes. A equivalência matemática não promete padrões de bits idênticos em ponto flutuante. Discussão de precisão
Verificar o cálculo didático
Nossa verificação usou CPython 3.12.10 e apenas a biblioteca padrão. As raízes do caso de quatro pontos [1, −i, −1, i] são representadas exatamente, portanto a igualdade exata é adequada para essas pequenas entradas inteiras. Esse critério não deve ser transferido mecanicamente para transformadas mais longas em ponto flutuante.
Os cálculos básicos a seguir foram executados em nossa verificação registrada:
ROOTS = (1, -1j, -1, 1j)
def direct(x, roots=ROOTS):
return [
sum(x[n] * roots[(n*k) % 4] for n in range(4))
for k in range(4)
]
def butterfly(x):
even = (x[0] + x[2], x[0] - x[2])
odd = (x[1] + x[3], x[1] - x[3])
return [
even[0] + odd[0], even[1] - 1j*odd[1],
even[0] - odd[0], even[1] + 1j*odd[1],
]
Compare ambas as funções com [1, 2, 3, 4], um impulso [1, 0, 0, 0], uma constante [1, 1, 1, 1], zeros e [1+i, −2, 3−i, 2i]. Os cinco resultados concordaram exatamente. O primeiro também correspondeu à tabela acima. Inverter os sinais imaginários das raízes mudou o espectro do caso assimétrico, e a verificação o rejeitou como uma convenção diferente.
Isso valida os casos didáticos fixados. Não prova que toda implementação esteja correta nem replica de forma independente o desempenho histórico. O artigo original não fornece o programa completo, as entradas das provas de desempenho ou todas as condições de cronometragem necessárias para uma reprodução desse tipo.
Artigo escrito e traduzido por um sistema de IA a partir das fontes citadas, com verificações automatizadas segundo o método editorial News. O cálculo didático foi executado como descrito; ele não constitui revisão por pares, validação científica humana ou reprodução do programa histórico.
