Imported Upstream version 3.0
[debian/gnuradio] / gnuradio-examples / python / channel-coding / fsm_utils.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2004 Free Software Foundation, Inc.
4 #
5 # This file is part of GNU Radio
6 #
7 # GNU Radio is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2, or (at your option)
10 # any later version.
11 #
12 # GNU Radio is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with GNU Radio; see the file COPYING.  If not, write to
19 # the Free Software Foundation, Inc., 51 Franklin Street,
20 # Boston, MA 02110-1301, USA.
21 #
22
23
24 import re
25 import math
26 import sys
27 import operator
28
29
30
31
32 ######################################################################
33 # Decimal to any base conversion.
34 # Convert 'num' to a list of 'l' numbers representing 'num'
35 # to base 'base' (most significant symbol first).
36 ######################################################################
37 def dec2base(num,base,l):
38     s=range(l)
39     n=num
40     for i in range(l):
41         s[l-i-1]=n%base
42         n=int(n/base)
43     if n!=0:
44         print 'Number ', num, ' requires more than ', l, 'digits.'
45     return s
46
47
48 ######################################################################
49 # Conversion from any base to decimal.
50 # Convert a list 's' of symbols to a decimal number
51 # (most significant symbol first)
52 ######################################################################
53 def base2dec(s,base):
54     num=0
55     for i in range(len(s)):
56         num=num*base+s[i]
57     return num
58
59
60
61
62
63 ######################################################################
64 # Automatically generate the lookup table that maps the FSM outputs
65 # to channel inputs corresponding to a channel 'channel' and a modulation
66 # 'mod'. Optional normalization of channel to unit energy.
67 # This table is used by the 'metrics' block to translate
68 # channel outputs to metrics for use with the Viterbi algorithm. 
69 # Limitations: currently supports only one-dimensional modulations.
70 ######################################################################
71 def make_isi_lookup(mod,channel,normalize):
72     dim=mod[0]
73     constellation = mod[1]
74
75     if normalize:
76         p = 0
77         for i in range(len(channel)):
78             p = p + channel[i]**2
79         for i in range(len(channel)):
80             channel[i] = channel[i]/math.sqrt(p)
81
82     lookup=range(len(constellation)**len(channel))
83     for o in range(len(constellation)**len(channel)):
84         ss=dec2base(o,len(constellation),len(channel))
85         ll=0
86         for i in range(len(channel)):
87             ll=ll+constellation[ss[i]]*channel[i]
88         lookup[o]=ll
89     return (1,lookup)
90
91
92     
93
94
95
96 ######################################################################
97 # A list of common modulations.
98 # Format: (dimensionality,constellation)
99 ######################################################################
100 pam2 = (1,[-1, 1])
101 pam4 = (1,[-3, -1, 3, 1])               # includes Gray mapping
102 pam8 = (1,[-7, -5, -3, -1, 1, 3, 5, 7])
103
104 psk4=(2,[1, 0, \
105          0, 1, \
106          0, -1,\
107         -1, 0])                         # includes Gray mapping
108 psk8=(2,[math.cos(2*math.pi*0/8), math.sin(2*math.pi*0/8),  \
109          math.cos(2*math.pi*1/8), math.sin(2*math.pi*1/8),  \
110          math.cos(2*math.pi*2/8), math.sin(2*math.pi*2/8),  \
111          math.cos(2*math.pi*3/8), math.sin(2*math.pi*3/8),  \
112          math.cos(2*math.pi*4/8), math.sin(2*math.pi*4/8),  \
113          math.cos(2*math.pi*5/8), math.sin(2*math.pi*5/8),  \
114          math.cos(2*math.pi*6/8), math.sin(2*math.pi*6/8),  \
115          math.cos(2*math.pi*7/8), math.sin(2*math.pi*7/8)])
116
117 orth2 = (2,[1, 0, \
118             0, 1])
119 orth4=(4,[1, 0, 0, 0, \
120           0, 1, 0, 0, \
121           0, 0, 1, 0, \
122           0, 0, 0, 1])
123
124 ######################################################################
125 # A list of channels to be tested
126 ######################################################################
127
128 # C test channel (J. Proakis, Digital Communications, McGraw-Hill Inc., 2001)
129 c_channel = [0.227, 0.460, 0.688, 0.460, 0.227]
130
131
132
133
134
135
136
137
138
139
140 if __name__ == '__main__':
141     make_fsm_bin_cc_ff (1,2,[[7,5]])
142     print "----------\n"
143     make_fsm_bin_cc_ff (2,3,[[1,0,2],[0,1,6]])
144