annotate ext/kissfft/test/compfft.py @ 184:76ec2365b250

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