annotate constant-q-cpp/src/ext/kissfft/test/testkiss.py @ 372:af71cbdab621 tip

Update bqvec code
author Chris Cannam
date Tue, 19 Nov 2019 10:13:32 +0000
parents 5d0a2ebb4d17
children
rev   line source
Chris@366 1 #!/usr/bin/env python
Chris@366 2
Chris@366 3 import math
Chris@366 4 import sys
Chris@366 5 import os
Chris@366 6 import random
Chris@366 7 import struct
Chris@366 8 import popen2
Chris@366 9 import getopt
Chris@366 10 import numpy
Chris@366 11
Chris@366 12 pi=math.pi
Chris@366 13 e=math.e
Chris@366 14 j=complex(0,1)
Chris@366 15
Chris@366 16 doreal=0
Chris@366 17
Chris@366 18 datatype = os.environ.get('DATATYPE','float')
Chris@366 19
Chris@366 20 util = '../tools/fft_' + datatype
Chris@366 21 minsnr=90
Chris@366 22 if datatype == 'double':
Chris@366 23 fmt='d'
Chris@366 24 elif datatype=='int16_t':
Chris@366 25 fmt='h'
Chris@366 26 minsnr=10
Chris@366 27 elif datatype=='int32_t':
Chris@366 28 fmt='i'
Chris@366 29 elif datatype=='simd':
Chris@366 30 fmt='4f'
Chris@366 31 sys.stderr.write('testkiss.py does not yet test simd')
Chris@366 32 sys.exit(0)
Chris@366 33 elif datatype=='float':
Chris@366 34 fmt='f'
Chris@366 35 else:
Chris@366 36 sys.stderr.write('unrecognized datatype %s\n' % datatype)
Chris@366 37 sys.exit(1)
Chris@366 38
Chris@366 39
Chris@366 40 def dopack(x,cpx=1):
Chris@366 41 x = numpy.reshape( x, ( numpy.size(x),) )
Chris@366 42
Chris@366 43 if cpx:
Chris@366 44 s = ''.join( [ struct.pack(fmt*2,c.real,c.imag) for c in x ] )
Chris@366 45 else:
Chris@366 46 s = ''.join( [ struct.pack(fmt,c.real) for c in x ] )
Chris@366 47 return s
Chris@366 48
Chris@366 49 def dounpack(x,cpx):
Chris@366 50 uf = fmt * ( len(x) / struct.calcsize(fmt) )
Chris@366 51 s = struct.unpack(uf,x)
Chris@366 52 if cpx:
Chris@366 53 return numpy.array(s[::2]) + numpy.array( s[1::2] )*j
Chris@366 54 else:
Chris@366 55 return numpy.array(s )
Chris@366 56
Chris@366 57 def make_random(dims=[1]):
Chris@366 58 res = []
Chris@366 59 for i in range(dims[0]):
Chris@366 60 if len(dims)==1:
Chris@366 61 r=random.uniform(-1,1)
Chris@366 62 if doreal:
Chris@366 63 res.append( r )
Chris@366 64 else:
Chris@366 65 i=random.uniform(-1,1)
Chris@366 66 res.append( complex(r,i) )
Chris@366 67 else:
Chris@366 68 res.append( make_random( dims[1:] ) )
Chris@366 69 return numpy.array(res)
Chris@366 70
Chris@366 71 def flatten(x):
Chris@366 72 ntotal = numpy.size(x)
Chris@366 73 return numpy.reshape(x,(ntotal,))
Chris@366 74
Chris@366 75 def randmat( ndims ):
Chris@366 76 dims=[]
Chris@366 77 for i in range( ndims ):
Chris@366 78 curdim = int( random.uniform(2,5) )
Chris@366 79 if doreal and i==(ndims-1):
Chris@366 80 curdim = int(curdim/2)*2 # force even last dimension if real
Chris@366 81 dims.append( curdim )
Chris@366 82 return make_random(dims )
Chris@366 83
Chris@366 84 def test_fft(ndims):
Chris@366 85 x=randmat( ndims )
Chris@366 86
Chris@366 87
Chris@366 88 if doreal:
Chris@366 89 xver = numpy.fft.rfftn(x)
Chris@366 90 else:
Chris@366 91 xver = numpy.fft.fftn(x)
Chris@366 92
Chris@366 93 open('/tmp/fftexp.dat','w').write(dopack( flatten(xver) , True ) )
Chris@366 94
Chris@366 95 x2=dofft(x,doreal)
Chris@366 96 err = xver - x2
Chris@366 97 errf = flatten(err)
Chris@366 98 xverf = flatten(xver)
Chris@366 99 errpow = numpy.vdot(errf,errf)+1e-10
Chris@366 100 sigpow = numpy.vdot(xverf,xverf)+1e-10
Chris@366 101 snr = 10*math.log10(abs(sigpow/errpow) )
Chris@366 102 print 'SNR (compared to NumPy) : %.1fdB' % float(snr)
Chris@366 103
Chris@366 104 if snr<minsnr:
Chris@366 105 print 'xver=',xver
Chris@366 106 print 'x2=',x2
Chris@366 107 print 'err',err
Chris@366 108 sys.exit(1)
Chris@366 109
Chris@366 110 def dofft(x,isreal):
Chris@366 111 dims=list( numpy.shape(x) )
Chris@366 112 x = flatten(x)
Chris@366 113
Chris@366 114 scale=1
Chris@366 115 if datatype=='int16_t':
Chris@366 116 x = 32767 * x
Chris@366 117 scale = len(x) / 32767.0
Chris@366 118 elif datatype=='int32_t':
Chris@366 119 x = 2147483647.0 * x
Chris@366 120 scale = len(x) / 2147483647.0
Chris@366 121
Chris@366 122 cmd='%s -n ' % util
Chris@366 123 cmd += ','.join([str(d) for d in dims])
Chris@366 124 if doreal:
Chris@366 125 cmd += ' -R '
Chris@366 126
Chris@366 127 print cmd
Chris@366 128 p = popen2.Popen3(cmd )
Chris@366 129
Chris@366 130 open('/tmp/fftin.dat','w').write(dopack( x , isreal==False ) )
Chris@366 131
Chris@366 132 p.tochild.write( dopack( x , isreal==False ) )
Chris@366 133 p.tochild.close()
Chris@366 134
Chris@366 135 res = dounpack( p.fromchild.read() , 1 )
Chris@366 136 open('/tmp/fftout.dat','w').write(dopack( flatten(res) , True ) )
Chris@366 137 if doreal:
Chris@366 138 dims[-1] = int( dims[-1]/2 ) + 1
Chris@366 139
Chris@366 140 res = scale * res
Chris@366 141
Chris@366 142 p.wait()
Chris@366 143 return numpy.reshape(res,dims)
Chris@366 144
Chris@366 145 def main():
Chris@366 146 opts,args = getopt.getopt(sys.argv[1:],'r')
Chris@366 147 opts=dict(opts)
Chris@366 148
Chris@366 149 global doreal
Chris@366 150 doreal = opts.has_key('-r')
Chris@366 151
Chris@366 152 if doreal:
Chris@366 153 print 'Testing multi-dimensional real FFTs'
Chris@366 154 else:
Chris@366 155 print 'Testing multi-dimensional FFTs'
Chris@366 156
Chris@366 157 for dim in range(1,4):
Chris@366 158 test_fft( dim )
Chris@366 159
Chris@366 160 if __name__ == "__main__":
Chris@366 161 main()
Chris@366 162