September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
1
Task/Fast-Fourier-transform/00META.yaml
Normal file
1
Task/Fast-Fourier-transform/00META.yaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
--- {}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
;;; This is adapted from the Python sample; it uses lists for simplicity.
|
||||
;;; Production code would use complex arrays (for compiler optimization).
|
||||
;;; This version exhibits LOOP features, closing with compositional golf.
|
||||
(defun fft (x &aux (length (length x)))
|
||||
;; base case: return the list as-is
|
||||
(if (<= length 1) x
|
||||
;; collect alternating elements into separate lists...
|
||||
(loop for (a b) on x by #'cddr collect a into as collect b into bs finally
|
||||
;; ... and take the FFT of both;
|
||||
(let* ((ffta (fft as)) (fftb (fft bs))
|
||||
;; incrementally phase shift each element of the 2nd list
|
||||
(aux (loop for b in fftb and k from 0 by (/ pi length -1/2)
|
||||
collect (* b (cis k)))))
|
||||
;; finally, concatenate the sum and difference of the lists
|
||||
(return (mapcan #'mapcar '(+ -) `(,ffta ,ffta) `(,aux ,aux)))))))
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
;;; Demonstrates printing an FFT in both rectangular and polar form:
|
||||
CL-USER> (mapc (lambda (c) (format t "~&~6F~6@Fi = ~6Fe^~6@Fipi"
|
||||
(realpart c) (imagpart c) (abs c) (/ (phase c) pi)))
|
||||
(fft '(1 1 1 1 0 0 0 0)))
|
||||
|
||||
4.0 +0.0i = 4.0e^ +0.0ipi
|
||||
1.0-2.414i = 2.6131e^-0.375ipi
|
||||
0.0 +0.0i = 0.0e^ +0.0ipi
|
||||
1.0-0.414i = 1.0824e^-0.125ipi
|
||||
0.0 +0.0i = 0.0e^ +0.0ipi
|
||||
1.0+0.414i = 1.0824e^+0.125ipi
|
||||
0.0 +0.0i = 0.0e^ +0.0ipi
|
||||
1.0+2.414i = 2.6131e^+0.375ipi
|
||||
;;; MAPC also returns the FFT data, which looks like this:
|
||||
(#C(4.0 0.0) #C(1.0D0 -2.414213562373095D0) #C(0.0D0 0.0D0)
|
||||
#C(1.0D0 -0.4142135623730949D0) #C(0.0 0.0)
|
||||
#C(0.9999999999999999D0 0.4142135623730949D0) #C(0.0D0 0.0D0)
|
||||
#C(0.9999999999999997D0 2.414213562373095D0))
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
(defun fft (x)
|
||||
(if (<= (length x) 1) x
|
||||
(let*
|
||||
(
|
||||
(even (fft (loop for i from 0 below (length x) by 2 collect (nth i x))))
|
||||
(odd (fft (loop for i from 1 below (length x) by 2 collect (nth i x))))
|
||||
(aux (loop for k from 0 below (/ (length x) 2) collect (* (exp (/ (* (complex 0 -2) pi k ) (length x))) (nth k odd))))
|
||||
)
|
||||
(append (mapcar #'+ even aux) (mapcar #'- even aux))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(mapcar (lambda (x) (format t "~a~&" x)) (fft '(1 1 1 1 0 0 0 0)))
|
||||
|
|
@ -1,8 +1,12 @@
|
|||
def fft(x : Array(Float64)) : Array(Complex)
|
||||
require "complex"
|
||||
|
||||
def fft(x : Array(Int32 | Float64)) #: Array(Complex)
|
||||
return [x[0].to_c] if x.size <= 1
|
||||
even = fft(Array.new(x.size / 2) { |k| x[2 * k] })
|
||||
odd = fft(Array.new(x.size / 2) { |k| x[2 * k + 1] })
|
||||
c = Array.new(x.size / 2) { |k| Complex.new(0, -2 * Math::PI * k / x.size).exp }
|
||||
odd = fft(Array.new(x.size / 2) { |k| x[2 * k + 1] })
|
||||
c = Array.new(x.size / 2) { |k| (-2 * Math::PI * k / x.size).i.exp }
|
||||
codd = Array.new(x.size / 2) { |k| c[k] * odd[k] }
|
||||
return Array.new(x.size / 2) { |k| even[k] + codd[k] } + Array.new(x.size / 2) { |k| even[k] - codd[k] }
|
||||
end
|
||||
|
||||
fft([1,1,1,1,0,0,0,0]).each{ |c| puts c }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
]add FFTW
|
||||
using FFTW
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
function fft(a)
|
||||
y1 = Any[]; y2 = Any[]
|
||||
n = length(a)
|
||||
if n ==1 return a end
|
||||
wn(n) = exp(-2*π*im/n)
|
||||
y_even = fft(a[1:2:end])
|
||||
y_odd = fft(a[2:2:end])
|
||||
w = 1
|
||||
for k in 1:Int(n/2)
|
||||
push!(y1, y_even[k] + w*y_odd[k])
|
||||
push!(y2, y_even[k] - w*y_odd[k])
|
||||
w = w*wn(n)
|
||||
end
|
||||
return vcat(y1,y2)
|
||||
end
|
||||
|
|
@ -1,26 +1,28 @@
|
|||
import math, complex, strutils
|
||||
|
||||
proc toComplex(x: float): TComplex = result.re = x
|
||||
proc toComplex(x: TComplex): TComplex = x
|
||||
|
||||
# Works with floats and complex numbers as input
|
||||
proc fft[T](x: openarray[T]): seq[TComplex] =
|
||||
proc fft[T: float | Complex[float]](x: openarray[T]): seq[Complex[float]] =
|
||||
let n = x.len
|
||||
result = newSeq[TComplex]()
|
||||
if n <= 1:
|
||||
for v in x: result.add toComplex(v)
|
||||
if n == 0: return
|
||||
|
||||
result.newSeq(n)
|
||||
|
||||
if n == 1:
|
||||
result[0] = (when T is float: complex(x[0]) else: x[0])
|
||||
return
|
||||
|
||||
var evens, odds = newSeq[T]()
|
||||
for i, v in x:
|
||||
if i mod 2 == 0: evens.add v
|
||||
else: odds.add v
|
||||
var (even, odd) = (fft(evens), fft(odds))
|
||||
|
||||
for k in 0 .. < n div 2:
|
||||
result.add(even[k] + exp((0.0, -2*pi*float(k)/float(n))) * odd[k])
|
||||
let halfn = n div 2
|
||||
|
||||
for k in 0 .. < n div 2:
|
||||
result.add(even[k] - exp((0.0, -2*pi*float(k)/float(n))) * odd[k])
|
||||
for k in 0 .. < halfn:
|
||||
let a = exp(complex(0.0, -2 * Pi* float(k) / float(n))) * odd[k]
|
||||
result[k] = even[k] + a
|
||||
result[k + halfn] = even[k] - a
|
||||
|
||||
for i in fft(@[1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]):
|
||||
echo formatFloat(abs(i), ffDecimal, 3)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue