Implémentez la transformée de Fourier discrète (DFT) pour une séquence de n'importe quelle longueur. Cela peut être implémenté sous forme de fonction ou de programme et la séquence peut être donnée soit en argument, soit en utilisant une entrée standard.
L'algorithme calculera un résultat basé sur la DFT standard dans le sens direct. La séquence d'entrée a une longueur N
et se compose de [x(0), x(1), ..., x(N-1)]
. La séquence de sortie aura la même longueur et se composera de l' [X(0), X(1), ..., X(N-1)]
endroit où chacun X(k)
est défini par la relation ci-dessous.
Règles
- C'est le golf de code, donc la solution la plus courte l'emporte.
- Les fonctions intégrées qui calculent la DFT dans les directions avant ou arrière (également appelées inverses) ne sont pas autorisées.
- Les inexactitudes en virgule flottante ne seront pas prises en compte contre vous.
Cas de test
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]
Aidez-moi
Il y avait un défi précédent pour trouver la DFT en utilisant un algorithme FFT pour des séquences de longueurs égales à une puissance de 2. Vous pouvez y trouver quelques astuces qui pourraient vous aider ici. Gardez à l'esprit que ce défi ne vous limite à aucune complexité et nécessite également que votre solution fonctionne pour des séquences de n'importe quelle longueur.
Python 3, 77 octets
Testez-le sur Ideone .
Le code utilise la formule équivalente
la source
J,
3020 octets3 octets grâce à @miles .
Utilise le fait que
e^ipi = -1
.La formule devient
X_k = sum(x_n / ((-1)^(2nk/N)))
.Usage
où
>>
est STDIN et<<
STDOUT."Les inexactitudes en virgule flottante ne seront pas prises en compte contre vous."
la source
MATL ,
2016 octetsL'entrée est un vecteur colonne, c'est-à-dire remplacer les virgules par des points-virgules:
Cela utilise la formule dans la réponse de Leaky Nun , basée sur les faits que exp ( iπ ) = −1, et que l'opératon de puissance de MATL avec un exposant non entier produit (comme dans la plupart des langages de programmation) le résultat de la branche principale .
Essayez-le en ligne!
En raison de l'espacement étrange d'Octave avec des nombres complexes, les parties réelles et imaginaires sont séparées par un espace, tout comme les différentes entrées du vecteur résultant. Si cela semble trop moche, ajoutez un
!
à la fin ( 17 octets ) pour avoir chaque entrée de la sortie dans une ligne différente.Explication
la source
Pyth, 30
Suite de tests
Approche très naïve, juste une implémentation de la formule. Se heurte à divers problèmes mineurs de virgule flottante avec des valeurs qui devraient être des inverses additifs s'ajoutant pour aboutir à des valeurs légèrement différentes de zéro.
Curieusement,
.j
cela ne semble pas fonctionner sans argument, mais je ne sais pas si je l'utilise correctement.la source
Pyth, 18 octets
Utilise le fait que
e^ipi = -1
.La formule devient
X_k = sum(x_n / ((-1)^(2nk/N)))
.Suite de tests.
la source
Julia, 45 octets
Essayez-le en ligne!
Le code utilise la formule équivalente
la source
Python 2, 78 octets
Le polynôme est évalué pour chaque puissance
p
de1j**(4./len(l))
.L'expression
reduce(lambda a,b:a*p+b,l)
évalue le polynôme donné parl
sur la valeurp
via la méthode de Horner:Sauf que la liste d'entrée est inversée, avec un terme constant à la fin. Nous pourrions l'inverser, mais parce que
p**len(l)==1
pour les coefficients de Fourier, nous pouvons utiliser un hack d'inversionp
et multiplier le résultat entier parp
.Quelques tentatives de longueur égale:
En fonction pour 1 octet de plus (79):
Une tentative de récursivité (80):
Simulation itérative
reduce
(80):la source
C (gcc) ,
8678 octetsEssayez-le en ligne!
Cela suppose que le vecteur de sortie est remis à zéro avant utilisation.
la source
Python 2, 89 octets
Utilise le fait que
e^ipi = -1
.La formule devient
X_k = sum(x_n / ((-1)^(2nk/N)))
.Ideone it!
la source
Mathematica,
494847 octetsBasé sur la formule de la solution @Dennis .
la source
Axiome, 81 octets
en utilisant la formule que quelqu'un poste ici. Résultats
la source
Octave ,
4339 octetsEssayez-le en ligne!
Multiplie le vecteur d'entrée par la matrice DFT.
la source