1-
2-
31# Authors: Veeresh Taranalli <[email protected] > 42# License: BSD 3-Clause
53
1816class Trellis :
1917 """
2018 Class defining a Trellis corresponding to a k/n - rate convolutional code.
21-
2219 Parameters
2320 ----------
2421 memory : 1D ndarray of ints
2522 Number of memory elements per input of the convolutional encoder.
26-
2723 g_matrix : 2D ndarray of ints (octal representation)
2824 Generator matrix G(D) of the convolutional encoder. Each element of
2925 G(D) represents a polynomial.
30-
3126 feedback : int, optional
3227 Feedback polynomial of the convolutional encoder. Default value is 00.
33-
3428 code_type : {'default', 'rsc'}, optional
3529 Use 'rsc' to generate a recursive systematic convolutional code.
36-
3730 If 'rsc' is specified, then the first 'k x k' sub-matrix of
38-
3931 G(D) must represent a identity matrix along with a non-zero
4032 feedback polynomial.
41-
42-
4333 Attributes
4434 ----------
4535 k : int
4636 Size of the smallest block of input bits that can be encoded using
4737 the convolutional code.
48-
4938 n : int
5039 Size of the smallest block of output bits generated using
5140 the convolutional code.
52-
5341 total_memory : int
5442 Total number of delay elements needed to implement the convolutional
5543 encoder.
56-
5744 number_states : int
5845 Number of states in the convolutional code trellis.
59-
6046 number_inputs : int
6147 Number of branches from each state in the convolutional code trellis.
62-
6348 next_state_table : 2D ndarray of ints
6449 Table representing the state transition matrix of the
6550 convolutional code trellis. Rows represent current states and
6651 columns represent current inputs in decimal. Elements represent the
6752 corresponding next states in decimal.
68-
6953 output_table : 2D ndarray of ints
7054 Table representing the output matrix of the convolutional code trellis.
7155 Rows represent current states and columns represent current inputs in
7256 decimal. Elements represent corresponding outputs in decimal.
73-
7457 Examples
7558 --------
7659 >>> from numpy import array
@@ -98,7 +81,6 @@ class Trellis:
9881 [3 0]
9982 [1 2]
10083 [2 1]]
101-
10284 """
10385 def __init__ (self , memory , g_matrix , feedback = 0 , code_type = 'default' ):
10486
@@ -107,7 +89,8 @@ def __init__(self, memory, g_matrix, feedback = 0, code_type = 'default'):
10789 if code_type == 'rsc' :
10890 for i in range (self .k ):
10991 g_matrix [i ][i ] = feedback
110-
92+ self .code_type = code_type
93+
11194 self .total_memory = memory .sum ()
11295 self .number_states = pow (2 , self .total_memory )
11396 self .number_inputs = pow (2 , self .k )
@@ -176,7 +159,7 @@ def _generate_grid(self, trellis_length):
176159 """ Private method """
177160
178161 grid = np .mgrid [0.12 :0.22 * trellis_length :(trellis_length + 1 )* (0 + 1j ),
179- 0.1 :0.1 + self .number_states * 0.1 :self .number_states * (0 + 1j )].reshape (2 , - 1 )
162+ 0.1 :0.5 + self .number_states * 0.1 :self .number_states * (0 + 1j )].reshape (2 , - 1 )
180163
181164 return grid
182165
@@ -231,27 +214,22 @@ def _generate_labels(self, grid, state_order, state_radius, font):
231214 def visualize (self , trellis_length = 2 , state_order = None ,
232215 state_radius = 0.04 , edge_colors = None ):
233216 """ Plot the trellis diagram.
234-
235217 Parameters
236218 ----------
237219 trellis_length : int, optional
238220 Specifies the number of time steps in the trellis diagram.
239221 Default value is 2.
240-
241222 state_order : list of ints, optional
242223 Specifies the order in the which the states of the trellis
243224 are to be displayed starting from the top in the plot.
244225 Default order is [0,...,number_states-1]
245-
246226 state_radius : float, optional
247227 Radius of each state (circle) in the plot.
248228 Default value is 0.04
249-
250229 edge_colors = list of hex color codes, optional
251230 A list of length equal to the number_inputs,
252231 containing color codes that represent the edge corresponding
253232 to the input.
254-
255233 """
256234 if edge_colors is None :
257235 edge_colors = ["#9E1BE0" , "#06D65D" ]
@@ -260,7 +238,7 @@ def visualize(self, trellis_length = 2, state_order = None,
260238 state_order = list (range (self .number_states ))
261239
262240 font = "sans-serif"
263- fig = plt .figure ()
241+ fig = plt .figure (figsize = ( 12 , 6 ), dpi = 150 )
264242 ax = plt .axes ([0 ,0 ,1 ,1 ])
265243 trellis_patches = []
266244
@@ -281,26 +259,27 @@ def visualize(self, trellis_length = 2, state_order = None,
281259 ax .add_collection (collection )
282260 ax .set_xticks ([])
283261 ax .set_yticks ([])
284- # plt.legend([edge_patches[0], edge_patches[1]], ["1-input", "0-input"])
285- plt .show ( )
262+ plt .legend ([edge_patches [0 ], edge_patches [1 ]], ["1-input" , "0-input" ])
263+ plt .savefig ( 'trellis' )
286264
287265
288- def conv_encode (message_bits , trellis , code_type = 'default ' , puncture_matrix = None ):
266+ def conv_encode (message_bits , trellis , termination = 'cont ' , puncture_matrix = None ):
289267 """
290268 Encode bits using a convolutional code.
291-
269+
292270 Parameters
293271 ----------
294272 message_bits : 1D ndarray containing {0, 1}
295273 Stream of bits to be convolutionally encoded.
296-
297- generator_matrix : 2-D ndarray of ints
298- Generator matrix G(D) of the convolutional code using which the input
299- bits are to be encoded.
300-
301- M : 1D ndarray of ints
302- Number of memory elements per input of the convolutional encoder.
303-
274+
275+ trellis: pre-initialized Trellis structure.
276+
277+ termination: {'cont', 'term'}, optional
278+ Create ('term') or not ('cont') termination bits.
279+
280+ puncture_matrix: 2D ndarray containing {0, 1}, optional
281+ Matrix used for the puncturing algorithm
282+
304283 Returns
305284 -------
306285 coded_bits : 1D ndarray containing {0, 1}
@@ -311,26 +290,32 @@ def conv_encode(message_bits, trellis, code_type = 'default', puncture_matrix=No
311290 n = trellis .n
312291 total_memory = trellis .total_memory
313292 rate = float (k )/ n
293+
294+ code_type = trellis .code_type
314295
315296 if puncture_matrix is None :
316297 puncture_matrix = np .ones ((trellis .k , trellis .n ))
317298
318299 number_message_bits = np .size (message_bits )
319-
320- # Initialize an array to contain the message bits plus the truncation zeros
321- if code_type == 'default' :
322- inbits = np .zeros (number_message_bits + total_memory + total_memory % k ,
323- 'int' )
324- number_inbits = number_message_bits + total_memory + total_memory % k
325-
326- # Pad the input bits with M zeros (L-th terminated truncation)
327- inbits [0 :number_message_bits ] = message_bits
328- number_outbits = int (number_inbits / rate )
329-
300+
301+ if termination == 'term' :
302+ # Initialize an array to contain the message bits plus the truncation zeros
303+ if code_type == 'rsc' :
304+ inbits = message_bits
305+ number_inbits = number_message_bits
306+ number_outbits = int ((number_inbits + total_memory )/ rate )
307+ else :
308+ number_inbits = number_message_bits + total_memory + total_memory % k
309+ inbits = np .zeros (number_inbits , 'int' )
310+ # Pad the input bits with M zeros (L-th terminated truncation)
311+ inbits [0 :number_message_bits ] = message_bits
312+ number_outbits = int (number_inbits / rate )
330313 else :
331314 inbits = message_bits
332315 number_inbits = number_message_bits
333- number_outbits = int ((number_inbits + total_memory )/ rate )
316+ number_outbits = int (number_inbits / rate )
317+
318+
334319
335320 outbits = np .zeros (number_outbits , 'int' )
336321 p_outbits = np .zeros (int (number_outbits *
@@ -349,8 +334,7 @@ def conv_encode(message_bits, trellis, code_type = 'default', puncture_matrix=No
349334 current_state = next_state_table [current_state ][current_input ]
350335 j += 1
351336
352- if code_type == 'rsc' :
353-
337+ if code_type == 'rsc' and termination == 'term' :
354338 term_bits = dec2bitarray (current_state , trellis .total_memory )
355339 term_bits = term_bits [::- 1 ]
356340 for i in range (trellis .total_memory ):
@@ -360,11 +344,12 @@ def conv_encode(message_bits, trellis, code_type = 'default', puncture_matrix=No
360344 current_state = next_state_table [current_state ][current_input ]
361345 j += 1
362346
363- j = 0
364- for i in range (number_outbits ):
365- if puncture_matrix [0 ][i % np .size (puncture_matrix , 1 )] == 1 :
366- p_outbits [j ] = outbits [i ]
367- j = j + 1
347+ if puncture_matrix is not None :
348+ j = 0
349+ for i in range (number_outbits ):
350+ if puncture_matrix [0 ][i % np .size (puncture_matrix , 1 )] == 1 :
351+ p_outbits [j ] = outbits [i ]
352+ j = j + 1
368353
369354 return p_outbits
370355
@@ -474,32 +459,25 @@ def _acs_traceback(r_codeword, trellis, decoding_type,
474459def viterbi_decode (coded_bits , trellis , tb_depth = None , decoding_type = 'hard' ):
475460 """
476461 Decodes a stream of convolutionally encoded bits using the Viterbi Algorithm
477-
478462 Parameters
479463 ----------
480464 coded_bits : 1D ndarray
481465 Stream of convolutionally encoded bits which are to be decoded.
482-
483466 generator_matrix : 2D ndarray of ints
484467 Generator matrix G(D) of the convolutional code using which the
485468 input bits are to be decoded.
486-
487469 M : 1D ndarray of ints
488470 Number of memory elements per input of the convolutional encoder.
489-
490471 tb_length : int
491472 Traceback depth (Typically set to 5*(M+1)).
492-
493473 decoding_type : str {'hard', 'unquantized'}
494474 The type of decoding to be used.
495475 'hard' option is used for hard inputs (bits) to the decoder, e.g., BSC channel.
496476 'unquantized' option is used for soft inputs (real numbers) to the decoder, e.g., BAWGN channel.
497-
498477 Returns
499478 -------
500479 decoded_bits : 1D ndarray
501480 Decoded bit stream.
502-
503481 References
504482 ----------
505483 .. [1] Todd K. Moon. Error Correction Coding: Mathematical Methods and
0 commit comments