Start of topic | Skip to actions

The FFT with Sized Lists

DFT: 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.


End of topic
Skip to actions | Back to top
Creative Commons LicenseThis work is licensed under a Creative Commons Attribution 2.5 License. Please follow our citation guidelines.