annotate src/ext/kissfft/test/testkiss.py @ 196:da283326bcd3 tip master

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