def make_fix_twiddle(N, bits, fraction, offset=0.0, method="round"): twids = cfixpoint(bits, fraction, offset=offset, method=method) tmp = cfixpoint(bits, fraction, offset=offset, method=method) twids.from_complex(np.zeros(N // 2, dtype=np.complex)) for i in range(0, N // 2): tmp.from_complex(np.exp(-2 * i * np.pi * 1j / N)) twids[i] = tmp return twids
def run(self, DATA, cont=False): if (cont == False): size = DATA.data.shape[0] #get length of data stream stages = size // self.N #how many cycles of commutator X = cfixpoint(self.bits, self.fraction, unsigned=self.unsigned, offset=self.offset, method=self.method) X.from_complex(np.zeros([self.N, stages])) #will be tapsize x stage for i in range( 0, stages ): #for each stage, populate all firs, and run FFT once if (i == 0): X[:, i] = iterffft_natural_DIT( self._FIR(DATA[i * self.N:i * self.N + self.N]), self.twids, self.shiftreg.copy(), self.bits, self.fraction) else: X[:, i] = iterffft_natural_DIT( self._FIR(DATA[i * self.N - 1:i * self.N + self.N - 1]), self.twids, self.shiftreg.copy(), self.bits, self.fraction) if (self.dual): self._split(X) self.H_k = self._pow(self.H_k) self.G_k = self._pow(self.G_k) else: self.X_k = self._pow(X) else: pass
def _split(self, Yk): #reverse the arrays for the splitting function correctly R_k = Yk.real.copy() I_k = Yk.imag.copy() R_kflip = R_k.copy() R_kflip[1:] = R_kflip[:0:-1] I_kflip = I_k.copy() I_kflip[1:] = I_kflip[:0:-1] self.G_k = cfixpoint(real=R_k + R_kflip, imag=I_k - I_kflip) #declares two variables for 2 pols self.G_k >> 1 #for bit growth from addition self.G_k.bits = self.bits_fft self.G_k.normalise() self.H_k = cfixpoint(real=I_k + I_kflip, imag=R_kflip - R_k) self.H_k >> 1 self.H_k.bits = self.bits_fft self.H_k.normalise()
def _split(self, Yk): R_k = Yk.real.copy() I_k = Yk.imag.copy() R_kflip = R_k.copy() R_kflip[1:] = R_kflip[:0:-1] I_kflip = I_k.copy() I_kflip[1:] = I_kflip[:0:-1] self.G_k = cfixpoint(real=R_k + R_kflip, imag=I_k - I_kflip) self.G_k >> (self.G_k.bits - self.bits) self.G_k.bits = self.bits self.G_k.fraction = self.fraction self.G_k.normalise() self.H_k = cfixpoint(real=I_k + I_kflip, imag=R_kflip - R_k) self.H_k >> (self.H_k.bits - self.bits) self.H_k.bits = self.bits self.H_k.fraction = self.fraction self.H_k.normalise()
def _FIR(self, x): X_real = self.reg_real * self.window X_real >> self.bits + 1 X_imag = self.reg_imag * self.window X_imag >> (self.bits + 1) X = cfixpoint(real=X_real.sum(axis=1), imag=X_imag.sum(axis=1)) X >> int(np.log2(self.taps)) X.bits = self.bits X.fraction = self.fraction X.normalise() self.reg_real.data = np.column_stack( (x.real.data, self.reg_real.data))[:, :-1] self.reg_imag.data = np.column_stack(( x.imag.data, self.reg_imag.data))[:, :-1] #push and pop from FIR register array return X
def _FIR(self, x): #push and pop from FIR register array self.reg_real.data = np.column_stack( (x.real.data, self.reg_real.data))[:, :-1] self.reg_imag.data = np.column_stack( (x.imag.data, self.reg_imag.data))[:, :-1] X_real = self.reg_real * self.window #compute real and imag products X_imag = self.reg_imag * self.window prodgrth = X_real.fraction - self.frac_fft #-1 since the window coeffs have -1 less fraction X = cfixpoint(real=X_real.sum(axis=1), imag=X_imag.sum(axis=1)) X >> prodgrth + self.firsc #remove growth X.bits = self.bits_fft #normalise to correct bit and frac length X.fraction = self.frac_fft X.normalise() X.method = self.fftmethod #adjust so that it now uses FFT rounding scheme return X #FIR output
""" percent = ("{0:." + str(decimals) + "f}").format( 100 * (iteration / float(total))) filledLength = int(length * iteration // total) bar = fill * filledLength + '-' * (length - filledLength) print('%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end="\r") # Print New Line on Complete if iteration == total: print() N = 2**13 accumval = 500 dmpnum = 0 fixinputev = cfixpoint(17, 17, method="ROUND") #18bit using even rounding fixtwidsev = make_fix_twiddle( N, 17, 16, method="ROUND") #18 bit twiddle factor that uses even rounding fixtwidsev = bitrevfixarray(fixtwidsev, fixtwidsev.data.size) fixinputinf = cfixpoint(17, 17, method="ROUND_INFTY") #18bit using infty rounding fixtwidsinf = make_fix_twiddle( N, 17, 16, method="ROUND_INFTY") #18 bit twiddle factor that uses infty rounding fixtwidsinf = bitrevfixarray(fixtwidsinf, fixtwidsinf.data.size) floattwids = make_twiddle(N) floattwids = bitrevarray(floattwids, floattwids.size) output_vectorev = fixpoint(31, 31, method="ROUND")
from fixpoint import cfixpoint from collections import deque N = 256 n = np.arange(N) bits = 18 fraction = 18 method = "truncate" ####SIGNALS###### sig1 = np.cos(2 * np.pi * n / N) / 2.5 sig2 = np.zeros(N) / 2.5 sig2[10:20] = 1 sig3 = sig1 + 1j * sig2 fsig1 = cfixpoint(bits, fraction, method=method) fsig2 = cfixpoint(bits, fraction, method=method) fsig3 = cfixpoint(bits, fraction, method=method) fsig1.from_complex(sig1) fsig2.from_complex(sig2) fsig3.from_complex(sig3) ####PARAMS#### twidsfloat = make_twiddle(N) twidsfloat = bitrevarray(twidsfloat, twidsfloat.size) twidsfix = make_fix_twiddle(N, bits, fraction - 1, method=method) twidsfix = bitrevfixarray(twidsfix, twidsfix.data.size) #TEST FFT's# def iterfft_test(s, w, st):
N = 2**15 #32k iters = 1 #100k multiplied by the 10 from running individual processes. multiple = 92.1 #number of waves per period - purposefully commensurate over 10 x 32k #we will generate 10 x 32k signals for multiprocessing before abs and summing and saving resultarray = np.zeros((N, 10), dtype=np.float64) def FFT(ID, DATA, twid, shiftreg, bits, fraction, coeffbits): resultarray[:, ID] = np.abs( iterffft_natural_DIT(DATA, twid, shiftreg, bits, fraction, coeffbits).to_complex()) #Generate 10 input signals sig1 = cfixpoint(22, 22) #22 bit fixpoint number that will use even-rounding sig2 = cfixpoint(22, 22) sig3 = cfixpoint(22, 22) sig4 = cfixpoint(22, 22) sig5 = cfixpoint(22, 22) sig6 = cfixpoint(22, 22) sig7 = cfixpoint(22, 22) sig8 = cfixpoint(22, 22) sig9 = cfixpoint(22, 22) sig10 = cfixpoint(22, 22) tn1 = ((np.sin(multiple * (2 * np.pi * np.arange(N)) / N)).astype(np.float64)) / 20 tn2 = ((np.sin(multiple * (2 * np.pi * np.arange(N, 2 * N)) / N)).astype(np.float64)) / 20 tn3 = ((np.sin(multiple * (2 * np.pi * np.arange(2 * N, 3 * N)) / N)).astype(
def make_fix_twiddle(N, bits, fraction, method="ROUND"): twids = cfixpoint(bits, fraction, method=method) twids.from_complex(np.exp(-2 * np.arange(N // 2) * np.pi * 1j / N)) return twids
def run(self, DATA, cont=False): if (DATA is not None): #if a data vector has been parsed if (self.bits_in != DATA.bits): raise ValueError("Input data must match precision specified" + "for input data with bits_in") self.inputdata = DATA elif (self.inputdata is None): #if no data was specified at all raise ValueError("No input data for PFB specified.") size = self.inputdata.data.shape[ 0] #get length of data stream which should be multiple of N data_iter = size // self.N #how many cycles of commutator X = cfixpoint(self.bits_fft, self.frac_fft, unsigned=self.unsigned, method=self.fftmethod) if (self.staged): #if all stages need be stored X.from_complex( np.empty((self.N, data_iter, int(np.log2(self.N)) + 2), dtype=np.complex64) ) #will be tapsize x datalen/point x fft stages +2 #(input and re-ordererd output) for i in range( 0, data_iter ): #for each data_iter, populate all firs, and run FFT once if (i == 0): X[:, i, :] = iterffft_natural_DIT( self._FIR(self.inputdata[0:self.N]), self.twids, self.shiftreg.copy(), self.bits_fft, self.frac_fft, self.twidfrac, self.staged) else: X[:, i, :] = iterffft_natural_DIT( self._FIR(self.inputdata[i * self.N:i * self.N + self.N]), self.twids, self.shiftreg.copy(), self.bits_fft, self.frac_fft, self.twidfrac, self.staged) else: #if stages don't need to be stored X.from_complex(np.empty( (self.N, data_iter), dtype=np.complex64)) #will be tapsize x datalen/point for i in range( 0, data_iter ): #for each stage, populate all firs, and run FFT once if (i == 0): X[:, i] = iterffft_natural_DIT( self._FIR(self.inputdata[0:self.N]), self.twids, self.shiftreg.copy(), self.bits_fft, self.frac_fft, self.twidfrac, self.staged) else: X[:, i] = iterffft_natural_DIT( self._FIR(self.inputdata[i * self.N:i * self.N + self.N]), self.twids, self.shiftreg.copy(), self.bits_fft, self.frac_fft, self.twidfrac, self.staged) """Requantise if bitsout<bitsfft""" if (self.bits_out < self.bits_fft): X >> (self.bits_fft - self.bits_out) X.bits = self.bits_out X.fraction = self.frac_out X.normalise() # """Decide on how to manipulate and display output data""" if (self.dual and not self.staged): #If dual processing but not staged self._split(X) self.G_k_pow = self._pow(self.G_k) self.H_k_pow = self._pow(self.H_k) elif (not self.dual and self.staged): #If single pol processing and staged self.X_k_stgd = X self.X_k_pow = self._pow(X[:, :, -1]) self.X_k = X[:, :, -1] elif (self.dual and self.staged): #If dual pol and staged self.X_k_stgd = X self.split(X[:, :, -1]) self.G_k_pow = self._pow(self.G_k) self.H_k_pow = self._pow(self.H_k) else: #If single pol and no staging self.X_k = X self.X_k_pow = self._pow(X)
def __init__(self, N, taps, bits_in, frac_in, bits_fft, frac_fft, bits_out, frac_out, twidbits, twidfrac, swreg, bitsofacc=32, fracofacc=31, unsigned=False, chan_acc=False, datasrc=None, w='hann', firmethod="ROUND", fftmethod="ROUND", dual=False, fwidth=1, staged=False): """Populate PFB object properties""" self.N = N #how many points self.chan_acc = chan_acc #if summing outputs self.dual = dual #whether you're processing dual polarisations self.taps = taps #how many taps self.bitsofacc = bitsofacc #how many bits to grow to in integration self.fracofacc = fracofacc self.bits_in = bits_in #input data bitlength self.frac_in = frac_in self.bits_fft = bits_fft #fft data bitlength self.frac_fft = frac_fft self.bits_out = bits_out #what bitlength out you want self.frac_out = frac_out self.fwidth = fwidth #normalising factor for fir window if (type(swreg) == int): #if integer is parsed rather than list self.shiftreg = [int(x) for x in bin(swreg)[2:]] if (len(self.shiftreg) < int(np.log2(N))): for i in range(int(np.log2(N)) - len(self.shiftreg)): self.shiftreg.insert(0, 0) elif (type(swreg) == list and type(swreg[0]) == int): #if list of integers is parsed self.shiftreg = swreg else: raise ValueError( 'Shiftregister must be type int or binary list of ints') self.unsigned = unsigned #only used if data parsed in is in a file self.staged = staged #whether to record fft stages self.twidbits = twidbits #how many bits to give twiddle factors self.twidfrac = twidfrac self.firmethod = firmethod #rounding scheme in firs self.fftmethod = fftmethod #rounding scheme in fft #Define variables to be used: self.reg_real = fixpoint(self.bits_in, self.frac_in, unsigned=self.unsigned, method=self.firmethod) self.reg_real.from_float(np.zeros([ N, taps ], dtype=np.int64)) #our fir register size filled with zeros orignally self.reg_imag = self.reg_real.copy() if (datasrc is not None and type(datasrc) == str): #if input data file is specified self.inputdata = cfixpoint(self.bits_in, self.frac_in, unsigned=self.unsigned, method=self.firmethod) self.inputdatadir = datasrc self.outputdatadir = datasrc[:-4] + "out.npy" self.inputdata.from_complex(np.load(datasrc, mmap_mode='r')) else: self.inputdatadir = None #the window coefficients for the fir filter self.window = fixpoint(self.bits_fft, self.frac_fft, unsigned=self.unsigned, method=self.firmethod) tmpcoeff, self.firsc = coeff_gen(self.N, self.taps, w, self.fwidth) self.window.from_float(tmpcoeff) #the twiddle factors for the natural input fft self.twids = make_fix_twiddle(self.N, self.twidbits, twidfrac, method=self.fftmethod) self.twids = bitrevfixarray(self.twids, self.twids.data.size)
#plt.plot(casfftres) #plt.show() # #fxdmax = np.max(fxdfftres) #casmax = np.max(casfftres) #fltmax = np.max(fltfftres) #print('fxdloc ',np.where(fxdfftres>fxdmax-0.001),' casloc ',np.where(casfftres>casmax-0.001), ' fltloc ', # np.where(fltfftres>fltmax-0.001)) """FIR plot comparisons""" firinputdata = spio.loadmat('firinputdata_ns.mat', squeeze_me=True)['inputdata'] firoutputdata = spio.loadmat('firoutputdata_ns.mat', squeeze_me=True)['outputdata'] pfbflt = FloatPFB(2**13, 8) pfbflt.run(firinputdata) datfirfxd = cfixpoint(17, 17) datfirfxd.from_complex(firinputdata) pfbfxd = FixPFB(2**13, 8, 17, 17, 17, 17, 8191, 17, chan_acc=False, w='hann') pfbfxd.run(datfirfxd) firoutflt = np.sum(pfbflt.reg * pfbflt.window, axis=1) / (2**pfbflt.firsc) plt.plot(np.abs(firoutflt)) plt.show() X_real = pfbfxd.reg_real * pfbfxd.window X_imag = pfbfxd.reg_imag * pfbfxd.window prodgrth = X_real.bits - pfbfxd.bits_fft - 1 X = cfixpoint(real=X_real.sum(axis=1), imag=X_imag.sum(axis=1)) X >> prodgrth + pfbfxd.firsc X.bits = pfbfxd.bits_fft X.fraction = pfbfxd.bits_fft X.normalise()