diff options
Diffstat (limited to 'gnuradio-examples/python/channel-coding/fsm_utils.py')
-rwxr-xr-x | gnuradio-examples/python/channel-coding/fsm_utils.py | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/gnuradio-examples/python/channel-coding/fsm_utils.py b/gnuradio-examples/python/channel-coding/fsm_utils.py new file mode 100755 index 000000000..dc5ee79f1 --- /dev/null +++ b/gnuradio-examples/python/channel-coding/fsm_utils.py @@ -0,0 +1,239 @@ +#!/usr/bin/env python +# +# Copyright 2004 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + + +import re +import math +import sys +import operator + + + + +###################################################################### +# 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 + for i in range(l): + 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 + for i in range(len(s)): + num=num*base+s[i] + return num + + + + + + + +###################################################################### +# Automaticaly generate the FSM structure for a binary feed-forward +# convolutional code. +# Input: k x n generator matrix (decimal representation) +###################################################################### +def make_fsm_bin_cc_ff(k,n,GM): + mem=[[]]*k + max_mem_x=[-1]*k + max_mem = -1 + for i in range(k): + memr=[0]*n + for j in range(n): + if GM[i][j]==0: + memr[j]=-1 + else: + memr[j]=int(math.log(GM[i][j],2)) + if memr[j]>max_mem_x[i]: + max_mem_x[i]=memr[j] + if memr[j]>max_mem: + max_mem=memr[j] + mem[i]=memr + + sum_max_mem = 0 + for i in range(k): + sum_max_mem = sum_max_mem+max_mem_x[i] + + + #print mem + #print max_mem_x + #print max_mem + #print sum_max_mem + + I=2**k + S=2**sum_max_mem + O=2**n + + #print I, S, O + + NS=[0]*S*I; + OS=[0]*S*I; + for s in range(S): + for i in range(I): + ss=dec2base(s,2,sum_max_mem) + ind=0 + ss_r=[] + for kk in range(k): + ss1 = [0]*max_mem + ss1[0:max_mem_x[kk]] = ss[ind:ind+max_mem_x[kk]] + ss_r.append(ss1) + ind=ind+max_mem_x[kk] + ii=dec2base(i,2,k) + + tt_r = ss_r + for kk in range(k): + tt_r[kk].insert(0,ii[kk]) + #print tt_r + + ns_r = [] + for kk in range(k): + ns_r.append(tt_r[kk][0:max_mem]) + + ns=[] + for kk in range(k): + ns = ns + ns_r[kk][0:max_mem_x[kk]] + NS[s*I+i]=base2dec(ns,2); + + out_r=[0]*n + for nn in range(n): + out=0; + for kk in range(k): + c=[0]*max_mem + gm = dec2base(GM[kk][nn],2,max_mem_x[kk]+1) + gm.reverse() + c[0:len(gm)] = gm + sy = 0 + for m in range(len(c)): + sy = sy + c[m]*tt_r[kk][m]; + out=operator.mod(out+sy,2); + out_r[nn]=out; + out_r.reverse() + OS[s*I+i] = base2dec(out_r,2); + + #O=max(max(OS))+1; + print I, S, O + print NS + print OS + + return (I,S,O,NS,OS) + + + + + +###################################################################### +# 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] + constellation = mod[1] + + if normalize: + p = 0 + for i in range(len(channel)): + p = p + channel[i]**2 + for i in range(len(channel)): + channel[i] = channel[i]/math.sqrt(p) + + lookup=range(len(constellation)**len(channel)) + for o in range(len(constellation)**len(channel)): + 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) + + + + + + +###################################################################### +# 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]) + +psk4=(2,[1, 0, \ + 0, 1, \ + 0, -1,\ + -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), \ + math.cos(2*math.pi*2/8), math.sin(2*math.pi*2/8), \ + math.cos(2*math.pi*3/8), math.sin(2*math.pi*3/8), \ + math.cos(2*math.pi*4/8), math.sin(2*math.pi*4/8), \ + math.cos(2*math.pi*5/8), math.sin(2*math.pi*5/8), \ + math.cos(2*math.pi*6/8), math.sin(2*math.pi*6/8), \ + math.cos(2*math.pi*7/8), math.sin(2*math.pi*7/8)]) + +orth2 = (2,[1, 0, \ + 0, 1]) +orth4=(4,[1, 0, 0, 0, \ + 0, 1, 0, 0, \ + 0, 0, 1, 0, \ + 0, 0, 0, 1]) + +###################################################################### +# A list of channels to be tested +###################################################################### + +# C test channel (J. Proakis, Digital Communications, McGraw-Hill Inc., 2001) +c_channel = [0.227, 0.460, 0.688, 0.460, 0.227] + + + + + + + + + + +if __name__ == '__main__': + make_fsm_bin_cc_ff (1,2,[[7,5]]) + print "----------\n" + make_fsm_bin_cc_ff (2,3,[[1,0,2],[0,1,6]]) + |