annotate ext/kissfft/test/compfft.py @ 409:1f1999b0f577

Bring in kissfft into this repo (formerly a subrepo, but the remote is not responding)
author Chris Cannam <c.cannam@qmul.ac.uk>
date Tue, 21 Jul 2015 07:34:15 +0100
parents
children
rev   line source
c@409 1 #!/usr/bin/env python
c@409 2
c@409 3 # use FFTPACK as a baseline
c@409 4 import FFT
c@409 5 from Numeric import *
c@409 6 import math
c@409 7 import random
c@409 8 import sys
c@409 9 import struct
c@409 10 import fft
c@409 11
c@409 12 pi=math.pi
c@409 13 e=math.e
c@409 14 j=complex(0,1)
c@409 15 lims=(-32768,32767)
c@409 16
c@409 17 def randbuf(n,cpx=1):
c@409 18 res = array( [ random.uniform( lims[0],lims[1] ) for i in range(n) ] )
c@409 19 if cpx:
c@409 20 res = res + j*randbuf(n,0)
c@409 21 return res
c@409 22
c@409 23 def main():
c@409 24 from getopt import getopt
c@409 25 import popen2
c@409 26 opts,args = getopt( sys.argv[1:],'u:n:Rt:' )
c@409 27 opts=dict(opts)
c@409 28 exitcode=0
c@409 29
c@409 30 util = opts.get('-u','./kf_float')
c@409 31
c@409 32 try:
c@409 33 dims = [ int(d) for d in opts['-n'].split(',')]
c@409 34 cpx = opts.get('-R') is None
c@409 35 fmt=opts.get('-t','f')
c@409 36 except KeyError:
c@409 37 sys.stderr.write("""
c@409 38 usage: compfft.py
c@409 39 -n d1[,d2,d3...] : FFT dimension(s)
c@409 40 -u utilname : see sample_code/fftutil.c, default = ./kf_float
c@409 41 -R : real-optimized version\n""")
c@409 42 sys.exit(1)
c@409 43
c@409 44 x = fft.make_random( dims )
c@409 45
c@409 46 cmd = '%s -n %s ' % ( util, ','.join([ str(d) for d in dims]) )
c@409 47 if cpx:
c@409 48 xout = FFT.fftnd(x)
c@409 49 xout = reshape(xout,(size(xout),))
c@409 50 else:
c@409 51 cmd += '-R '
c@409 52 xout = FFT.real_fft(x)
c@409 53
c@409 54 proc = popen2.Popen3( cmd , bufsize=len(x) )
c@409 55
c@409 56 proc.tochild.write( dopack( x , fmt ,cpx ) )
c@409 57 proc.tochild.close()
c@409 58 xoutcomp = dounpack( proc.fromchild.read( ) , fmt ,1 )
c@409 59 #xoutcomp = reshape( xoutcomp , dims )
c@409 60
c@409 61 sig = xout * conjugate(xout)
c@409 62 sigpow = sum( sig )
c@409 63
c@409 64 diff = xout-xoutcomp
c@409 65 noisepow = sum( diff * conjugate(diff) )
c@409 66
c@409 67 snr = 10 * math.log10(abs( sigpow / noisepow ) )
c@409 68 if snr<100:
c@409 69 print xout
c@409 70 print xoutcomp
c@409 71 exitcode=1
c@409 72 print 'NFFT=%s,SNR = %f dB' % (str(dims),snr)
c@409 73 sys.exit(exitcode)
c@409 74
c@409 75 def dopack(x,fmt,cpx):
c@409 76 x = reshape( x, ( size(x),) )
c@409 77 if cpx:
c@409 78 s = ''.join( [ struct.pack('ff',c.real,c.imag) for c in x ] )
c@409 79 else:
c@409 80 s = ''.join( [ struct.pack('f',c) for c in x ] )
c@409 81 return s
c@409 82
c@409 83 def dounpack(x,fmt,cpx):
c@409 84 uf = fmt * ( len(x) / 4 )
c@409 85 s = struct.unpack(uf,x)
c@409 86 if cpx:
c@409 87 return array(s[::2]) + array( s[1::2] )*j
c@409 88 else:
c@409 89 return array(s )
c@409 90
c@409 91 if __name__ == "__main__":
c@409 92 main()