Implemente a Transformada discreta de Fourier (DFT) para uma sequência de qualquer comprimento. Isso pode ser implementado como uma função ou um programa e a sequência pode ser dada como um argumento ou usando entrada padrão.
O algoritmo calculará um resultado com base na DFT padrão na direção direta. A sequência de entrada tem comprimento N
e consiste em [x(0), x(1), ..., x(N-1)]
. A sequência de saída terá o mesmo comprimento e consiste em [X(0), X(1), ..., X(N-1)]
onde cada um X(k)
é definido pela relação abaixo.
Regras
- Isso é código-golfe, então a solução mais curta vence.
- Os componentes internos que calculam a DFT nas direções para frente ou para trás (também conhecidos como inversos) não são permitidos.
- Imprecisões de ponto flutuante não serão contadas contra você.
Casos de teste
DFT([1, 1, 1, 1]) = [4, 0, 0, 0]
DFT([1, 0, 2, 0, 3, 0, 4, 0]) = [10, -2+2j, -2, -2-2j, 10, -2+2j, -2, -2-2j]
DFT([1, 2, 3, 4, 5]) = [15, -2.5+3.44j, -2.5+0.81j, -2.5-0.81j, -2.5-3.44j]
DFT([5-3.28571j, -0.816474-0.837162j, 0.523306-0.303902j, 0.806172-3.69346j, -4.41953+2.59494j, -0.360252+2.59411j, 1.26678+2.93119j] = [2, -3j, 5, -7j, 11, -13j, 17]
Socorro
Havia um desafio anterior para encontrar a DFT usando um algoritmo FFT para seqüências com comprimentos iguais a uma potência de 2. Você pode encontrar alguns truques lá que podem ajudá-lo aqui. Lembre-se de que esse desafio não o limita a nenhuma complexidade e também exige que sua solução funcione para sequências de qualquer tamanho.
Python 3, 77 bytes
Teste em Ideone .
O código usa a fórmula equivalente
fonte
J,
3020 bytes3 bytes graças a @miles .
Usa o fato de que
e^ipi = -1
.A fórmula se torna
X_k = sum(x_n / ((-1)^(2nk/N)))
.Uso
onde
>>
é STDIN e<<
STDOUT."Imprecisões de ponto flutuante não serão contadas contra você."
fonte
MATL ,
2016 bytesInput é um vetor de coluna, ou seja, substitua vírgulas por ponto e vírgula:
Isso usa a fórmula na resposta de Leaky Nun , com base nos fatos que exp ( iπ ) = -1, e que a operação de potência do MATL com expoente não inteiro produz (como na maioria das linguagens de programação) o resultado do ramo principal .
Experimente online!
Devido ao espaçamento estranho da Oitava com números complexos, as partes reais e imaginárias são separadas por um espaço, assim como as diferentes entradas do vetor resultante. Se isso parecer muito feio, adicione um
!
no final ( 17 bytes ) para ter cada entrada da saída em uma linha diferente.Explicação
fonte
Pyth, 30
Suíte de teste
Abordagem muito ingênua, apenas uma implementação da fórmula. É executado em vários problemas menores de ponto flutuante com valores que devem ser inversos aditivos, resultando em valores ligeiramente fora de zero.
Estranhamente
.j
, parece não funcionar sem argumentos, mas não tenho certeza se estou usando corretamente.fonte
Pitão, 18 bytes
Usa o fato de que
e^ipi = -1
.A fórmula se torna
X_k = sum(x_n / ((-1)^(2nk/N)))
.Suíte de teste.
fonte
Julia, 45 bytes
Experimente online!
O código usa a fórmula equivalente
fonte
Python 2, 78 bytes
O polinômio é avaliado para cada potência
p
de1j**(4./len(l))
.A expressão
reduce(lambda a,b:a*p+b,l)
avalia o polinômio dado porl
no valorp
via método de Horner:Exceto, a lista de entrada externa é revertida, com termo constante no final. Poderíamos revertê-lo, mas, como
p**len(l)==1
para os coeficientes de Fourier, podemos usar um truque para inverterp
e multiplicar todo o resultado porp
.Algumas tentativas de igual comprimento:
Em função de mais 1 byte (79):
Uma tentativa de recursão (80):
Simulação iterativa
reduce
(80):fonte
C (gcc) ,
8678 bytesExperimente online!
Isso pressupõe que o vetor de saída seja zerado antes do uso.
fonte
Python 2, 89 bytes
Usa o fato de que
e^ipi = -1
.A fórmula se torna
X_k = sum(x_n / ((-1)^(2nk/N)))
.Ideone it!
fonte
Mathematica,
494847 bytesCom base na fórmula da solução @Dennis ' .
fonte
Axioma, 81 bytes
usando a fórmula de alguém postar aqui. Resultados
fonte
Oitava ,
4339 bytesExperimente online!
Multiplica o vetor de entrada pela matriz DFT.
fonte