|
|
||
|
|
Start of topic | Skip to actions
The FFT with Sized ListsDFT: Discrete fourier transform. Transform a signal in time domain into frequency domain
x_k=sum_{n=0}^{N-1} x(n)*exp((-2*pi*i/N)*nk) k=0,...,N-1
This is order N^2
FFT: Fast fourier Transform has complexity O(NlogN?). Many versions, most famous Cooley-Tukey. This uses a divide and conquer approach. Applicable to lists that have size that is a power of two. To compute
FFT(x,N,k)=sum_{n odd} x(n)*exp(-(2*pi*i/N)*nk)+sum_{n even} x(n)*exp(-(2*pi*i/N)*nk)
Since we divided things into even an odd, we can rewrite n odd as 2n'+1 and n even as 2n'. We will write x'(n')=x(2n'+1) and x''(n')=x(2n'). To compute
FFT(x,N,k)
=sum_{n'=0}^{N/2-1} x'(n')*exp(-(2*pi*i/N)*(2n'+1)k)+sum_{n'=0}^{N/2-1} x''(2n')*exp(-(2*pi*i/N)*2n'k)
=exp((-2\pi i/N)k)sum_{n'=0}^{N/2-1} x'(n')*exp(-(2*pi*i/(N/2))*n'k)+sum_{n'=0}^{N/2-1} x''(2n')*exp(-(2*pi*i/N)*2n'k)
=exp((-2\pi i/N)k)FFT(x',N/2,k)+FFT(x'',N/2,k)
=w_N^k FFT(x',N/2,k)+FFT(x'',N/2,k)
FFT(x,1,0)=x(0)
In OCaml we can implement this function with
let pi=4.0*atan(1.0);;
let w dir n j=
let theta=dir*.-2*j*.pi/n in
cos ((cos theta),(sin theta))
let add ((r1,i1),(r2,i2))=((r1+.r2),(i1+.i2));;
let sub=...;;
let mult=...;;
let rec split l=
match l with
|[]->([],[])
|x::y::xs->
let (a,b)=split xs in (x::a,y::b);;
let merge dir l1 l2=
uses add, subsr, mult, w...
let rec fft dir l=
if(List .length l=1) then l
else
let (e,0)=split l in
let y0=fft dir e in
let y1=fft dir 0 in
merge dir y0 y1;;
Notice that split takes a list of size N and returns two lists of size N/2 and N/2. Merge takes two lists of size N/2 and returns a single list of size N. The function fft takes a list of size N and returns a list of size N. Our goal will be to replicated these functions in Concoqtion where instead of lists we use sized lists. In concoqtion, our definition of sized lists is:
type (n:nat,'a) slist=
| Nil : ('(0),'a) slist
| Cons of let 'm:'(nat) in 'a*('(n),'a) slist: ('(S m), 'a) slist
For the split function
(* Note that this acts like floor(n/2) rather than n/2 *)
coq
Fixpoint half(n:nat) :nat :=
match n with
| O => O
| S O => O
| S (S m)=> S(half m)
end
let rec split .|n:'(nat)| (l:'(n),'a) slist: (('(half n), 'a)slist,('(half n),'a)slist)
match l in (('(half n), 'a)slist,('(half n),'a)slist) with
| Nil-> Nil,Nil
| Cons -> ...
They could also type merge successfully. Unfortunately, there's a problem with FFT. The problem is that in the FFT function, we split a list into two and then merge it back together. Unfortunately, the half function doesn't exactly divide by two, it takes the floor of n/2. Thus, we can not guarantee that the remerged list has the correct size. Thus, we need to pass through more information. One suggestion is to pass through a proof that something is even as an extra parameter. On the coq side, we then need to prove a few theorems that will guarantee that our remerge list will have the correct size. The nature of these poroofs and theorems is yet to be determined.
Topic Actions: Edit | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r3 < r2 < r1 | More topic actions
Webs: Main | TWiki | Africa | EmbeddedSystems | Gpce | Houston | International | K12 | MetaOCaml | MulticoreOCR | ProgrammingLanguages | RAP | RIDL | Sandbox | SpeechClub | Teaching | Texbot | WG211 Web Actions: |
|
This work is licensed under a Creative Commons Attribution 2.5 License. Please follow our citation guidelines.