diff options
author | Marcus Müller <mueller@kit.edu> | 2018-06-18 11:36:54 +0200 |
---|---|---|
committer | Marcus Müller <marcus@hostalia.de> | 2018-06-20 15:51:11 +0200 |
commit | add88dc7387ef41efb2c6aca9e2eccbf311e8f3d (patch) | |
tree | 3372cda37067373caceee017af914b52d3eeaa3b /gr-trellis/python | |
parent | 351dfb8ec4b07dddbd921f994c2bfd89cc35eadf (diff) |
increased PEP compliance of fsm_utils
Diffstat (limited to 'gr-trellis/python')
-rwxr-xr-x | gr-trellis/python/trellis/fsm_utils.py | 177 |
1 files changed, 82 insertions, 95 deletions
diff --git a/gr-trellis/python/trellis/fsm_utils.py b/gr-trellis/python/trellis/fsm_utils.py index 72aa1d3660..f4076623a5 100755 --- a/gr-trellis/python/trellis/fsm_utils.py +++ b/gr-trellis/python/trellis/fsm_utils.py @@ -20,7 +20,6 @@ # Boston, MA 02110-1301, USA. # - import re import math import sys @@ -36,47 +35,44 @@ except ImportError: sys.exit(1) - -###################################################################### -# Decimal to any base conversion. -# Convert 'num' to a list of 'l' numbers representing 'num' -# to base 'base' (most significant symbol first). -###################################################################### -def dec2base(num,base,l): - s=range(l) - n=num +def dec2base(num, base, l): + """ + Decimal to any base conversion. + Convert 'num' to a list of 'l' numbers representing 'num' + to base 'base' (most significant symbol first). + """ + s = range(l) + n = num for i in range(l): - s[l-i-1]=n%base - n=int(n/base) - if n!=0: + s[l - i - 1] = n % base + n = int(n / base) + if n != 0: print 'Number ', num, ' requires more than ', l, 'digits.' return s -###################################################################### -# Conversion from any base to decimal. -# Convert a list 's' of symbols to a decimal number -# (most significant symbol first) -###################################################################### -def base2dec(s,base): - num=0 +def base2dec(s, base): + """ + Conversion from any base to decimal. + Convert a list 's' of symbols to a decimal number + (most significant symbol first) + """ + num = 0 for i in range(len(s)): - num=num*base+s[i] + num = num * base + s[i] return num - - -###################################################################### -# Automatically generate the lookup table that maps the FSM outputs -# to channel inputs corresponding to a channel 'channel' and a modulation -# 'mod'. Optional normalization of channel to unit energy. -# This table is used by the 'metrics' block to translate -# channel outputs to metrics for use with the Viterbi algorithm. -# Limitations: currently supports only one-dimensional modulations. -###################################################################### -def make_isi_lookup(mod,channel,normalize): - dim=mod[0] +def make_isi_lookup(mod, channel, normalize): + """ + Automatically generate the lookup table that maps the FSM outputs + to channel inputs corresponding to a channel 'channel' and a modulation + 'mod'. Optional normalization of channel to unit energy. + This table is used by the 'metrics' block to translate + channel outputs to metrics for use with the Viterbi algorithm. + Limitations: currently supports only one-dimensional modulations. + """ + dim = mod[0] constellation = mod[1] if normalize: @@ -84,104 +80,96 @@ def make_isi_lookup(mod,channel,normalize): for i in range(len(channel)): p = p + channel[i]**2 for i in range(len(channel)): - channel[i] = channel[i]/math.sqrt(p) + channel[i] = channel[i] / math.sqrt(p) - lookup=range(len(constellation)**len(channel)) + lookup = range(len(constellation)**len(channel)) for o in range(len(constellation)**len(channel)): - ss=dec2base(o,len(constellation),len(channel)) - ll=0 + ss = dec2base(o, len(constellation), len(channel)) + ll = 0 for i in range(len(channel)): - ll=ll+constellation[ss[i]]*channel[i] - lookup[o]=ll - return (1,lookup) - - - - - - -###################################################################### -# Automatically generate the signals appropriate for CPM -# decomposition. -# This decomposition is based on the paper by B. Rimoldi -# "A decomposition approach to CPM", IEEE Trans. Info Theory, March 1988 -# See also my own notes at http://www.eecs.umich.edu/~anastas/docs/cpm.pdf -###################################################################### -def make_cpm_signals(K,P,M,L,q,frac): - - Q=numpy.size(q)/L - h=(1.0*K)/P - f0=-h*(M-1)/2 - dt=0.0; # maybe start at t=0.5 - t=(dt+numpy.arange(0,Q))/Q - qq=numpy.zeros(Q) + ll = ll + constellation[ss[i]] * channel[i] + lookup[o] = ll + return (1, lookup) + + +def make_cpm_signals(K, P, M, L, q, frac): + """ + Automatically generate the signals appropriate for CPM + decomposition. + This decomposition is based on the paper by B. Rimoldi + "A decomposition approach to CPM", IEEE Trans. Info Theory, March 1988 + See also my own notes at http://www.eecs.umich.edu/~anastas/docs/cpm.pdf + """ + Q = numpy.size(q) / L + h = (1.0 * K) / P + f0 = -h * (M - 1) / 2 + dt = 0.0 + # maybe start at t=0.5 + t = (dt + numpy.arange(0, Q)) / Q + qq = numpy.zeros(Q) for m in range(L): - qq=qq + q[m*Q:m*Q+Q] - w=math.pi*h*(M-1)*t-2*math.pi*h*(M-1)*qq+math.pi*h*(L-1)*(M-1) + qq = qq + q[m * Q:m * Q + Q] + w = math.pi * h * (M - 1) * t - 2 * math.pi * h * ( + M - 1) * qq + math.pi * h * (L - 1) * (M - 1) - X=(M**L)*P - PSI=numpy.empty((X,Q)) + X = (M**L) * P + PSI = numpy.empty((X, Q)) for x in range(X): - xv=dec2base(x/P,M,L) - xv=numpy.append(xv, x%P) - qq1=numpy.zeros(Q) - for m in range(L): - qq1=qq1+xv[m]*q[m*Q:m*Q+Q] - psi=2*math.pi*h*xv[-1]+4*math.pi*h*qq1+w - #print psi - PSI[x]=psi - PSI = numpy.transpose(PSI) - SS=numpy.exp(1j*PSI) # contains all signals as columns - #print SS - + xv = dec2base(x / P, M, L) + xv = numpy.append(xv, x % P) + qq1 = numpy.zeros(Q) + for m in range(L): + qq1 = qq1 + xv[m] * q[m * Q:m * Q + Q] + psi = 2 * math.pi * h * xv[-1] + 4 * math.pi * h * qq1 + w + PSI[x] = psi + PSI = numpy.transpose(PSI) + SS = numpy.exp(1j * PSI) # contains all signals as columns # Now we need to orthogonalize the signals - F = scipy.linalg.orth(SS) # find an orthonormal basis for SS + F = scipy.linalg.orth(SS) # find an orthonormal basis for SS #print numpy.dot(numpy.transpose(F.conjugate()),F) # check for orthonormality - S = numpy.dot(numpy.transpose(F.conjugate()),SS) + S = numpy.dot(numpy.transpose(F.conjugate()), SS) #print F #print S # We only want to keep those dimensions that contain most # of the energy of the overall constellation (eg, frac=0.9 ==> 90%) # evaluate mean energy in each dimension - E=numpy.sum(numpy.absolute(S)**2,axis=1)/Q - E=E/numpy.sum(E) + E = numpy.sum(numpy.absolute(S)**2, axis=1) / Q + E = E / numpy.sum(E) #print E Es = -numpy.sort(-E) Esi = numpy.argsort(-E) #print Es #print Esi - Ecum=numpy.cumsum(Es) + Ecum = numpy.cumsum(Es) #print Ecum - v0=numpy.searchsorted(Ecum,frac) - N = v0+1 + v0 = numpy.searchsorted(Ecum, frac) + N = v0 + 1 #print v0 #print Esi[0:v0+1] - Ff=numpy.transpose(numpy.transpose(F)[Esi[0:v0+1]]) + Ff = numpy.transpose(numpy.transpose(F)[Esi[0:v0 + 1]]) #print Ff - Sf = S[Esi[0:v0+1]] + Sf = S[Esi[0:v0 + 1]] #print Sf - - return (f0,SS,S,F,Sf,Ff,N) - #return f0 - + return (f0, SS, S, F, Sf, Ff, N) +#return f0 ###################################################################### # A list of common modulations. # Format: (dimensionality,constellation) ###################################################################### -pam2 = (1,[-1, 1]) -pam4 = (1,[-3, -1, 3, 1]) # includes Gray mapping -pam8 = (1,[-7, -5, -3, -1, 1, 3, 5, 7]) +pam2 = (1, [-1, 1]) +pam4 = (1, [-3, -1, 3, 1]) # includes Gray mapping +pam8 = (1, [-7, -5, -3, -1, 1, 3, 5, 7]) psk4=(2,[1, 0, \ 0, 1, \ 0, -1,\ - -1, 0]) # includes Gray mapping + -1, 0]) # includes Gray mapping psk8=(2,[math.cos(2*math.pi*0/8), math.sin(2*math.pi*0/8), \ math.cos(2*math.pi*1/8), math.sin(2*math.pi*1/8), \ @@ -231,4 +219,3 @@ orth4=(4,[1, 0, 0, 0, \ # C test channel (J. Proakis, Digital Communications, McGraw-Hill Inc., 2001) c_channel = [0.227, 0.460, 0.688, 0.460, 0.227] - |