summaryrefslogtreecommitdiff
path: root/gr-trellis/src/examples/fsm_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'gr-trellis/src/examples/fsm_utils.py')
-rwxr-xr-xgr-trellis/src/examples/fsm_utils.py213
1 files changed, 213 insertions, 0 deletions
diff --git a/gr-trellis/src/examples/fsm_utils.py b/gr-trellis/src/examples/fsm_utils.py
new file mode 100755
index 000000000..1b011246c
--- /dev/null
+++ b/gr-trellis/src/examples/fsm_utils.py
@@ -0,0 +1,213 @@
+#!/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 3, 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., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+
+import re
+import math
+import sys
+import operator
+
+from gnuradio import trellis
+
+
+
+######################################################################
+# 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
+
+
+######################################################################
+# Generate a new FSM representing the concatenation of two FSMs
+######################################################################
+def fsm_concatenate(f1,f2):
+ if f1.O() > f2.I():
+ print "Not compatible FSMs\n"
+ I=f1.I()
+ S=f1.S()*f2.S()
+ O=f2.O()
+ nsm=list([0]*I*S)
+ osm=list([0]*I*S)
+ for s1 in range(f1.S()):
+ for s2 in range(f2.S()):
+ for i in range(f1.I()):
+ ns1=f1.NS()[s1*f1.I()+i]
+ o1=f1.OS()[s1*f1.I()+i]
+ ns2=f2.NS()[s2*f2.I()+o1]
+ o2=f2.OS()[s2*f2.I()+o1]
+
+ s=s1*f2.S()+s2
+ ns=ns1*f2.S()+ns2
+ nsm[s*I+i]=ns
+ osm[s*I+i]=o2
+
+
+ f=trellis.fsm(I,S,O,nsm,osm)
+ return f
+
+######################################################################
+# Generate a new FSM representing n stages through the original FSM
+######################################################################
+def fsm_radix(f,n):
+ I=f.I()**n
+ S=f.S()
+ O=f.O()**n
+ nsm=list([0]*I*S)
+ osm=list([0]*I*S)
+ for s in range(f.S()):
+ for i in range(I):
+ ii=dec2base(i,f.I(),n)
+ oo=list([0]*n)
+ ns=s
+ for k in range(n):
+ oo[k]=f.OS()[ns*f.I()+ii[k]]
+ ns=f.NS()[ns*f.I()+ii[k]]
+
+ nsm[s*I+i]=ns
+ osm[s*I+i]=base2dec(oo,f.O())
+
+
+ f=trellis.fsm(I,S,O,nsm,osm)
+ return f
+
+
+
+
+######################################################################
+# 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__':
+ f1=trellis.fsm('fsm_files/awgn1o2_4.fsm')
+ #f2=trellis.fsm('fsm_files/awgn2o3_4.fsm')
+ print f1.I(), f1.S(), f1.O()
+ print f1.NS()
+ print f1.OS()
+ #print f2.I(), f2.S(), f2.O()
+ #print f2.NS()
+ #print f2.OS()
+ ##f1.write_trellis_svg('f1.svg',4)
+ #f2.write_trellis_svg('f2.svg',4)
+ #f=fsm_concatenate(f1,f2)
+ f=fsm_radix(f1,2)
+
+ print "----------\n"
+ print f.I(), f.S(), f.O()
+ print f.NS()
+ print f.OS()
+ #f.write_trellis_svg('f.svg',4)
+