Mercurial > hg > may
view src/may/transform/fft.yeti @ 449:ea95ee1cb3a6
Add complex-complex forward/inverse
author | Chris Cannam |
---|---|
date | Thu, 24 Oct 2013 11:12:07 +0100 |
parents | 5d7ad9494633 |
children | 5256bd5ef4ac |
line wrap: on
line source
module may.transform.fft; import edu.emory.mathcs.jtransforms.fft: DoubleFFT_1D; vec = load may.vector; complex = load may.complex; load may.complex.type; packedToComplex len p is number -> ~double[] -> array<cplx> = (n = len / 2; array (map do i: re = if i == n then p[1] else p[i*2] fi; im = if i == 0 or i == n then 0 else p[i*2+1] fi; complex.complex re im; done [0..n])); complexToPacked arr = (n = length arr; v = new double[n*2-2]; for [0..(n-1)*2-1] do i: ix = int (i/2); v[i] := if i == ix*2 then complex.real arr[ix] else complex.imaginary arr[ix] fi; done; v[1] := complex.real arr[n-1]; v); unpackedToComplex len unp is number -> ~double[] -> array<cplx> = array (map2 complex.complex (vec.list (vec.slice unp 0 len)) (vec.list (vec.slice unp len (len*2)))); complexToUnpacked cc is array<cplx> -> ~double[] = vec.primitive (vec.fromList (map complex.real cc ++ map complex.imaginary cc)); //!!! doc: n separately as below forward n = (d = new DoubleFFT_1D(n); do cc: arr = complexToUnpacked cc; d#complexForward(arr); unpackedToComplex n arr; done); //!!! doc: n separately as below inverse n = (d = new DoubleFFT_1D(n); do cc: arr = complexToUnpacked cc; d#complexInverse(arr, true); unpackedToComplex n arr; done); //!!! doc: n is supplied separately from the input vector to support partial evaluation //!!! doc: output has n/2+1 complex values //!!! doc: powers of two only? check with jtransforms realForward n = (d = new DoubleFFT_1D(n); do bl: v = vec.primitive (vec.resizedTo n bl); d#realForward(v); packedToComplex n v; done); //!!! doc: n separately as above realForwardMagnitude n = complex.magnitudes . (realForward n); //!!! doc: input requires n/2+1 complex values (or should test and throw?) //!!! doc: powers of two only? check with jtransforms realInverse n = (d = new DoubleFFT_1D(n); do cplx: v = complexToPacked (array cplx); d#realInverse(v, true); vec.vector v; done); { forward, inverse, realForward, realForwardMagnitude, realInverse, }