Several enhancements to gr-trellis and gnuradio-examples/python/channel-coding:
authoranastas <anastas@221aa14e-8319-0410-a670-987f0aec2ac5>
Wed, 16 Aug 2006 20:07:36 +0000 (20:07 +0000)
committeranastas <anastas@221aa14e-8319-0410-a670-987f0aec2ac5>
Wed, 16 Aug 2006 20:07:36 +0000 (20:07 +0000)
-Added fsm constructor for generating FSM directly from the
generator matrix of binary convolutional codes.
-Added functionality to fsm class to compute the best way to
go from any state to any other state (useful for termination)
-Added soft-in-soft-out (SISO) block for turbo processing
-Added turbo decoding examples

git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@3322 221aa14e-8319-0410-a670-987f0aec2ac5

104 files changed:
gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.cc.t
gnuradio-examples/python/channel-coding/README
gnuradio-examples/python/channel-coding/fsm_files/awgn1o2_128.fsm
gnuradio-examples/python/channel-coding/fsm_files/awgn1o2_16.fsm
gnuradio-examples/python/channel-coding/fsm_files/awgn1o2_4.fsm
gnuradio-examples/python/channel-coding/fsm_files/awgn1o2_8.fsm
gnuradio-examples/python/channel-coding/fsm_files/awgn2o3_4.fsm
gnuradio-examples/python/channel-coding/fsm_files/awgn2o3_4_1.fsm [deleted file]
gnuradio-examples/python/channel-coding/fsm_files/awgn2o3_4_msb.fsm [new file with mode: 0644]
gnuradio-examples/python/channel-coding/fsm_files/awgn2o3_4_msbG.fsm [new file with mode: 0644]
gnuradio-examples/python/channel-coding/fsm_files/awgn2o4_4.fsm
gnuradio-examples/python/channel-coding/fsm_files/disconnected.fsm [new file with mode: 0644]
gnuradio-examples/python/channel-coding/fsm_files/rep3.fsm
gnuradio-examples/python/channel-coding/fsm_files/simple.fsm [new file with mode: 0644]
gnuradio-examples/python/channel-coding/fsm_utils.py
gnuradio-examples/python/channel-coding/test_sccc_hard.py
gnuradio-examples/python/channel-coding/test_sccc_soft.py [new file with mode: 0755]
gnuradio-examples/python/channel-coding/test_sccc_turbo.py [new file with mode: 0755]
gnuradio-examples/python/channel-coding/test_tcm.py
gnuradio-examples/python/channel-coding/test_tcm1.py
gnuradio-examples/python/channel-coding/test_tcm2.py [new file with mode: 0755]
gnuradio-examples/python/channel-coding/test_tcm_combined.py
gnuradio-examples/python/channel-coding/test_tcm_parallel.py
gr-trellis/doc/gr-trellis.html [deleted file]
gr-trellis/src/lib/Makefile.am
gr-trellis/src/lib/base.cc [new file with mode: 0644]
gr-trellis/src/lib/base.h [new file with mode: 0644]
gr-trellis/src/lib/fsm.cc
gr-trellis/src/lib/fsm.h
gr-trellis/src/lib/fsm.i
gr-trellis/src/lib/interleaver.cc
gr-trellis/src/lib/interleaver.h
gr-trellis/src/lib/interleaver.i
gr-trellis/src/lib/trellis.i
gr-trellis/src/lib/trellis_calc_metric.cc
gr-trellis/src/lib/trellis_calc_metric.h
gr-trellis/src/lib/trellis_encoder_XX.cc.t
gr-trellis/src/lib/trellis_encoder_XX.h.t
gr-trellis/src/lib/trellis_encoder_XX.i.t
gr-trellis/src/lib/trellis_encoder_bb.cc
gr-trellis/src/lib/trellis_encoder_bb.h
gr-trellis/src/lib/trellis_encoder_bb.i
gr-trellis/src/lib/trellis_encoder_bi.cc
gr-trellis/src/lib/trellis_encoder_bi.h
gr-trellis/src/lib/trellis_encoder_bi.i
gr-trellis/src/lib/trellis_encoder_bs.cc
gr-trellis/src/lib/trellis_encoder_bs.h
gr-trellis/src/lib/trellis_encoder_bs.i
gr-trellis/src/lib/trellis_encoder_ii.cc
gr-trellis/src/lib/trellis_encoder_ii.h
gr-trellis/src/lib/trellis_encoder_ii.i
gr-trellis/src/lib/trellis_encoder_si.cc
gr-trellis/src/lib/trellis_encoder_si.h
gr-trellis/src/lib/trellis_encoder_si.i
gr-trellis/src/lib/trellis_encoder_ss.cc
gr-trellis/src/lib/trellis_encoder_ss.h
gr-trellis/src/lib/trellis_encoder_ss.i
gr-trellis/src/lib/trellis_metrics_X.cc.t
gr-trellis/src/lib/trellis_metrics_X.h.t
gr-trellis/src/lib/trellis_metrics_X.i.t
gr-trellis/src/lib/trellis_metrics_c.cc
gr-trellis/src/lib/trellis_metrics_c.h
gr-trellis/src/lib/trellis_metrics_c.i
gr-trellis/src/lib/trellis_metrics_f.cc
gr-trellis/src/lib/trellis_metrics_f.h
gr-trellis/src/lib/trellis_metrics_f.i
gr-trellis/src/lib/trellis_metrics_i.cc
gr-trellis/src/lib/trellis_metrics_i.h
gr-trellis/src/lib/trellis_metrics_i.i
gr-trellis/src/lib/trellis_metrics_s.cc
gr-trellis/src/lib/trellis_metrics_s.h
gr-trellis/src/lib/trellis_metrics_s.i
gr-trellis/src/lib/trellis_permutation.cc
gr-trellis/src/lib/trellis_permutation.h
gr-trellis/src/lib/trellis_permutation.i
gr-trellis/src/lib/trellis_siso_f.cc [new file with mode: 0644]
gr-trellis/src/lib/trellis_siso_f.h [new file with mode: 0644]
gr-trellis/src/lib/trellis_siso_f.i [new file with mode: 0644]
gr-trellis/src/lib/trellis_siso_f.lo [new file with mode: 0644]
gr-trellis/src/lib/trellis_siso_type.h [new file with mode: 0644]
gr-trellis/src/lib/trellis_viterbi_X.cc.t
gr-trellis/src/lib/trellis_viterbi_X.h.t
gr-trellis/src/lib/trellis_viterbi_X.i.t
gr-trellis/src/lib/trellis_viterbi_b.cc
gr-trellis/src/lib/trellis_viterbi_b.h
gr-trellis/src/lib/trellis_viterbi_b.i
gr-trellis/src/lib/trellis_viterbi_combined_X.cc.t
gr-trellis/src/lib/trellis_viterbi_combined_X.h.t
gr-trellis/src/lib/trellis_viterbi_combined_X.i.t
gr-trellis/src/lib/trellis_viterbi_combined_b.cc
gr-trellis/src/lib/trellis_viterbi_combined_b.h
gr-trellis/src/lib/trellis_viterbi_combined_b.i
gr-trellis/src/lib/trellis_viterbi_combined_i.cc
gr-trellis/src/lib/trellis_viterbi_combined_i.h
gr-trellis/src/lib/trellis_viterbi_combined_i.i
gr-trellis/src/lib/trellis_viterbi_combined_s.cc
gr-trellis/src/lib/trellis_viterbi_combined_s.h
gr-trellis/src/lib/trellis_viterbi_combined_s.i
gr-trellis/src/lib/trellis_viterbi_i.cc
gr-trellis/src/lib/trellis_viterbi_i.h
gr-trellis/src/lib/trellis_viterbi_i.i
gr-trellis/src/lib/trellis_viterbi_s.cc
gr-trellis/src/lib/trellis_viterbi_s.h
gr-trellis/src/lib/trellis_viterbi_s.i

index a488733598e8240094ef5b9d6a24f61c73fb7ea3..971311d17ca0c8d3ff833b85b5c99dfd93c25487 100644 (file)
@@ -62,7 +62,7 @@ int
 
     // per stream processing
     for (int i = 0; i < noutput_items / d_D; i++){
-      assert (((unsigned int)in[i]*d_D) < d_symbol_table.size());
+      assert (((unsigned int)in[i]*d_D+d_D) <= d_symbol_table.size());
       memcpy(out, &d_symbol_table[(unsigned int)in[i]*d_D], d_D*sizeof(@O_TYPE@));
       out+=d_D;
     }
index abfceb429677bb02ea53b6260b69911c5d847e33..2be8c6ba1f1793e3911e52d7a150dc794b49ea54 100644 (file)
@@ -8,26 +8,39 @@ fsm_files is a directory with some FSM definitions
 
 If you just want to see what these programs do, run each of the following:
 
-./test_tcm.py fsm_files/awgn1o2_4.fsm 10.0 1000
-./test_tcm1.py fsm_files/awgn1o2_4.fsm 10.0 1000
-./test_tcm_combined.py fsm_files/awgn1o2_4.fsm 10.0 1000
-./test_tcm_parallel.py fsm_files/awgn1o2_4.fsm 10.0 1000
-./test_sccc_hard.py fsm_files/awgn1o2_4.fsm fsm_files/awgn1o2_4.fsm 10.0 1000
+./test_tcm.py  fsm_files/awgn1o2_4.fsm 6.0 1000
+./test_tcm1.py fsm_files/awgn1o2_4.fsm 6.0 1000
+./test_tcm2.py 6.0 1000
+./test_tcm_combined.py fsm_files/awgn1o2_4.fsm 6.0 1000
+./test_tcm_parallel.py fsm_files/awgn1o2_4.fsm 6.0 1000
+
+./test_sccc_hard.py  fsm_files/awgn1o2_4.fsm fsm_files/awgn1o2_4_msb.fsm 10.0 100
+./test_sccc_soft.py  fsm_files/awgn1o2_4.fsm fsm_files/awgn1o2_4_msb.fsm  8.0 100
+./test_sccc_turbo.py fsm_files/awgn1o2_4.fsm fsm_files/awgn1o2_4_msb.fsm  5.0 100
 
 In your terminal you will see something like this:
 
-[anastas@ernesto channel-coding]$ ./test_tcm.py fsm_files/awgn1o2_4.fsm 6.0 1000
-100 1024 1 103424 10 9.668936e-05
-200 1024 1 205824 21 1.020289e-04
-300 1024 0 308224 40 1.297757e-04
-400 1024 0 410624 1074 2.615531e-03
-500 1024 0 513024 1081 2.107114e-03
-600 1024 0 615424 1090 1.771137e-03
-700 1024 0 717824 1097 1.528230e-03
-800 1024 0 820224 1107 1.349631e-03
-900 1024 0 922624 1120 1.213929e-03
-1024000 1129 1.102539e-03
-
-1.102539e-03 is the error rate estimates by sending 1000 packets of
-1024x16 bits each using an 1/2 4-state convolutional code and QPSK
+$ ./test_tcm.py fsm_files/awgn1o2_4.fsm 6.0 1000
+100 98 9.80e-01 102400 9 8.79e-05
+200 198 9.90e-01 204800 20 9.77e-05
+300 298 9.93e-01 307200 40 1.30e-04
+400 398 9.95e-01 409600 1074 2.62e-03
+500 498 9.96e-01 512000 1081 2.11e-03
+600 598 9.97e-01 614400 1090 1.77e-03
+700 698 9.97e-01 716800 1097 1.53e-03
+800 798 9.98e-01 819200 1107 1.35e-03
+900 898 9.98e-01 921600 1120 1.22e-03
+1000 998 9.98e-01 1024000 1129 1.10e-03
+1000 998 9.98e-01 1024000 1129 1.10e-03
+
+which gives you information about the:
+number of transmitted packets
+number of packets in error
+iestimated packet error rate
+number of transmitted shorts
+number of shorts in error
+estimated (short) error rate 
+
+1.10e-03 is the error rate estimate by sending 1000 packets of
+1024 shorts each, using an 1/2 4-state convolutional code and QPSK
 modulation through an AWGN with Es/N0 = 6.0 dB
index 9c14d82f3ccea806f3b111238b7383ac2581cf6d..bb79c59da45f83d2d9f40ad2babdd795e48b3cce 100644 (file)
 
 
 
-GM1o2_128=[1+D^3+D^4+D^5+D^6+D^7   1+D+D^2+D^5+D^7]
-         =[249 167]
+GM1o2_128=[1+D+D^2+D^5+D^7     1+D^3+D^4+D^5+D^6+D^7]
+         =[11100101            10011111]
+         =[229                 159]
index 2b000da691265c91450ed1f9ca5e80437544681c..cdab41359eb09883cfa85388227be2e65206fa88 100644 (file)
@@ -36,4 +36,4 @@
 
 
 
-GM1o2_16=[1+D^2+D^3+D^4   1+D+D^4];
+GM1o2_16=[1+D+D^4  1+D^2+D^3+D^4 ] = [25,23] (decimal)
index 33e5ee315aec14b90a9ef96da1fb32e4d1ab3d31..fb316b5ef8b29509226b4c8553c7268b1140fb8f 100644 (file)
@@ -11,7 +11,4 @@
 2 1
 
 AWGN CC from Proakis-Salehi pg 779
-GM1o2_4=[1+D+D^2   1+D^2];
-
-
-
+GM1o2_4=[1+D^2, 1+D+D^2] = [5, 7] (in decimal);
index dd63b1ef50ce8aa985ce19c746cdb0153f07caf3..604bac6c2c5b14ba930356ece04accb2a10d9439 100644 (file)
@@ -21,4 +21,4 @@
 
 
 1/2 8-state code (Proakis pg. 493)
-GM1o2_8=[ 1+D+D^2+D^3   1+D+D^3];
+GM1o2_8=[ 1+D+D^3   1+D+D^2+D^3] =[13 , 15] (decimal)
index 567948e784779c8e8465561f985324e89def4ca3..3ac57be18d77dc421f63844e6d8a4578e8533952 100644 (file)
@@ -1,44 +1,15 @@
 4 4 8
 
-0      2       1       3
-0      2       1       3
-0      2       1       3
-0      2       1       3
-
-0 3 5 6
-4 7 1 2
-7 4 2 1
-3 0 6 5 
-
-
-This is generated by the 1/2 AWGN code (5 7) by puncturing the first (MSB) bit.
---> d_free=3
-
-before puncturing:
-
-00 03 31 32
-30 33 01 02
-13 10 22 21
-23 20 12 11
-
-or in decimal representation:
-
- 0  3 13 14
-12 15  1  2
- 7  4 10  9
-11  8  6  5
-
-by punturing the MSB you get (dmin=3)
-
-0 3 5 6
-4 7 1 2
-7 4 2 1
-3 0 6 5 
-
-and by puncturing the LSB (something is wrong with this code)
-
-0      1       6       7
-6      7       0       1
-3      2       5       4
-5      4       3       2
-
+0       1       2       3
+0       1       2       3
+0       1       2       3
+0       1       2       3
+
+0       7       4       3
+3       4       7       0
+5       2       1       6
+6       1       2       5
+
+I don't remeber how I generated this one...
+it is a bit better than awgn2o3_4_msb and worse
+than awgn2o3_4_msbG.
diff --git a/gnuradio-examples/python/channel-coding/fsm_files/awgn2o3_4_1.fsm b/gnuradio-examples/python/channel-coding/fsm_files/awgn2o3_4_1.fsm
deleted file mode 100644 (file)
index c5aee69..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-4 4 8
-
-0       1       2       3
-0       1       2       3
-0       1       2       3
-0       1       2       3
-
-0       7       4       3
-3       4       7       0
-5       2       1       6
-6       1       2       5
-
-
-
-This is generated by the 1/2 AWGN code (5 7) by puncturing the first (MSB) bit.
---> d_free=3
-
-before puncturing:
-
-
-or in decimal representation:
-
-0       7       12      11
-3       4       15      8
-13      10      1       6
-14      9       2       5
-
-by punturing the MSB you get (dmin=3)
-
-0       7       4       3
-3       4       7       0
-5       2       1       6
-6       1       2       5
-
-
-and by puncturing the LSB (something is wrong with this code)
-
-0       3       6       5
-1       2       7       4
-6       5       0       3
-7       4       1       2
-
diff --git a/gnuradio-examples/python/channel-coding/fsm_files/awgn2o3_4_msb.fsm b/gnuradio-examples/python/channel-coding/fsm_files/awgn2o3_4_msb.fsm
new file mode 100644 (file)
index 0000000..551b711
--- /dev/null
@@ -0,0 +1,46 @@
+4 4 8
+
+0      1       2       3
+0      1       2       3
+0      1       2       3
+0      1       2       3
+
+0      5       3       6
+4      1       7       2
+7      2       4       1
+3      6       0       5 
+
+
+This is generated by the 1/2 AWGN code (5 7) operated twice, ie,
+(xk+1 xki) [xk-1 xk-2] -> [xk+1 xki].
+We also puncture the first (MSB) bit.
+This code is worse than awgn2o3_4_msbG and slightly worse than
+awgn2o3_4, BUT seems to be a good innner code for sctcm (with 8PSK natural).
+
+intermediate states:
+
+00 21 02 23
+00 21 02 23
+10 31 12 33
+10 31 12 33
+
+output before puncturing:
+
+00 31 03 32
+30 01 33 02
+13 22 10 21
+23 12 20 11
+
+output after punturing the MSB:
+
+00 11 03 12
+10 01 13 02
+13 02 10 01
+03 12 00 11
+
+and in decimal:
+
+0 5 3 6
+4 1 7 2
+7 2 4 1
+3 6 0 5
diff --git a/gnuradio-examples/python/channel-coding/fsm_files/awgn2o3_4_msbG.fsm b/gnuradio-examples/python/channel-coding/fsm_files/awgn2o3_4_msbG.fsm
new file mode 100644 (file)
index 0000000..8956c53
--- /dev/null
@@ -0,0 +1,60 @@
+4 4 8
+
+0      1       2       3
+0      1       2       3
+0      1       2       3
+0      1       2       3
+
+0      4       2       6
+5      1       3       7
+3      7       5       1
+
+
+This is generated by the 1/2 AWGN code (5 7) operated twice, ie,
+(xk+1 xki) [xk-1 xk-2] -> [xk+1 xki].
+We also puncture the first (MSB) bit and Gray map the symbols.
+
+intermediate states:
+
+00 21 02 23
+00 21 02 23
+10 31 12 33
+10 31 12 33
+
+output before puncturing:
+
+00 31 03 32
+30 01 33 02
+13 22 10 21
+23 12 20 11
+
+output after punturing the MSB:
+
+00 11 03 12
+10 01 13 02
+13 02 10 01
+03 12 00 11
+
+and in decimal:
+
+0 5 3 6
+4 1 7 2
+7 2 4 1
+3 6 0 5
+
+After Gray mapping:
+label -> phase
+0 -> 0
+1 -> 0
+2 -> 7
+3 -> 2
+4 -> 5
+5 -> 4
+6 -> 6
+7 -> 3
+
+0 4 2 6
+5 1 3 7
+3 7 5 1
+2 6 0 4
+
index 793d419c5981fb80bed65583b77e8b25f9225547..a895be8965f97b0374899ecb269ace947867d235 100644 (file)
@@ -1,14 +1,36 @@
-4 4 16 
+4 4 16
 
-0   2   1   3
-0   2   1   3
-0   2   1   3
-0   2   1   3
+0      1       2       3
+0      1       2       3
+0      1       2       3
+0      1       2       3
 
- 0  3 13 14
-12 15  1  2
- 7  4 10  9
-11  8  6  5
+ 0     13       3      14
+12      1      15       2
+ 7     10       4       9
+11      6       8       5
 
-generated by the awgn1o2_4.fsm code
-(two steps of the 1o2 code)
+
+This is generated by the 1/2 AWGN code (5 7) operated twice, ie,
+(xk+1 xki) [xk-1 xk-2] -> [xk+1 xki].
+
+intermediate states:
+
+00 21 02 23
+00 21 02 23
+10 31 12 33
+10 31 12 33
+
+output:
+
+00 31 03 32
+30 01 33 02
+13 22 10 21
+23 12 20 11
+
+and in decimal:
+
+ 0 13  3 14
+12  1 15  2
+ 7 10  4  9
+11  6  8  5
diff --git a/gnuradio-examples/python/channel-coding/fsm_files/disconnected.fsm b/gnuradio-examples/python/channel-coding/fsm_files/disconnected.fsm
new file mode 100644 (file)
index 0000000..847963e
--- /dev/null
@@ -0,0 +1,11 @@
+1 4 1
+
+1
+0
+3
+2
+
+0
+0
+0
+0
index 1930523b3fde21196c6bb6736d9f0dcfde1eafdc..ef1bd1f02583095a5680f5c9ef8bb615d91351b5 100644 (file)
@@ -4,4 +4,5 @@
 
 0 7
 
-1/3 repetition code (with binary input)
+1/3 repetition code (with binary input).
+There is only one state, since this is essentially a memoryless system.
diff --git a/gnuradio-examples/python/channel-coding/fsm_files/simple.fsm b/gnuradio-examples/python/channel-coding/fsm_files/simple.fsm
new file mode 100644 (file)
index 0000000..07fb085
--- /dev/null
@@ -0,0 +1,13 @@
+1 4 1
+
+1
+2
+3
+0
+
+0
+0
+0
+0
+
+essentially this fsm has no inputs and no outputs; it ijust cycles through all 4 states.
index dc5ee79f1aad6ac5a73cda6c77c342953beaef01..fe9f4f3b85e0529e172b6eb8527fd7d78422780b 100755 (executable)
@@ -60,101 +60,6 @@ def base2dec(s,base):
 
 
 
-
-
-######################################################################
-# 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
index a869e91e1023b80735fcef49aac2b3bb7348a01b..d634282fe75ae5857521644ff26b89aee74dc02e 100755 (executable)
@@ -18,7 +18,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,
     src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
     s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
     enc_out = trellis.encoder_ss(fo,0) # initial state = 0
-    inter = trellis.permutation(interleaver.K(),interleaver.INTER(),gr.sizeof_short)
+    inter = trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
     enc_in = trellis.encoder_ss(fi,0) # initial state = 0
     mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
 
@@ -29,7 +29,7 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,
     # RX
     metrics_in = trellis.metrics_f(fi.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner Viterbi
     va_in = trellis.viterbi_s(fi,K,0,-1) # Put -1 if the Initial/Final states are not set.
-    deinter = trellis.permutation(interleaver.K(),interleaver.DEINTER(),gr.sizeof_short)
+    deinter = trellis.permutation(interleaver.K(),interleaver.DEINTER(),1,gr.sizeof_short)
     metrics_out = trellis.metrics_s(fo.O(),1,[0,1,2,3],trellis.TRELLIS_HARD_SYMBOL) # data preprocessing to generate metrics for outer Viterbi (hard decisions)
     va_out = trellis.viterbi_s(fo,K,0,-1) # Put -1 if the Initial/Final states are not set.
     fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
@@ -85,14 +85,16 @@ def main(args):
     
     tot_s=0 # total number of transmitted shorts
     terr_s=0 # total number of shorts in error
+    terr_p=0 # total number of packets in error
     for i in range(rep):
         (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
         tot_s=tot_s+s
         terr_s=terr_s+e
-        if (i%100==0) & (i>0): # display progress
-            print i,s,e,tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
+        terr_p=terr_p+(terr_s!=0)
+        if ((i+1)%100==0) : # display progress
+            print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
     # estimate of the (short or bit) error rate
-    print tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
+    print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
 
 
 if __name__ == '__main__':
diff --git a/gnuradio-examples/python/channel-coding/test_sccc_soft.py b/gnuradio-examples/python/channel-coding/test_sccc_soft.py
new file mode 100755 (executable)
index 0000000..23e6553
--- /dev/null
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio import trellis
+from gnuradio import eng_notation
+import math
+import sys
+import random
+import fsm_utils
+
+
+
+
+def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
+    fg = gr.flow_graph ()
+
+
+    # TX
+    src = gr.lfsr_32k_source_s()
+    src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
+    s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
+    enc_out = trellis.encoder_ss(fo,0) # initial state = 0
+    inter = trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
+    enc_in = trellis.encoder_ss(fi,0) # initial state = 0
+    mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+
+    # CHANNEL
+    add = gr.add_ff()
+    noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
+
+    # RX
+    metrics_in = trellis.metrics_f(fi.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner Viterbi
+    gnd = gr.vector_source_f([0],True);
+    siso_in = trellis.siso_f(fi,K,0,-1,True,False,trellis.TRELLIS_MIN_SUM) # Put -1 if the Initial/Final states are not set.
+    deinter = trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float)
+    va_out = trellis.viterbi_s(fo,K,0,-1) # Put -1 if the Initial/Final states are not set.
+    fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
+    dst = gr.check_lfsr_32k_s()
+    
+    fg.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
+    fg.connect (mod,(add,0))
+    fg.connect (noise,(add,1))
+    fg.connect (add,metrics_in)
+    fg.connect (gnd,(siso_in,0))
+    fg.connect (metrics_in,(siso_in,1))
+    fg.connect (siso_in,deinter,va_out,fsmi2s,dst)
+
+    fg.run()
+    
+    ntotal = dst.ntotal ()
+    nright = dst.nright ()
+    runlength = dst.runlength ()
+    return (ntotal,ntotal-nright)
+
+
+def main(args):
+    nargs = len (args)
+    if nargs == 4:
+        fname_out=args[0]
+        fname_in=args[1]
+        esn0_db=float(args[2]) # Es/No in dB
+        rep=int(args[3]) # number of times the experiment is run to collect enough errors
+    else:
+        sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db  repetitions\n')
+        sys.exit (1)
+
+    # system parameters
+    Kb=1024*16  # packet size in bits (make it multiple of 16 so it can be packed in a short)
+    fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
+    fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
+    bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
+    if fo.O() != fi.I():
+        sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
+        sys.exit (1)
+    K=Kb/bitspersymbol # packet size in trellis steps
+    interleaver=trellis.interleaver(K,666) # construct a random interleaver
+    modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
+    dimensionality = modulation[0]
+    constellation = modulation[1] 
+    if len(constellation)/dimensionality != fi.O():
+        sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
+        sys.exit (1)
+    # calculate average symbol energy
+    Es = 0
+    for i in range(len(constellation)):
+        Es = Es + constellation[i]**2
+    Es = Es / (len(constellation)/dimensionality)
+    N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
+
+
+    tot_s=0 # total number of transmitted shorts
+    terr_s=0 # total number of shorts in error
+    terr_p=0 # total number of packets in error
+    for i in range(rep):
+        (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
+        tot_s=tot_s+s
+        terr_s=terr_s+e
+        terr_p=terr_p+(terr_s!=0)
+        if ((i+1)%100==0) : # display progress
+            print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+    # estimate of the (short or bit) error rate
+    print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+    
+
+
+if __name__ == '__main__':
+    main (sys.argv[1:])
diff --git a/gnuradio-examples/python/channel-coding/test_sccc_turbo.py b/gnuradio-examples/python/channel-coding/test_sccc_turbo.py
new file mode 100755 (executable)
index 0000000..cdd1ad8
--- /dev/null
@@ -0,0 +1,139 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio import trellis
+from gnuradio import eng_notation
+import math
+import sys
+import random
+import fsm_utils
+
+
+
+def make_rx(fg,fo,fi,dimensionality,constellation,K,interleaver,IT,Es,N0,type):
+    metrics_in = trellis.metrics_f(fi.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner Viterbi
+    scale = gr.multiply_const_ff(1.0/N0)
+    gnd = gr.vector_source_f([0],True);
+
+    inter=[]
+    deinter=[]
+    siso_in=[]
+    siso_out=[]
+
+    for it in range(IT-1):
+      inter.append( trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) )
+      siso_in.append( trellis.siso_f(fi,K,0,3,True,False,type) )
+      deinter.append( trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float) )
+      siso_out.append( trellis.siso_f(fo,K,0,3,False,True,type) )
+      fg.connect (inter[it],(siso_in[it],0))
+      fg.connect (gnd,(siso_out[it],0))
+      fg.connect (siso_in[it],deinter[it],(siso_out[it],1))
+
+    inter.append( trellis.permutation(interleaver.K(),interleaver.INTER(),fi.I(),gr.sizeof_float) )
+    siso_in.append( trellis.siso_f(fi,K,0,-1,True,False,type) )
+    deinter.append( trellis.permutation(interleaver.K(),interleaver.DEINTER(),fi.I(),gr.sizeof_float) )
+    siso_out.append( trellis.viterbi_s(fo,K,0,-1) )
+    fg.connect (inter[IT-1],(siso_in[IT-1],0))
+    fg.connect (siso_in[IT-1],deinter[IT-1],siso_out[IT-1])
+
+    # connect first stage
+    fg.connect (gnd,inter[0])
+    fg.connect (metrics_in,scale)
+    fg.connect (scale,(siso_in[0],1))
+    for it in range(IT-1):
+      fg.connect (siso_out[it],inter[it+1])
+      fg.connect (metrics_in,(siso_in[it+1],1))
+    return (metrics_in,siso_out[IT-1])
+
+
+def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed):
+    fg = gr.flow_graph ()
+
+
+    # TX
+    src = gr.lfsr_32k_source_s()
+    src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
+    s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
+    enc_out = trellis.encoder_ss(fo,0) # initial state = 0
+    inter = trellis.permutation(interleaver.K(),interleaver.INTER(),1,gr.sizeof_short)
+    enc_in = trellis.encoder_ss(fi,0) # initial state = 0
+    mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+
+    # CHANNEL
+    add = gr.add_ff()
+    noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
+
+    # RX
+    (head,tail) = make_rx(fg,fo,fi,dimensionality,constellation,K,interleaver,IT,Es,N0,trellis.TRELLIS_MIN_SUM)
+    #(head,tail) = make_rx(fg,fo,fi,dimensionality,constellation,K,interleaver,IT,Es,N0,trellis.TRELLIS_SUM_PRODUCT)
+    fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
+    dst = gr.check_lfsr_32k_s()
+    
+    fg.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
+    fg.connect (mod,(add,0))
+    fg.connect (noise,(add,1))
+    fg.connect (add,head)
+    fg.connect (tail,fsmi2s,dst)
+
+    fg.run()
+    #print enc_out.ST(), enc_in.ST()
+    
+    ntotal = dst.ntotal ()
+    nright = dst.nright ()
+    runlength = dst.runlength ()
+    return (ntotal,ntotal-nright)
+
+
+def main(args):
+    nargs = len (args)
+    if nargs == 4:
+        fname_out=args[0]
+        fname_in=args[1]
+        esn0_db=float(args[2]) # Es/No in dB
+        rep=int(args[3]) # number of times the experiment is run to collect enough errors
+    else:
+        sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db  repetitions\n')
+        sys.exit (1)
+
+    # system parameters
+    Kb=1024*16  # packet size in bits (make it multiple of 16 so it can be packed in a short)
+    fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
+    fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
+    bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
+    if fo.O() != fi.I():
+        sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
+        sys.exit (1)
+    K=Kb/bitspersymbol # packet size in trellis steps
+    interleaver=trellis.interleaver(K,666) # construct a random interleaver
+    modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
+    dimensionality = modulation[0]
+    constellation = modulation[1] 
+    if len(constellation)/dimensionality != fi.O():
+        sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
+        sys.exit (1)
+    # calculate average symbol energy
+    Es = 0
+    for i in range(len(constellation)):
+        Es = Es + constellation[i]**2
+    Es = Es / (len(constellation)/dimensionality)
+    N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
+    IT = 3 # number of turbo iterations
+    
+    tot_s=0 # total number of transmitted shorts
+    terr_s=0 # total number of shorts in error
+    terr_p=0 # total number of packets in error
+    for i in range(rep):
+        (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
+        tot_s=tot_s+s
+        terr_s=terr_s+e
+        terr_p=terr_p+(terr_s!=0)
+        if ((i+1)%10==0): # display progress
+            print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+    # estimate of the (short or bit) error rate
+    print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+
+
+if __name__ == '__main__':
+    main (sys.argv[1:])
index 1f892ef996b0da94e2a70c817837a993f1362ede..f2250155800509bef4825a492dbb9db8fea114be 100755 (executable)
@@ -101,14 +101,17 @@ def main(args):
     
     tot_s=0 # total number of transmitted shorts
     terr_s=0 # total number of shorts in error
+    terr_p=0 # total number of packets in error
     for i in range(rep):
         (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
         tot_s=tot_s+s
         terr_s=terr_s+e
-        if (i%100==0) & (i>0): # display progress
-            print i,s,e,tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
+        terr_p=terr_p+(terr_s!=0)
+        if ((i+1)%100==0) : # display progress
+            print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
     # estimate of the (short or bit) error rate
-    print tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
+    print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+
 
 
 if __name__ == '__main__':
index e4f88d0b5c5593984f4ce160e616901b1b979b92..66d7131e38272b6be2062fac3ed313d9da9a04fc 100755 (executable)
@@ -102,17 +102,19 @@ def main(args):
     Es = Es / (len(constellation)/dimensionality)
     N0=Es/pow(10.0,esn0_db/10.0); # noise variance
     
-
-    tot_s=0
-    terr_s=0
+    tot_s=0 # total number of transmitted shorts
+    terr_s=0 # total number of shorts in error
+    terr_p=0 # total number of packets in error
     for i in range(rep):
         (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
         tot_s=tot_s+s
         terr_s=terr_s+e
-        if (i%1==0) & (i>0):
-            print i,s,e,tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
+        terr_p=terr_p+(terr_s!=0)
+        if ((i+1)%1==0) : # display progress
+            print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
     # estimate of the (short or bit) error rate
-    print tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
+    print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+
 
 
 if __name__ == '__main__':
diff --git a/gnuradio-examples/python/channel-coding/test_tcm2.py b/gnuradio-examples/python/channel-coding/test_tcm2.py
new file mode 100755 (executable)
index 0000000..9680909
--- /dev/null
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio import trellis
+from gnuradio import eng_notation
+import math
+import sys
+import random
+import fsm_utils
+
+def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
+    fg = gr.flow_graph ()
+
+
+    # TX
+    #packet = [0]*Kb
+    #for i in range(Kb-1*16): # last 16 bits = 0 to drive the final state to 0
+        #packet[i] = random.randint(0, 1) # random 0s and 1s
+    #src = gr.vector_source_s(packet,False)
+    src = gr.lfsr_32k_source_s()
+    src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
+    #b2s = gr.unpacked_to_packed_ss(1,gr.GR_MSB_FIRST) # pack bits in shorts
+    s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
+    enc = trellis.encoder_ss(f,0) # initial state = 0
+    mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+
+    # CHANNEL
+    add = gr.add_ff()
+    noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
+
+    # RX
+    metrics = trellis.metrics_f(f.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
+    va = trellis.viterbi_s(f,K,0,-1) # Put -1 if the Initial/Final states are not set.
+    fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
+    #s2b = gr.packed_to_unpacked_ss(1,gr.GR_MSB_FIRST) # unpack shorts to bits
+    #dst = gr.vector_sink_s(); 
+    dst = gr.check_lfsr_32k_s()
+    
+
+    fg.connect (src,src_head,s2fsmi,enc,mod)
+    #fg.connect (src,b2s,s2fsmi,enc,mod)
+    fg.connect (mod,(add,0))
+    fg.connect (noise,(add,1))
+    fg.connect (add,metrics)
+    fg.connect (metrics,va,fsmi2s,dst)
+    #fg.connect (metrics,va,fsmi2s,s2b,dst)
+    
+
+    fg.run()
+    
+    # A bit of cheating: run the program once and print the 
+    # final encoder state..
+    # Then put it as the last argument in the viterbi block
+    #print "final state = " , enc.ST()
+
+    ntotal = dst.ntotal ()
+    nright = dst.nright ()
+    runlength = dst.runlength ()
+    #ntotal = len(packet)
+    #if len(dst.data()) != ntotal:
+        #print "Error: not enough data\n"
+    #nright = 0;
+    #for i in range(ntotal):
+        #if packet[i]==dst.data()[i]:
+            #nright=nright+1
+        #else:
+            #print "Error in ", i
+    return (ntotal,ntotal-nright)
+
+
+
+
+def main(args):
+    nargs = len (args)
+    if nargs == 2:
+        esn0_db=float(args[0]) # Es/No in dB
+        rep=int(args[1]) # number of times the experiment is run to collect enough errors
+    else:
+        sys.stderr.write ('usage: test_tcm2.py Es/No_db  repetitions\n')
+        sys.exit (1)
+
+    # system parameters
+    f=trellis.fsm(1,2,[5,7]) # generate FSM specification from the generator matrix
+    Kb=1024*16  # packet size in bits (make it multiple of 16 so it can be packed in a short)
+    bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
+    K=Kb/bitspersymbol # packet size in trellis steps
+    modulation = fsm_utils.psk4 # see fsm_utlis.py for available predefined modulations
+    dimensionality = modulation[0]
+    constellation = modulation[1] 
+    if len(constellation)/dimensionality != f.O():
+        sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
+        sys.exit (1)
+    # calculate average symbol energy
+    Es = 0
+    for i in range(len(constellation)):
+        Es = Es + constellation[i]**2
+    Es = Es / (len(constellation)/dimensionality)
+    N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
+    
+    tot_s=0 # total number of transmitted shorts
+    terr_s=0 # total number of shorts in error
+    terr_p=0 # total number of packets in error
+    for i in range(rep):
+        (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
+        tot_s=tot_s+s
+        terr_s=terr_s+e
+        terr_p=terr_p+(terr_s!=0)
+        if ((i+1)%100==0) : # display progress
+            print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+    # estimate of the (short or bit) error rate
+    print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+
+
+if __name__ == '__main__':
+    main (sys.argv[1:])
index ce08631831e1a649ded73ce5e5c41ee072191533..37f38ef1a1a803db419df4ba2cc2aeb32d7c22c6 100755 (executable)
@@ -80,17 +80,19 @@ def main(args):
     Es = Es / (len(constellation)/dimensionality)
     N0=Es/pow(10.0,esn0_db/10.0); # noise variance
 
-
-    tot_s=0
-    terr_s=0
+    tot_s=0 # total number of transmitted shorts
+    terr_s=0 # total number of shorts in error
+    terr_p=0 # total number of packets in error
     for i in range(rep):
         (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
         tot_s=tot_s+s
         terr_s=terr_s+e
-        if (i%100==0) & (i>0):
-            print i,s,e,tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
-    # estimate of the (short) error rate
-    print tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
+        terr_p=terr_p+(terr_s!=0)
+        if ((i+1)%100==0) : # display progress
+            print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+    # estimate of the (short or bit) error rate
+    print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+
 
 
 if __name__ == '__main__':
index 230bf4b9842f8a2ab91846d8f4eca9b11d9f7e15..f9dcb5852607306520c10cabe11e0b97923f9e87 100755 (executable)
@@ -15,7 +15,7 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed,P):
     src = gr.lfsr_32k_source_s()
     src_head = gr.head (gr.sizeof_short,Kb/16*P) # packet size in shorts
     s2fsmi=gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
-    s2p = gr.stream_to_streams(2,P) # serial to parallel
+    s2p = gr.stream_to_streams(gr.sizeof_short,P) # serial to parallel
     enc = trellis.encoder_ss(f,0) # initiali state = 0
     mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
 
@@ -26,11 +26,10 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed,P):
         add.append(gr.add_ff())
         noise.append(gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed))
 
-    
     # RX
     metrics = trellis.metrics_f(f.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
     va = trellis.viterbi_s(f,K,0,-1) # Put -1 if the Initial/Final states are not set.
-    p2s = gr.streams_to_stream(2,P) # parallel to serial
+    p2s = gr.streams_to_stream(gr.sizeof_short,P) # parallel to serial
     fsmi2s=gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
     dst = gr.check_lfsr_32k_s()
 
@@ -90,14 +89,16 @@ def main(args):
 
     tot_s=0 # total number of transmitted shorts
     terr_s=0 # total number of shorts in error
+    terr_p=0 # total number of packets in error
     for i in range(rep):
         (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i),P) # run experiment with different seed to get different noise realizations
         tot_s=tot_s+s
         terr_s=terr_s+e
-        if (i%10==0) & (i>0): # display progress
-            print i,s,e,tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
+        terr_p=terr_p+(terr_s!=0)
+        if ((i+1)%100==0) : # display progress
+            print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
     # estimate of the (short or bit) error rate
-    print tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
+    print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
 
 
 if __name__ == '__main__':
diff --git a/gr-trellis/doc/gr-trellis.html b/gr-trellis/doc/gr-trellis.html
deleted file mode 100644 (file)
index 82d9237..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Trellis-based algorithms for GNU Radio</title><meta name="generator" content="DocBook XSL Stylesheets V1.65.1"><meta name="description" content="This document provides a description of the 
-Finite State Machine (FSM) implementation and the related 
-trellis-based encoding and decoding algorithms
-for GNU Radio.
-"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article" lang="en"><div class="titlepage"><div><div><h1 class="title"><a name="id2753996"></a>Trellis-based algorithms for GNU Radio</h1></div><div><div class="author"><h3 class="author"><span class="firstname">Achilleas</span> <span class="surname">Anastasopoulos</span></h3><div class="affiliation"><div class="address"><p><br>
-           <tt class="email">&lt;<a href="mailto:anastas@umich.edu">anastas@umich.edu</a>&gt;</tt><br>
-        </p></div></div></div></div><div><div class="revhistory"><table border="1" width="100%" summary="Revision history"><tr><th align="left" valign="top" colspan="2"><b>Revision History</b></th></tr><tr><td align="left">Revision v0.0</td><td align="left">2006-08-03</td></tr><tr><td align="left" colspan="2">
-    First cut.
-  </td></tr></table></div></div><div><div class="abstract"><p class="title"><b>Abstract</b></p><p>This document provides a description of the 
-Finite State Machine (FSM) implementation and the related 
-trellis-based encoding and decoding algorithms
-for GNU Radio.
-</p></div></div></div><div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="#intro">Introduction</a></span></dt><dt><span class="sect1"><a href="#fsm">The FSM class</a></span></dt><dt><span class="sect1"><a href="#tcm">TCM: A Complete Example</a></span></dt><dt><span class="sect1"><a href="#future">Future Work</a></span></dt></dl></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="intro"></a>Introduction</h2></div></div><div></div></div><p>....</p><p>
-The basic goal of the implementation is to have a generic way of 
-describing an FSM that is decoupled from whether it describes a 
-convolutional 
-code (CC), a trellis code (TC), an inter-symbol interference (ISI) 
-channel, or any
-other communication system that can be modeled with an FSM.
-To achieve this goal, we need to separate the pure FSM descrition from the
-rest of the model details. For instance, in the case of a rate 2/3 TC, 
-the FSM should not involve details about the modulation used (it can
-be an 8-ary PAM, or 8-PSK, etc). Similarly, when attempting maximum likelihood
-sequence detection (MLSD)--using for instance the Viterbi algorithm (VA)--
-the VA implementation should not be concerned with the channel details
-(such as modulations, channel type, hard or soft inputs, etc).
-Clearly, having generality as the primary goal implies some penalty
-on the code efficiency, as compared to fully custom implementations. 
-</p><p>
-We will now describe the implementation of the basic ingedient, the FSM.
-</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="fsm"></a>The FSM class</h2></div></div><div></div></div><p>An FSM describes the evolution of a system with inputs
-x<sub>k</sub>, states s<sub>k</sub> and outputs y<sub>k</sub>. At time k the FSM state is s<sub>k</sub>. 
-Upon reception of a new input symbol x<sub>k</sub>, it outputs an output symbol
-y<sub>k</sub> which is a function of both x<sub>k</sub> and s<sub>k</sub>.  
-It will then move to a next state s<sub>k+1</sub>.
-An FSM has a finite number of states, input and output symbols. 
-All these are formally described as follows:
-</p><div class="itemizedlist"><ul type="disc"><li><p>The input alphabet A<sub>I</sub>={0,1,2,...,I-1}, with cardinality I, so that x<sub>k</sub> takes values in A<sub>I</sub>.</p></li><li><p>The state alphabet A<sub>S</sub>={0,1,2,...,S-1}, with cardinality S, so that s<sub>k</sub> takes values in A<sub>S</sub>.</p></li><li><p>The output alphabet A<sub>O</sub>={0,1,2,...,O-1}, with cardinality O, so that y<sub>k</sub> takes values in A<sub>O</sub></p></li><li><p>The "next-state" function NS: A<sub>S</sub> x A<sub>I</sub> --&gt; A<sub>S</sub>, 
-with the meaning 
-s<sub>k+1</sub> = NS(s<sub>k</sub>, x<sub>k</sub>)</p></li><li><p>The "output-symbol" function OS: A<sub>S</sub> x A<sub>I</sub> --&gt; A<sub>S</sub>, 
-with the meaning 
-y<sub>k</sub> = OS(s<sub>k</sub>, x<sub>k</sub>)</p></li></ul></div><p>
-Thus, a complete description of the FSM is given by the 
-the five-tuple (I,S,O,NS,OS).
-Observe that implementation details are hidden 
-in how the outside world interprets these input and output 
-integer symbols.
-Here is an example of an FSM describing the (2,1) CC
-with constraint length 3 and generator polynomial matrix
-(1+D+D<sup>2</sup> ,  1+D<sup>2</sup>)
-from Proakis-Salehi pg. 779.
-</p><div class="example"><a name="cc_ex"></a><p class="title"><b>Example 1. (2,1) CC with generator polynomials (1+D+D<sup>2</sup> , 1+D<sup>2</sup>)</b></p><p>
-This CC accepts 1 bit at a time, and outputs 2 bits at a time.
-It has a shift register storing the last two input bits.
-In particular, 
-b<sub>k</sub>(0)=x<sub>k</sub>+
-x<sub>k-1</sub>+x<sub>k-2</sub>, and
-b<sub>k</sub>(1)=x<sub>k</sub>+
-x<sub>k-2</sub>, where addition is mod-2. 
-We can represent the state of this system
-as s<sub>k</sub> = (x<sub>k-1</sub> x<sub>k-2</sub>)<sub>10</sub>. In addition we can represent its
-output symbol as y<sub>k</sub> = (b<sub>k</sub>(1) b<sub>k</sub>(0))<sub>10</sub>. 
-Based on the above assumptions, the input alphabet A<sub>I</sub>={0,1}, so I=2; 
-the state alphabet A<sub>S</sub>={0,1,2,3}, so S=4; and
-the output alphabet A<sub>O</sub>={0,1,2,3}, so O=4.
-The "next-state" function NS(,) is given by
-</p><pre class="programlisting">
-s<sub>k</sub>  x<sub>k</sub>   s<sub>k+1</sub>
-0      0       0
-0      1       2
-1      0       0
-1      1       2
-2      0       1
-2      1       3
-3      0       1
-3      1       3
-</pre><p>
-The "output-symbol" function OS(,) can be given by
-</p><pre class="programlisting">
-s<sub>k</sub>  x<sub>k</sub>   y<sub>k</sub>
-0      0       0
-0      1       3
-1      0       3
-1      1       0
-2      0       1
-2      1       2
-3      0       2
-3      1       1
-</pre><p>
-</p><p>
-Note that although the CC outputs 2 bits per time period, following 
-our approach, there is only one (quaternary) output symbol per 
-time period (for instance, here we use the decimal representation 
-of the 2-bits). Also note that the modulation used is not part of 
-the FSM description: it can be BPSK, OOK, BFSK, QPSK with or without Gray mapping, etc; 
-it is up to the rest of the program to interpret the meaning of 
-the symbol y<sub>k</sub>.
-</p></div><p>
-The C++ implementation of the FSM class keeps private information about
-I,S,O,NS,OS and public methods to read and write them. The NS
-and OS matrices are implemented as STL 1-dimensional vectors.
-</p><pre class="programlisting">
-class fsm {
-private:
-  int d_I;
-  int d_S;
-  int d_O;
-  std::vector&lt;int&gt; d_NS;
-  std::vector&lt;int&gt; d_OS;
-  std::vector&lt;int&gt; d_PS;
-  std::vector&lt;int&gt; d_PI;
-public:
-  fsm();
-  fsm(const fsm &amp;FSM);
-  fsm(const int I, const int S, const int O, const std::vector&lt;int&gt; &amp;NS, const std::vector&lt;int&gt; &amp;OS);
-  fsm(const char *name);
-  fsm(const int mod_size, const int ch_length);
-  int I () const { return d_I; }
-  int S () const { return d_S; }
-  int O () const { return d_O; }
-  const std::vector&lt;int&gt; &amp; NS () const { return d_NS; }
-  const std::vector&lt;int&gt; &amp; OS () const { return d_OS; }
-  const std::vector&lt;int&gt; &amp; PS () const { return d_PS; }
-  const std::vector&lt;int&gt; &amp; PI () const { return d_PI; }
-};
-</pre><p>
-As can be seen, other than the trivial and the copy constructor, 
-there are three additional
-ways to construct an FSM. 
-</p><div class="itemizedlist"><ul type="disc"><li><p>Supplying the parameters I,S,O,NS,OS:</p><pre class="programlisting">
-  fsm(const int I, const int S, const int O, const std::vector&lt;int&gt; &amp;NS, const std::vector&lt;int&gt; &amp;OS);
-</pre></li><li><p>Giving a filename containing all the FSM information:</p><pre class="programlisting">
-  fsm(const char *name);
-</pre><p>
-This information has to be in the following format:
-</p><pre class="programlisting">
-I S O
-
-NS(0,0)   NS(0,1)   ...  NS(0,I-1)
-NS(1,0)   NS(1,1)   ...  NS(1,I-1)
-...
-NS(S-1,0) NS(S-1,1) ...  NS(S-1,I-1)
-
-OS(0,0)   OS(0,1)   ...  OS(0,I-1)
-OS(1,0)   OS(1,1)   ...  OS(1,I-1)
-...
-OS(S-1,0) OS(S-1,1) ... OS(S-1,I-1)
-</pre><p>
-</p><p>
-For instance, the file containing the information for the example mentioned above is of the form:
-</p><pre class="programlisting">
-2 4 4
-
-0 2
-0 2
-1 3
-1 3
-
-0 3
-3 0
-1 2
-2 1
-</pre><p>
-</p></li><li><p>The third way is specific to FSMs resulting from shift registers, and the output symbol being the entire transition (ie, current_state and current_input). These FSMs are usefull when describibg ISI channels. In particular the state is comprised of the.....
-</p><pre class="programlisting">
-  fsm(const int mod_size, const int ch_length);
-</pre></li></ul></div><p>
-Finally, as can be seen from the above description, there are
-two more variables included in the FSM class implementation, 
-the PS and the PI matrices. These are computed internally 
-when an FSM is instantiated and their meaning is as follows.
-Sometimes (eg, in the traceback operation of the VA) we need
-to trace the history of the state or the input sequence. 
-To do this we would like to know for a given state s<sub>k</sub>, what are the possible previous states s<sub>k-1</sub>
-and what input symbols x<sub>k-1</sub> will get us from 
-s<sub>k-1</sub> to s<sub>k</sub>. This information can be derived from NS; however we want to have it ready in a 
-convenient format. 
-In the following we assume that for any state, 
-the number of incoming transitions is the same as the number of 
-outgoing transitions, ie, equal to I. All applications of interest 
-have FSMs satisfying this requirement.
-
-If we arbitrarily index the incoming transitions to the current state 
-by "i", then  as i goes from 0 to I-1, PS(s<sub>k</sub>,i)
-gives all previous states s<sub>k-1</sub>,
-and PI(s<sub>k</sub>,i) gives all previous inputs x<sub>k-1</sub>.
-In other words, for any given s<sub>k</sub> and any index i=0,1,...I-1, starting from 
-s<sub>k-1</sub>=PS(s<sub>k</sub>,i)
-with input 
-x<sub>k-1</sub>=PI(s<sub>k</sub>,i)
-will get us to the state s<sub>k</sub>. 
-More formally, for any i=0,1,...I-1 we have
-s<sub>k</sub> = NS(PS(s<sub>k</sub>,i),PI(s<sub>k</sub>,i)).
-
-</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="tcm"></a>TCM: A Complete Example</h2></div></div><div></div></div><p>
-We now discuss through a concrete example how
-the above FSM model can be used in GNU Radio.
-
-The communication system that we want to simulate
-consists of a source generating the
-input information in packets, a CC encoding each packet separately, 
-a memoryless modulator,
-an additive white Gaussian noise (AWGN) channel, and
-the VA performing MLSD.
-The program source is as follows.
-</p><pre class="programlisting">
-  1  #!/usr/bin/env python
-  2  
-  3  from gnuradio import gr
-  4  from gnuradio import audio
-  5  from gnuradio import trellis
-  6  from gnuradio import eng_notation
-  7  import math
-  8  import sys
-  9  import random
- 10  import fsm_utils
- 11  
- 12  def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
- 13      fg = gr.flow_graph ()
- 14  
- 15      # TX
- 16      src = gr.lfsr_32k_source_s()
- 17      src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
- 18      s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
- 19      enc = trellis.encoder_ss(f,0) # initial state = 0
- 20      mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
- 21  
- 22      # CHANNEL
- 23      add = gr.add_ff()
- 24      noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
- 25  
- 26      # RX
- 27      metrics = trellis.metrics_f(f.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
- 28      va = trellis.viterbi_s(f,K,0,-1) # Put -1 if the Initial/Final states are not set.
- 29      fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- 30      dst = gr.check_lfsr_32k_s(); 
- 31  
- 32      fg.connect (src,src_head,s2fsmi,enc,mod)
- 33      fg.connect (mod,(add,0))
- 34      fg.connect (noise,(add,1))
- 35      fg.connect (add,metrics)
- 36      fg.connect (metrics,va,fsmi2s,dst)
- 37      
- 38      fg.run()
- 39      
- 40      # A bit of cheating: run the program once and print the 
- 41      # final encoder state.
- 42      # Then put it as the last argument in the viterbi block
- 43      #print "final state = " , enc.ST()
- 44  
- 45      ntotal = dst.ntotal ()
- 46      nright = dst.nright ()
- 47      runlength = dst.runlength ()
- 48      return (ntotal,ntotal-nright)
- 49  
- 50  
- 51  def main(args):
- 52      nargs = len (args)
- 53      if nargs == 3:
- 54          fname=args[0]
- 55          esn0_db=float(args[1]) # Es/No in dB
- 56          rep=int(args[2]) # number of times the experiment is run to collect enough errors
- 57      else:
- 58          sys.stderr.write ('usage: test_tcm.py fsm_fname Es/No_db  repetitions\n')
- 59          sys.exit (1)
- 60  
- 61      # system parameters
- 62      f=trellis.fsm(fname) # get the FSM specification from a file (will hopefully be automated in the future...)
- 63      Kb=1024*16  # packet size in bits (make it multiple of 16 so it can be packed in a short)
- 64      bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
- 65      K=Kb/bitspersymbol # packet size in trellis steps
- 66      modulation = fsm_utils.psk4 # see fsm_utlis.py for available predefined modulations
- 67      dimensionality = modulation[0]
- 68      constellation = modulation[1] 
- 69      if len(constellation)/dimensionality != f.O():
- 70          sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- 71          sys.exit (1)
- 72      # calculate average symbol energy
- 73      Es = 0
- 74      for i in range(len(constellation)):
- 75          Es = Es + constellation[i]**2
- 76      Es = Es / (len(constellation)/dimensionality)
- 77      N0=Es/pow(10.0,esn0_db/10.0); # noise variance
- 78      
- 79      tot_s=0
- 80      terr_s=0
- 81      for i in range(rep):
- 82          (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
- 83          tot_s=tot_s+s
- 84          terr_s=terr_s+e
- 85          if (i%100==0):
- 86              print i,s,e,tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
- 87      # estimate of the (short) error rate
- 88      print tot_s,terr_s, '%e' % ((1.0*terr_s)/tot_s)
- 89  
- 90  
- 91  if __name__ == '__main__':
- 92      main (sys.argv[1:])
-</pre><p>
-The program is called by
-</p><div class="literallayout"><p><br>
-./test_tcm.py fsm_fname Es/No_db repetitions<br>
-</p></div><p>
-where "fsm_fname" is the file containing the FSM specification of the
-tested TCM code, "Es/No_db" is the SNR in dB, and "repetitions" 
-are the number of packets to be transmitted and received in order to
-collect sufficient number of errors for an accurate estimate of the
-error rate.
-</p><p>
-The FSM is first intantiated in "main" by 
-</p><pre class="programlisting">
- 62      f=trellis.fsm(fname) # get the FSM specification from a file (will hopefully be automated in the future...)
-</pre><p>
-Each packet has size Kb bits
-(we choose Kb to be a multiple of 16 so that all bits fit nicely into shorts and can be generated by the lfsr GNU Radio).
-Assuming that the FSM input has cardinality I, each input symbol consists 
-of bitspersymbol=log<sub>2</sub>( I ). The Kb/16 shorts are now 
-unpacked to K=Kb/bitspersymbol input
-symbols that will drive the FSM encoder.
-</p><pre class="programlisting">
- 63      Kb=1024*16  # packet size in bits (make it multiple of 16 so it can be packed in a short)
- 64      bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
- 65      K=Kb/bitspersymbol # packet size in trellis steps
-</pre><p>
-The FSM will produce K output symbols (remeber the FSM produces always one output symbol for each input symbol). Each of these symbols needs to be modulated. Since we are simulating the communication system, we need not simulate the actual waveforms. An M-ary, N-dimensional
-modulation is completely specified by a set of M, N-dimensional real vectors. In "fsm_utils.py" file we give a number of useful modulations with the following format: modulation = (N,constellation), where
-constellation=[c11,c12,...,c1N,c21,c22,...,c2N,...,cM1,cM2,...cMN].
-The meaning of the above is that every constellation point c_i
-is an N-dimnsional vector c_i=(ci1,ci2,...,ciN)
-For instance, 4-ary PAM is represented as
-(1,[-3, -1, 1, 3]), while QPSK is represented as
-(2,[1, 0, 0, 1, 0, -1, -1, 0]). In our example we choose QPSK modulation.
-Clearly, M should be equal to the cardinality of the FSM output, O.
-Finally the average symbol energy and noise variance are calculated.
-</p><pre class="programlisting">
- 66      modulation = fsm_utils.psk4 # see fsm_utlis.py for available predefined modulations
- 67      dimensionality = modulation[0]
- 68      constellation = modulation[1]
- 69      if len(constellation)/dimensionality != f.O():
- 70          sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
- 71          sys.exit (1)
- 72      # calculate average symbol energy
- 73      Es = 0
- 74      for i in range(len(constellation)):
- 75          Es = Es + constellation[i]**2
- 76      Es = Es / (len(constellation)/dimensionality)
- 77      N0=Es/pow(10.0,esn0_db/10.0); # noise variance
-</pre><p>
-Then, "run_test" is called with a different "seed" so that we get
-different noise realizations.
-</p><pre class="programlisting">
- 82          (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
-</pre><p>
-Let us examine now the "run_test" function. 
-First we set up the transmitter blocks.
-The Kb/16 shorts are first unpacked to 
-symbols consistent with the FSM input alphabet.
-The FSm encoder requires the FSM specification,
-and an initial state (which is set to 0 in this example).
-</p><pre class="programlisting">
- 15      # TX
- 16      src = gr.lfsr_32k_source_s()
- 17      src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
- 18      s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
- 19      enc = trellis.encoder_ss(f,0) # initial state = 0
-</pre><p>
-We now need to modulate the FSM output symbols.
-The "chunks_to_symbols_sf" is essentially a memoryless mapper which 
-for each input symbol y_k 
-outputs a sequence of N numbers ci1,ci2,...,ciN  representing the 
-coordianates of the constellation symbol c_i with i=y_k.
-</p><pre class="programlisting">
- 20      mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
-</pre><p>
-The channel is AWGN with appropriate noise variance.
-For each transmitted symbol c_k=(ck1,ck2,...,ckN) we receive a noisy version
-r_k=(rk1,rk2,...,rkN).
-</p><pre class="programlisting">
- 22      # CHANNEL
- 23      add = gr.add_ff()
- 24      noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
-</pre><p>
-Part of the design methodology was to decouple the FSM and VA from
-the details of the modulation, channel, receiver front-end etc.
-In order for the VA to run, we only need to provide it with
-a number representing a cost associated with each transition 
-in the trellis. Then the VA will find the sequence with 
-the smallest total cost through the trellis. 
-The cost associated with a transition (s_k,x_k) is only a function
-of the output y_k = OS(s_k,x_k), and the observation
-vector r_k. Thus, for each time period, k,
-we need to label each of the SxI transitions with such a cost.
-This means that for each time period we need to evaluate 
-O such numbers (one for each possible output symbol y_k). 
-This is done 
-in "metrics_f". In particular, metrics_f is a memoryless device
-taking N inputs at a time and producing O outputs. The N inputs are
-rk1,rk2,...,rkN.
-The O outputs
-are the costs associated with observations rk1,rk2,...,rkN and
-hypothesized output symbols c_1,c_2,...,c_M. For instance,
-if we choose to perform soft-input VA, we need to evaluate
-the Euclidean distance between r_k and each of c_1,c_2,...,c_M,
-for each of the K transmitted symbols.
-Other options are available as well; for instance, we can
-do hard decision demodulation and feed the VA with 
-symbol Hamming distances, or even bit Hamming distances, etc.
-These are all implemented in "metrics_f".
-</p><pre class="programlisting">
- 26      # RX
- 27      metrics = trellis.metrics_f(f.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
-</pre><p>
-Now the VA can run once it is supplied by the initial and final states.
-The initial state is known to be 0; the final state is usually 
-forced to some value by padding the information sequence appropriately.
-In this example, we always send the the same info sequence (we only randomize noise) so we can evaluate off line the final state and then provide it to the VA (a value of -1 signifies that there is no fixed initial
-or final state). The VA outputs the estimates of the symbols x_k which
-are then packed to shorts and compared with the transmitted sequence.
-</p><pre class="programlisting">
- 28      va = trellis.viterbi_s(f,K,0,-1) # Put -1 if the Initial/Final states are not set.
- 29      fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- 30      dst = gr.check_lfsr_32k_s();
-</pre><p>
-The function returns the number of shorts and the number of shorts in error. Observe that this way the estimated error rate refers to 
-16-bit-symbol error rate.
-</p><pre class="programlisting">
- 48      return (ntotal,ntotal-nright)
-</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="future"></a>Future Work</h2></div></div><div></div></div><div class="itemizedlist"><ul type="disc"><li><p>
-Improve the documentation :-)
-</p></li><li><p>
-automate fsm generation from generator polynomials 
-(feedforward or feedback form).
-</p></li><li><p>
-Optimize the VA code.
-</p></li><li><p>
-Provide implementation of soft-input soft-output (SISO) decoders for 
-potential use in concatenated systems. Also a host of suboptimal
-decoders, eg, sphere decoding, M- and T- algorithms, sequential decoding, etc.
-can be implemented.
-</p></li><li><p>
-Although turbo decoding is rediculously slow in software, 
-we can design it in principle. One question is, whether we should 
-use the encoder, and SISO blocks and connect them
-through GNU radio or we should implement turbo-decoding
-as a single block (issues with buffering between blocks).
-</p></li></ul></div></div></div></body></html>
index 935fe9fbf10bd8e4e8dd45dea80d106c4f3d894c..769d4a3386c98f9f5ae11e97f6d815f94c0aaaeb 100644 (file)
@@ -65,9 +65,11 @@ _trellis_la_SOURCES =                        \
        trellis.cc                      \
         fsm.cc                         \
         quicksort_index.cc             \
+        base.cc                                \
         interleaver.cc                 \
         trellis_calc_metric.cc         \
         trellis_permutation.cc         \
+       trellis_siso_f.cc               \
        $(GENERATED_CC)                 
 
 # magic flags
@@ -87,10 +89,13 @@ trellis.cc trellis.py: $(ALL_IFILES)
 grinclude_HEADERS =                    \
         fsm.h                          \
         quicksort_index.h              \
+        base.h                         \
         interleaver.h                  \
         trellis_metric_type.h          \
         trellis_calc_metric.h          \
         trellis_permutation.h          \
+        trellis_siso_type.h            \
+       trellis_siso_f.h                \
        $(GENERATED_H)                  
 
 
diff --git a/gr-trellis/src/lib/base.cc b/gr-trellis/src/lib/base.cc
new file mode 100644 (file)
index 0000000..35ba2ea
--- /dev/null
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */\r
+/*\r
+ * Copyright 2002 Free Software Foundation, Inc.\r
+ *\r
+ * This file is part of GNU Radio\r
+ *\r
+ * GNU Radio is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2, or (at your option)\r
+ * any later version.\r
+ *\r
+ * GNU Radio is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GNU Radio; see the file COPYING.  If not, write to\r
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
+ * Boston, MA 02111-1307, USA.\r
+ */\r
+\r
+#include <cstdio>\r
+#include <stdexcept>\r
+#include <cmath>\r
+#include "base.h"\r
+\r
+\r
+bool dec2base(unsigned int num, int base, std::vector<int> &s)\r
+{\r
+  int l = s.size();\r
+  unsigned int n=num;\r
+  for(int i=0;i<l;i++) {\r
+    s[l-i-1] = n % base; //MSB first\r
+    n /= base;\r
+  }\r
+  if(n!=0) {\r
+    printf("Number %d requires more than %d digits.",num,l);\r
+    return false;\r
+  }\r
+  else\r
+    return true;\r
+}\r
+\r
+\r
+unsigned int base2dec(const std::vector<int> &s, int base)\r
+{\r
+  int l = s.size();\r
+  unsigned int num=0;\r
+  for(int i=0;i<l;i++)\r
+      num=num*base+s[i];\r
+  return num;\r
+}\r
+\r
+\r
+bool dec2bases(unsigned int num, const std::vector<int> &bases, std::vector<int> &s)\r
+{\r
+  int l = s.size();\r
+  unsigned int n=num;\r
+  for(int i=0;i<l;i++) {\r
+      s[l-i-1] = n % bases[l-i-1];\r
+      n /= bases[l-i-1];\r
+  }\r
+  if(n!=0) {\r
+    printf("Number %d requires more than %d digits.",num,l);\r
+    return false;\r
+  }\r
+  else\r
+    return true;\r
+}\r
+\r
+\r
+\r
+unsigned int bases2dec(const std::vector<int> &s, const std::vector<int> &bases)\r
+{\r
+  int l = s.size();\r
+  unsigned int num=0;\r
+  for(int i=0;i<l;i++)\r
+      num = num * bases[i] + s[i];\r
+  return num;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/gr-trellis/src/lib/base.h b/gr-trellis/src/lib/base.h
new file mode 100644 (file)
index 0000000..b0fe3e9
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */\r
+/*\r
+ * Copyright 2002 Free Software Foundation, Inc.\r
+ *\r
+ * This file is part of GNU Radio\r
+ *\r
+ * GNU Radio is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2, or (at your option)\r
+ * any later version.\r
+ *\r
+ * GNU Radio is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with GNU Radio; see the file COPYING.  If not, write to\r
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
+ * Boston, MA 02111-1307, USA.\r
+ */\r
+\r
+#ifndef INCLUDED_TRELLIS_BASE_H\r
+#define INCLUDED_TRELLIS_BASE_H\r
+\r
+#include <vector>\r
+\r
+/*!\r
+ * \brief  change base\r
+ */\r
+\r
+\r
+bool dec2base(unsigned int num, int base, std::vector<int> &s);\r
+bool dec2bases(unsigned int num, const std::vector<int> &bases, std::vector<int> &s);\r
+unsigned int base2dec(const std::vector<int> &s, int base);\r
+unsigned int bases2dec(const std::vector<int> &s, const std::vector<int> &bases);\r
+\r
+#endif\r
index 05d1589fe6aea40ed15e67e5499ddb07cfb32eae..f343088343fc31c6791ede0531a07330fe48b163 100644 (file)
 #include <cstdio>\r
 #include <stdexcept>\r
 #include <cmath>\r
+#include "base.h"\r
 #include "fsm.h"\r
 \r
+\r
 fsm::fsm()\r
 {\r
   d_I=0;\r
@@ -34,6 +36,8 @@ fsm::fsm()
   d_OS.resize(0);\r
   d_PS.resize(0);\r
   d_PI.resize(0);\r
+  d_TMi.resize(0);\r
+  d_TMl.resize(0);\r
 }\r
 \r
 fsm::fsm(const fsm &FSM)\r
@@ -45,28 +49,20 @@ fsm::fsm(const fsm &FSM)
   d_OS=FSM.OS();\r
   d_PS=FSM.PS();\r
   d_PI=FSM.PI();\r
+  d_TMi=FSM.TMi();\r
+  d_TMl=FSM.TMl();\r
 }\r
 \r
-fsm::fsm(const int I, const int S, const int O, const std::vector<int> &NS, const std::vector<int> &OS)\r
+fsm::fsm(int I, int S, int O, const std::vector<int> &NS, const std::vector<int> &OS)\r
 {\r
   d_I=I;\r
   d_S=S;\r
   d_O=O;\r
   d_NS=NS;\r
   d_OS=OS;\r
-  d_PS.resize(d_I*d_S);\r
-  d_PI.resize(d_I*d_S);\r
-  \r
-  // generate the PS, PI tables for later use\r
-  for(int i=0;i<d_S;i++) {\r
-    int j=0;\r
-    for(int ii=0;ii<d_S;ii++) for(int jj=0;jj<d_I;jj++) {\r
-      if(d_NS[ii*d_I+jj]!=i) continue;\r
-      d_PS[i*d_I+j]=ii;\r
-      d_PI[i*d_I+j]=jj;\r
-      j++;\r
-    }\r
-  }\r
\r
+  generate_PS_PI();\r
+  generate_TM();\r
 }\r
 \r
 //######################################################################\r
@@ -84,14 +80,12 @@ fsm::fsm(const char *name)
   FILE *fsmfile;\r
 \r
   if((fsmfile=fopen(name,"r"))==NULL) \r
-    throw std::runtime_error ("file open error in fsm()");\r
+    throw std::runtime_error ("fsm::fsm(const char *name): file open error\n");\r
     //printf("file open error in fsm()\n");\r
   \r
   fscanf(fsmfile,"%d %d %d\n",&d_I,&d_S,&d_O);\r
   d_NS.resize(d_I*d_S);\r
   d_OS.resize(d_I*d_S);\r
-  d_PS.resize(d_I*d_S);\r
-  d_PI.resize(d_I*d_S);\r
 \r
   for(int i=0;i<d_S;i++) {\r
     for(int j=0;j<d_I;j++) fscanf(fsmfile,"%d",&(d_NS[i*d_I+j]));\r
@@ -99,25 +93,128 @@ fsm::fsm(const char *name)
   for(int i=0;i<d_S;i++) {\r
     for(int j=0;j<d_I;j++) fscanf(fsmfile,"%d",&(d_OS[i*d_I+j]));\r
   }\r
\r
+  generate_PS_PI();\r
+  generate_TM();\r
+}\r
+\r
+\r
+\r
+\r
+//######################################################################\r
+//# Automatically generate the FSM from the generator matrix\r
+//# of a (n,k) binary convolutional code\r
+//######################################################################\r
+fsm::fsm(int k, int n, const std::vector<int> &G)\r
+{\r
+\r
+  // calculate maximum memory requirements for each input stream\r
+  std::vector<int> max_mem_x(k,-1);\r
+  int max_mem = -1;\r
+  for(int i=0;i<k;i++) {\r
+    for(int j=0;j<n;j++) {\r
+      int mem = -1;\r
+      if(G[i*n+j]!=0)\r
+        mem=(int)(log(G[i*n+j])/log(2.0));\r
+      if(mem>max_mem_x[i])\r
+        max_mem_x[i]=mem;\r
+      if(mem>max_mem)\r
+        max_mem=mem;\r
+    }\r
+  }\r
   \r
-  // generate the PS, PI tables for later use\r
-  for(int i=0;i<d_S;i++) {\r
-    int j=0;\r
-    for(int ii=0;ii<d_S;ii++) for(int jj=0;jj<d_I;jj++) {\r
-      if(d_NS[ii*d_I+jj]!=i) continue;\r
-      d_PS[i*d_I+j]=ii;\r
-      d_PI[i*d_I+j]=jj;\r
-      j++;\r
+//printf("max_mem_x\n");\r
+//for(int j=0;j<max_mem_x.size();j++) printf("%d ",max_mem_x[j]); printf("\n");\r
+\r
+  // calculate total memory requirements to set S\r
+  int sum_max_mem = 0;\r
+  for(int i=0;i<k;i++)\r
+    sum_max_mem += max_mem_x[i];\r
+\r
+//printf("sum_max_mem = %d\n",sum_max_mem);\r
+\r
+  d_I=1<<k;\r
+  d_S=1<<sum_max_mem;\r
+  d_O=1<<n;\r
\r
+  // binary representation of the G matrix\r
+  std::vector<std::vector<int> > Gb(k*n);\r
+  for(int j=0;j<k*n;j++) {\r
+    Gb[j].resize(max_mem+1);\r
+    dec2base(G[j],2,Gb[j]);\r
+//printf("Gb\n");\r
+//for(int m=0;m<Gb[j].size();m++) printf("%d ",Gb[j][m]); printf("\n");\r
+  }\r
+\r
+  // alphabet size of each shift register \r
+  std::vector<int> bases_x(k);\r
+  for(int j=0;j<k ;j++) \r
+    bases_x[j] = 1 << max_mem_x[j];\r
+//printf("bases_x\n");\r
+//for(int j=0;j<max_mem_x.size();j++) printf("%d ",max_mem_x[j]); printf("\n");\r
+\r
+  d_NS.resize(d_I*d_S);\r
+  d_OS.resize(d_I*d_S);\r
+\r
+  std::vector<int> sx(k);\r
+  std::vector<int> nsx(k);\r
+  std::vector<int> tx(k);\r
+  std::vector<std::vector<int> > tb(k);\r
+  for(int j=0;j<k;j++)\r
+    tb[j].resize(max_mem+1);\r
+  std::vector<int> inb(k);\r
+  std::vector<int> outb(n);\r
+\r
+\r
+  for(int s=0;s<d_S;s++) {\r
+    dec2bases(s,bases_x,sx); // split s into k values, each representing on of the k shift registers\r
+//printf("state = %d \nstates = ",s);\r
+//for(int j=0;j<sx.size();j++) printf("%d ",sx[j]); printf("\n");\r
+    for(int i=0;i<d_I;i++) {\r
+      dec2base(i,2,inb); // input in binary\r
+//printf("input = %d \ninputs = ",i);\r
+//for(int j=0;j<inb.size();j++) printf("%d ",inb[j]); printf("\n");\r
+\r
+      // evaluate next state\r
+      for(int j=0;j<k;j++)\r
+        nsx[j] = (inb[j]*bases_x[j]+sx[j])/2; // next state (for each shift register) MSB first\r
+      d_NS[s*d_I+i]=bases2dec(nsx,bases_x); // collect all values into the new state\r
+\r
+      // evaluate transitions\r
+      for(int j=0;j<k;j++)\r
+        tx[j] = inb[j]*bases_x[j]+sx[j]; // transition (for each shift register)MSB first\r
+      for(int j=0;j<k;j++) {\r
+        dec2base(tx[j],2,tb[j]); // transition in binary\r
+//printf("transition = %d \ntransitions = ",tx[j]);\r
+//for(int m=0;m<tb[j].size();m++) printf("%d ",tb[j][m]); printf("\n");\r
+      }\r
+\r
+      // evaluate outputs\r
+      for(int nn=0;nn<n;nn++) {\r
+        outb[nn] = 0;\r
+        for(int j=0;j<k;j++) {\r
+          for(int m=0;m<max_mem+1;m++)\r
+            outb[nn] = (outb[nn] + Gb[j*n+nn][m]*tb[j][m]) % 2; // careful: polynomial 1+D ir represented as 110, not as 011\r
+//printf("output %d equals %d\n",nn,outb[nn]);\r
+        }\r
+      }\r
+      d_OS[s*d_I+i] = base2dec(outb,2);\r
     }\r
   }\r
+\r
+  generate_PS_PI();\r
+  generate_TM();\r
 }\r
 \r
+\r
+\r
+\r
 //######################################################################\r
 //# Automatically generate an FSM specification describing the \r
 //# ISI for a channel\r
 //# of length ch_length and a modulation of size mod_size\r
 //######################################################################\r
-fsm::fsm(const int mod_size, const int ch_length)\r
+fsm::fsm(int mod_size, int ch_length)\r
 {\r
   d_I=mod_size;\r
   d_S=(int) (pow(1.0*d_I,1.0*ch_length-1)+0.5);\r
@@ -125,8 +222,6 @@ fsm::fsm(const int mod_size, const int ch_length)
 \r
   d_NS.resize(d_I*d_S);\r
   d_OS.resize(d_I*d_S);\r
-  d_PS.resize(d_I*d_S);\r
-  d_PI.resize(d_I*d_S);\r
 \r
   for(int s=0;s<d_S;s++) {\r
     for(int i=0;i<d_I;i++) { \r
@@ -135,8 +230,20 @@ fsm::fsm(const int mod_size, const int ch_length)
       d_OS[s*d_I+i] = t;\r
     }\r
   }\r
-  \r
-  // generate the PS, PI tables for later use\r
\r
+  generate_PS_PI();\r
+  generate_TM();\r
+}\r
+\r
+\r
+//######################################################################\r
+//# generate the PS and PI tables for later use\r
+//######################################################################\r
+void fsm::generate_PS_PI()\r
+{\r
+  d_PS.resize(d_I*d_S);\r
+  d_PI.resize(d_I*d_S);\r
+\r
   for(int i=0;i<d_S;i++) {\r
     int j=0;\r
     for(int ii=0;ii<d_S;ii++) for(int jj=0;jj<d_I;jj++) {\r
@@ -147,3 +254,70 @@ fsm::fsm(const int mod_size, const int ch_length)
     }\r
   }\r
 }\r
+\r
+\r
+//######################################################################\r
+//# generate the termination matrices TMl and TMi for later use\r
+//######################################################################\r
+void fsm::generate_TM()\r
+{\r
+  d_TMi.resize(d_S*d_S);\r
+  d_TMl.resize(d_S*d_S);\r
+\r
+  for(int i=0;i<d_S*d_S;i++) {\r
+    d_TMi[i] = -1; // no meaning\r
+    d_TMl[i] = d_S; //infinity: you need at most S-1 steps\r
+    if (i/d_S == i%d_S)\r
+      d_TMl[i] = 0;\r
+  }\r
+\r
+  for(int s=0;s<d_S;s++) {\r
+    bool done = false;\r
+    int attempts = 0;\r
+    while (done == false && attempts < d_S-1) {\r
+      done = find_es(s);\r
+      attempts ++;\r
+    }\r
+    if (done == false)\r
+      //throw std::runtime_error ("fsm::generate_TM(): FSM appears to be disconnected\n");\r
+      printf("fsm::generate_TM(): FSM appears to be disconnected\n");\r
+  }\r
+}\r
+\r
+\r
+// find a path from any state to the ending state "es"\r
+bool fsm::find_es(int es)\r
+{\r
+  bool done = true;\r
+  for(int s=0;s<d_S;s++) {\r
+    if(d_TMl[s*d_S+es] < d_S) \r
+      continue;\r
+    int minl=d_S;\r
+    int mini=-1;\r
+    for(int i=0;i<d_I;i++) {\r
+      if( 1 + d_TMl[d_NS[s*d_I+i]*d_S+es] < minl) {\r
+        minl = 1 + d_TMl[d_NS[s*d_I+i]*d_S+es];\r
+        mini = i;\r
+      }\r
+    }\r
+    if (mini != -1) {\r
+      d_TMl[s*d_S+es]=minl;\r
+      d_TMi[s*d_S+es]=mini;\r
+    }\r
+    else\r
+      done = false;\r
+  }\r
+  return done;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
index b5a8e0d5bc1ffe067ef3758596209c7c2cdd7bc7..01703e35fce7da35991153e2fb23c9c7e6da95cb 100644 (file)
@@ -37,12 +37,18 @@ private:
   std::vector<int> d_OS;\r
   std::vector<int> d_PS;\r
   std::vector<int> d_PI;\r
+  std::vector<int> d_TMi;\r
+  std::vector<int> d_TMl;\r
+  void generate_PS_PI ();\r
+  void generate_TM ();\r
+  bool find_es(int es);\r
 public:\r
   fsm();\r
   fsm(const fsm &FSM);\r
-  fsm(const int I, const int S, const int O, const std::vector<int> &NS, const std::vector<int> &OS);\r
+  fsm(int I, int S, int O, const std::vector<int> &NS, const std::vector<int> &OS);\r
   fsm(const char *name);\r
-  fsm(const int mod_size, const int ch_length);\r
+  fsm(int k, int n, const std::vector<int> &G);\r
+  fsm(int mod_size, int ch_length);\r
   int I () const { return d_I; }\r
   int S () const { return d_S; }\r
   int O () const { return d_O; }\r
@@ -50,6 +56,8 @@ public:
   const std::vector<int> & OS () const { return d_OS; }\r
   const std::vector<int> & PS () const { return d_PS; }\r
   const std::vector<int> & PI () const { return d_PI; }\r
+  const std::vector<int> & TMi () const { return d_TMi; }\r
+  const std::vector<int> & TMl () const { return d_TMl; }\r
 };\r
 \r
 #endif\r
index eda8aeefdca9e566507a4678ec5a0c98f1088d77..e5b1af0ca5267d2a58eed589fc23227dd5956b1d 100644 (file)
@@ -29,12 +29,17 @@ private:
   std::vector<int> d_OS;
   std::vector<int> d_PS;
   std::vector<int> d_PI;
+  std::vector<int> d_TMi;
+  std::vector<int> d_TMl;
+  void generate_PS_PI ();
+  void generate_TM ();
 public:
   fsm();
   fsm(const fsm &FSM);
-  fsm(const int I, const int S, const int O, const std::vector<int> &NS, const std::vector<int> &OS);
+  fsm(int I, int S, int O, const std::vector<int> &NS, const std::vector<int> &OS);
   fsm(const char *name);
-  fsm(const int mod_size, const int ch_length);
+  fsm(int k, int n, const std::vector<int> &G);
+  fsm(int mod_size, int ch_length);
   int I () const { return d_I; }
   int S () const { return d_S; }
   int O () const { return d_O; }
@@ -42,8 +47,7 @@ public:
   const std::vector<int> & OS () const { return d_OS; }
   const std::vector<int> & PS () const { return d_PS; }
   const std::vector<int> & PI () const { return d_PI; }
+  const std::vector<int> & TMi () const { return d_TMi; }
+  const std::vector<int> & TMl () const { return d_TMl; }
 };
 
-
-
-
index 042dc04bac04000446988c540cb4fe5c8871ba76..174d31c0b8cdbaa8fcf5526cbf6e90c9cce5ceee 100644 (file)
@@ -42,7 +42,7 @@ interleaver::interleaver(const interleaver &INTERLEAVER)
   d_DEINTER=INTERLEAVER.DEINTER();\r
 }\r
 \r
-interleaver::interleaver(const int K, const std::vector<int> &INTER)\r
+interleaver::interleaver(int K, const std::vector<int> &INTER)\r
 {\r
   d_K=K;\r
   d_INTER=INTER;\r
@@ -85,7 +85,7 @@ interleaver::interleaver(const char *name)
 //######################################################################\r
 //# Generate a random interleaver\r
 //######################################################################\r
-interleaver::interleaver(const int K, unsigned int seed)\r
+interleaver::interleaver(int K, unsigned int seed)\r
 {\r
   d_K=K;\r
   d_INTER.resize(d_K);\r
index 13c316be2daf7d159615b2663b255753247df966..14ed80faf5be2224aa3fae4be0881da7addbde6a 100644 (file)
@@ -36,9 +36,9 @@ private:
 public:\r
   interleaver();\r
   interleaver(const interleaver & INTERLEAVER);\r
-  interleaver(const int K, const std::vector<int> & INTER);\r
+  interleaver(int K, const std::vector<int> & INTER);\r
   interleaver(const char *name);\r
-  interleaver(const int K, unsigned int seed);\r
+  interleaver(int K, unsigned int seed);\r
   int K () const { return d_K; }\r
   const std::vector<int> & INTER () const { return d_INTER; }\r
   const std::vector<int> & DEINTER () const { return d_DEINTER; }\r
index 6baec3bdc8753274c45f98d8adb35866d9bf87ea..625bd8620f7fe8b846d69b5535a4c8bfce49e3c9 100644 (file)
@@ -28,9 +28,9 @@ private:
 public:\r
   interleaver();\r
   interleaver(const interleaver & INTERLEAVER);\r
-  interleaver(const int K, const std::vector<int> & INTER);\r
+  interleaver(int K, const std::vector<int> & INTER);\r
   interleaver(const char *name);\r
-  interleaver(const int K, unsigned int seed);\r
+  interleaver(int K, unsigned int seed);\r
   int K () const { return d_K; }\r
   const std::vector<int> & INTER () const { return d_INTER; }\r
   const std::vector<int> & DEINTER () const { return d_DEINTER; }\r
index bd3144119b6c02d8c0449a1b6d0360238947e483..983576e83852affaa52b733f1e4205133667c8bc 100644 (file)
@@ -10,6 +10,7 @@
 #include "fsm.h"
 #include "interleaver.h"
 #include "trellis_permutation.h"
+#include "trellis_siso_f.h"
 #include <stdexcept>
 %}
 
 %include "fsm.i"
 %include "interleaver.i"
 %include "trellis_permutation.i"
+%include "trellis_siso_f.i"
+
 %include "trellis_metric_type.h"
+%include "trellis_siso_type.h"
 
 
 %include "trellis_generated.i"
index ae25a67bad4bd2a2b215ae65cd40dc76fdb6bea6..5faa4b7c70bd4c3d2a1ab02da6f9d9383fd068e0 100644 (file)
@@ -24,8 +24,7 @@
 #include <stdexcept>
 #include "trellis_calc_metric.h"
 
-// soft decisions (Euclidean distance squared)
-void calc_metric_s(const int O, const int D, const std::vector<short> &TABLE, const short *in, float *metric, trellis_metric_type_t type)
+void calc_metric_s(int O, int D, const std::vector<short> &TABLE, const short *in, float *metric, trellis_metric_type_t type)
 {
   float minm = FLT_MAX;
   int minmi = 0;
@@ -33,24 +32,24 @@ void calc_metric_s(const int O, const int D, const std::vector<short> &TABLE, co
   switch (type){
   case TRELLIS_EUCLIDEAN:
     for(int o=0;o<O;o++) {
-       metric[o]=0.0;
-       for (int m=0;m<D;m++) {
-           float s=in[m]-TABLE[o*D+m];
-           metric[o]+=s*s;
-       }
+      metric[o]=0.0;
+      for (int m=0;m<D;m++) {
+        float s=in[m]-TABLE[o*D+m];
+        metric[o]+=s*s;
+      }
     }
     break;
   case TRELLIS_HARD_SYMBOL:
     for(int o=0;o<O;o++) {
-       metric[o]=0.0;
-       for (int m=0;m<D;m++) {
-           float s=in[m]-TABLE[o*D+m];
-           metric[o]+=s*s;
-       }
-       if(metric[o]<minm) {
-         minm=metric[o];
-         minmi=o;
-       }
+      metric[o]=0.0;
+      for (int m=0;m<D;m++) {
+        float s=in[m]-TABLE[o*D+m];
+        metric[o]+=s*s;
+      }
+      if(metric[o]<minm) {
+        minm=metric[o];
+        minmi=o;
+      }
     }
     for(int o=0;o<O;o++) {
       metric[o] = (o==minmi?0.0:1.0);
@@ -66,8 +65,7 @@ void calc_metric_s(const int O, const int D, const std::vector<short> &TABLE, co
 
 
 
-// soft decisions (Euclidean distance squared)
-void calc_metric_i(const int O, const int D, const std::vector<int> &TABLE, const int *in, float *metric, trellis_metric_type_t type)
+void calc_metric_i(int O, int D, const std::vector<int> &TABLE, const int *in, float *metric, trellis_metric_type_t type)
 {
   float minm = FLT_MAX;
   int minmi = 0;
@@ -75,24 +73,24 @@ void calc_metric_i(const int O, const int D, const std::vector<int> &TABLE, cons
   switch (type){
   case TRELLIS_EUCLIDEAN:
     for(int o=0;o<O;o++) {
-       metric[o]=0.0;
-       for (int m=0;m<D;m++) {
-           float s=in[m]-TABLE[o*D+m];
-           metric[o]+=s*s;
-       }
+      metric[o]=0.0;
+      for (int m=0;m<D;m++) {
+        float s=in[m]-TABLE[o*D+m];
+        metric[o]+=s*s;
+      }
     }
     break;
   case TRELLIS_HARD_SYMBOL:
     for(int o=0;o<O;o++) {
-       metric[o]=0.0;
-       for (int m=0;m<D;m++) {
-           float s=in[m]-TABLE[o*D+m];
-           metric[o]+=s*s;
-       }
-       if(metric[o]<minm) {
-         minm=metric[o];
-         minmi=o;
-       }
+      metric[o]=0.0;
+      for (int m=0;m<D;m++) {
+        float s=in[m]-TABLE[o*D+m];
+        metric[o]+=s*s;
+      }
+      if(metric[o]<minm) {
+        minm=metric[o];
+        minmi=o;
+      }
     }
     for(int o=0;o<O;o++) {
       metric[o] = (o==minmi?0.0:1.0);
@@ -108,12 +106,7 @@ void calc_metric_i(const int O, const int D, const std::vector<int> &TABLE, cons
 
 
 
-
-
-
-
-// soft decisions (Euclidean distance squared)
-void calc_metric_f(const int O, const int D, const std::vector<float> &TABLE, const float *in, float *metric, trellis_metric_type_t type)
+void calc_metric_f(int O, int D, const std::vector<float> &TABLE, const float *in, float *metric, trellis_metric_type_t type)
 {
   float minm = FLT_MAX;
   int minmi = 0;
@@ -121,24 +114,24 @@ void calc_metric_f(const int O, const int D, const std::vector<float> &TABLE, co
   switch (type){
   case TRELLIS_EUCLIDEAN:
     for(int o=0;o<O;o++) {
-       metric[o]=0.0;
-       for (int m=0;m<D;m++) {
-           float s=in[m]-TABLE[o*D+m];
-           metric[o]+=s*s;
-       }
+      metric[o]=0.0;
+      for (int m=0;m<D;m++) {
+        float s=in[m]-TABLE[o*D+m];
+        metric[o]+=s*s;
+      }
     } 
     break;
   case TRELLIS_HARD_SYMBOL:
     for(int o=0;o<O;o++) {
-       metric[o]=0.0;
-       for (int m=0;m<D;m++) {
-           float s=in[m]-TABLE[o*D+m];
-           metric[o]+=s*s;
-       }
-       if(metric[o]<minm) {
-         minm=metric[o];
-         minmi=o;
-       }
+      metric[o]=0.0;
+      for (int m=0;m<D;m++) {
+        float s=in[m]-TABLE[o*D+m];
+        metric[o]+=s*s;
+      }
+      if(metric[o]<minm) {
+        minm=metric[o];
+        minmi=o;
+      }
     }
     for(int o=0;o<O;o++) {
       metric[o] = (o==minmi?0.0:1.0);
@@ -153,8 +146,7 @@ void calc_metric_f(const int O, const int D, const std::vector<float> &TABLE, co
 }
 
 
-// soft decisions (Euclidean distance squared)
-void calc_metric_c(const int O, const int D, const std::vector<gr_complex> &TABLE, const gr_complex *in, float *metric, trellis_metric_type_t type)
+void calc_metric_c(int O, int D, const std::vector<gr_complex> &TABLE, const gr_complex *in, float *metric, trellis_metric_type_t type)
 {
   float minm = FLT_MAX;
   int minmi = 0;
@@ -169,7 +161,20 @@ void calc_metric_c(const int O, const int D, const std::vector<gr_complex> &TABL
       }
     }
   case TRELLIS_HARD_SYMBOL:
-    throw std::runtime_error ("Invalid metric type (not yet implemented).");
+    for(int o=0;o<O;o++) {
+      metric[o]=0.0;
+      for (int m=0;m<D;m++) {
+        gr_complex s=in[m]-TABLE[o*D+m];
+        metric[o]+=s.real()*s.real()+s.imag()*s.imag();
+      }
+      if(metric[o]<minm) {
+        minm=metric[o];
+        minmi=o;
+      }
+    }
+    for(int o=0;o<O;o++) {
+      metric[o] = (o==minmi?0.0:1.0);
+    }
     break;
   case TRELLIS_HARD_BIT:
     throw std::runtime_error ("Invalid metric type (not yet implemented).");
index 1e180532227a8620ffd731b06869e9d2f1e7b817..0f66d82d87a4c786597f7d2a68a0d91d67de2c31 100644 (file)
 #include <gr_complex.h>
 #include <trellis_metric_type.h>
 
-void calc_metric_s(const int O, const int D, const std::vector<short> &TABLE, const short *in, float *metric, trellis_metric_type_t type);
+void calc_metric_s(int O, int D, const std::vector<short> &TABLE, const short *in, float *metric, trellis_metric_type_t type);
 
-void calc_metric_i(const int O, const int D, const std::vector<int> &TABLE, const int *in, float *metric, trellis_metric_type_t type);
+void calc_metric_i(int O, int D, const std::vector<int> &TABLE, const int *in, float *metric, trellis_metric_type_t type);
 
-void calc_metric_f(const int O, const int D, const std::vector<float> &TABLE, const float *in, float *metric, trellis_metric_type_t type);
+void calc_metric_f(int O, int D, const std::vector<float> &TABLE, const float *in, float *metric, trellis_metric_type_t type);
 
-void calc_metric_c(const int O, const int D, const std::vector<gr_complex> &TABLE, const gr_complex *in, float *metric, trellis_metric_type_t type);
+void calc_metric_c(int O, int D, const std::vector<gr_complex> &TABLE, const gr_complex *in, float *metric, trellis_metric_type_t type);
 
 #endif
index 75ae0750aab8b74143064efdc229c4f4f09d68f8..810951e647f3f83b626c8affad9ac6922059e296 100644 (file)
 #include <iostream>
 
 @SPTR_NAME@ 
-trellis_make_@BASE_NAME@ (const fsm &FSM, const int ST)
+trellis_make_@BASE_NAME@ (const fsm &FSM, int ST)
 {
   return @SPTR_NAME@ (new @NAME@ (FSM,ST));
 }
 
-@NAME@::@NAME@ (const fsm &FSM, const int ST)
+@NAME@::@NAME@ (const fsm &FSM, int ST)
   : gr_sync_block ("@BASE_NAME@",
                   gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
                   gr_make_io_signature (1, -1, sizeof (@O_TYPE@))),
@@ -50,26 +50,24 @@ int
                        gr_vector_const_void_star &input_items,
                        gr_vector_void_star &output_items)
 {
-  int d_ST_tmp;
+  int ST_tmp;
 
   assert (input_items.size() == output_items.size());
   int nstreams = input_items.size();
 
-for (int m=0;m<nstreams;m++) {
-  const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[m];
-  @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
-  d_ST_tmp = d_ST;
+  for (int m=0;m<nstreams;m++) {
+    const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[m];
+    @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
+    ST_tmp = d_ST;
 
-// per stream processing
-
-  for (int i = 0; i < noutput_items; i++){
-    out[i] = (@O_TYPE@) d_FSM.OS()[d_ST_tmp*d_FSM.I()+in[i]]; // direction of time?
-    d_ST_tmp = (int) d_FSM.NS()[d_ST_tmp*d_FSM.I()+in[i]];
+    // per stream processing
+    for (int i = 0; i < noutput_items; i++){
+      out[i] = (@O_TYPE@) d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]]; // direction of time?
+      ST_tmp = (int) d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
+    }
+    // end per stream processing
   }
-
-// end per stream processing
-}
-  d_ST = d_ST_tmp;
+  d_ST = ST_tmp;
 
   return noutput_items;
 }
index bfca5ee402c656451ad559a05654a97ba38df500..26c220489313755153e180538af481c031905908 100644 (file)
@@ -31,7 +31,7 @@
 class @NAME@;
 typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
 
-@SPTR_NAME@ trellis_make_@BASE_NAME@ (const fsm &FSM, const int ST);
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (const fsm &FSM, int ST);
 
 /*!
  * \brief Convolutional encoder.
@@ -42,10 +42,10 @@ typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
 class @NAME@ : public gr_sync_block
 {
 private:
-  friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (const fsm &FSM, const int ST);
+  friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (const fsm &FSM, int ST);
   fsm d_FSM;
   int d_ST;
-  @NAME@ (const fsm &FSM, const int ST); 
+  @NAME@ (const fsm &FSM, int ST); 
 
 public:
   fsm FSM () const { return d_FSM; }
index ea015a84fb3e043173bb0f8600471848ee19910f..e5627be790441f5912095a215d9b5ff1ad5bb620 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@);
 
-@SPTR_NAME@ trellis_make_@BASE_NAME@ (const fsm &FSM, const int ST);
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (const fsm &FSM, int ST);
 
 class @NAME@ : public gr_sync_block
 {
 private:
-  @NAME@ (const fsm &FSM, const int ST);
+  @NAME@ (const fsm &FSM, int ST);
 public:
   fsm FSM () const { return d_FSM; }
   int ST () const { return d_ST; }
index aecba87a4c282255d3519e1a25a17eb7d8819b17..cad4490ad0169510e403faaa86dfaecc3a3ee4eb 100644 (file)
 #include <iostream>
 
 trellis_encoder_bb_sptr 
-trellis_make_encoder_bb (const fsm &FSM, const int ST)
+trellis_make_encoder_bb (const fsm &FSM, int ST)
 {
   return trellis_encoder_bb_sptr (new trellis_encoder_bb (FSM,ST));
 }
 
-trellis_encoder_bb::trellis_encoder_bb (const fsm &FSM, const int ST)
+trellis_encoder_bb::trellis_encoder_bb (const fsm &FSM, int ST)
   : gr_sync_block ("encoder_bb",
                   gr_make_io_signature (1, -1, sizeof (unsigned char)),
                   gr_make_io_signature (1, -1, sizeof (unsigned char))),
@@ -50,26 +50,24 @@ trellis_encoder_bb::work (int noutput_items,
                        gr_vector_const_void_star &input_items,
                        gr_vector_void_star &output_items)
 {
-  int d_ST_tmp;
+  int ST_tmp;
 
   assert (input_items.size() == output_items.size());
   int nstreams = input_items.size();
 
-for (int m=0;m<nstreams;m++) {
-  const unsigned char *in = (const unsigned char *) input_items[m];
-  unsigned char *out = (unsigned char *) output_items[m];
-  d_ST_tmp = d_ST;
+  for (int m=0;m<nstreams;m++) {
+    const unsigned char *in = (const unsigned char *) input_items[m];
+    unsigned char *out = (unsigned char *) output_items[m];
+    ST_tmp = d_ST;
 
-// per stream processing
-
-  for (int i = 0; i < noutput_items; i++){
-    out[i] = (unsigned char) d_FSM.OS()[d_ST_tmp*d_FSM.I()+in[i]]; // direction of time?
-    d_ST_tmp = (int) d_FSM.NS()[d_ST_tmp*d_FSM.I()+in[i]];
+    // per stream processing
+    for (int i = 0; i < noutput_items; i++){
+      out[i] = (unsigned char) d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]]; // direction of time?
+      ST_tmp = (int) d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
+    }
+    // end per stream processing
   }
-
-// end per stream processing
-}
-  d_ST = d_ST_tmp;
+  d_ST = ST_tmp;
 
   return noutput_items;
 }
index a3817f2e7f71eaefb09879e9c668b00046b17e75..f2d7a3ace0141786669d291e93f37fcd6cffcf51 100644 (file)
@@ -31,7 +31,7 @@
 class trellis_encoder_bb;
 typedef boost::shared_ptr<trellis_encoder_bb> trellis_encoder_bb_sptr;
 
-trellis_encoder_bb_sptr trellis_make_encoder_bb (const fsm &FSM, const int ST);
+trellis_encoder_bb_sptr trellis_make_encoder_bb (const fsm &FSM, int ST);
 
 /*!
  * \brief Convolutional encoder.
@@ -42,10 +42,10 @@ trellis_encoder_bb_sptr trellis_make_encoder_bb (const fsm &FSM, const int ST);
 class trellis_encoder_bb : public gr_sync_block
 {
 private:
-  friend trellis_encoder_bb_sptr trellis_make_encoder_bb (const fsm &FSM, const int ST);
+  friend trellis_encoder_bb_sptr trellis_make_encoder_bb (const fsm &FSM, int ST);
   fsm d_FSM;
   int d_ST;
-  trellis_encoder_bb (const fsm &FSM, const int ST); 
+  trellis_encoder_bb (const fsm &FSM, int ST); 
 
 public:
   fsm FSM () const { return d_FSM; }
index 07f5606e639c46c6967f2855e449a0cd7d3e2b3e..4610d967ed3fe576acfddf42582f844188bd2e86 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,encoder_bb);
 
-trellis_encoder_bb_sptr trellis_make_encoder_bb (const fsm &FSM, const int ST);
+trellis_encoder_bb_sptr trellis_make_encoder_bb (const fsm &FSM, int ST);
 
 class trellis_encoder_bb : public gr_sync_block
 {
 private:
-  trellis_encoder_bb (const fsm &FSM, const int ST);
+  trellis_encoder_bb (const fsm &FSM, int ST);
 public:
   fsm FSM () const { return d_FSM; }
   int ST () const { return d_ST; }
index 968527b8f0b8e5ca14249e8e7e35262746c00ad7..d0848be6369b4a36441209993be53975fa6ddafa 100644 (file)
 #include <iostream>
 
 trellis_encoder_bi_sptr 
-trellis_make_encoder_bi (const fsm &FSM, const int ST)
+trellis_make_encoder_bi (const fsm &FSM, int ST)
 {
   return trellis_encoder_bi_sptr (new trellis_encoder_bi (FSM,ST));
 }
 
-trellis_encoder_bi::trellis_encoder_bi (const fsm &FSM, const int ST)
+trellis_encoder_bi::trellis_encoder_bi (const fsm &FSM, int ST)
   : gr_sync_block ("encoder_bi",
                   gr_make_io_signature (1, -1, sizeof (unsigned char)),
                   gr_make_io_signature (1, -1, sizeof (int))),
@@ -50,26 +50,24 @@ trellis_encoder_bi::work (int noutput_items,
                        gr_vector_const_void_star &input_items,
                        gr_vector_void_star &output_items)
 {
-  int d_ST_tmp;
+  int ST_tmp;
 
   assert (input_items.size() == output_items.size());
   int nstreams = input_items.size();
 
-for (int m=0;m<nstreams;m++) {
-  const unsigned char *in = (const unsigned char *) input_items[m];
-  int *out = (int *) output_items[m];
-  d_ST_tmp = d_ST;
+  for (int m=0;m<nstreams;m++) {
+    const unsigned char *in = (const unsigned char *) input_items[m];
+    int *out = (int *) output_items[m];
+    ST_tmp = d_ST;
 
-// per stream processing
-
-  for (int i = 0; i < noutput_items; i++){
-    out[i] = (int) d_FSM.OS()[d_ST_tmp*d_FSM.I()+in[i]]; // direction of time?
-    d_ST_tmp = (int) d_FSM.NS()[d_ST_tmp*d_FSM.I()+in[i]];
+    // per stream processing
+    for (int i = 0; i < noutput_items; i++){
+      out[i] = (int) d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]]; // direction of time?
+      ST_tmp = (int) d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
+    }
+    // end per stream processing
   }
-
-// end per stream processing
-}
-  d_ST = d_ST_tmp;
+  d_ST = ST_tmp;
 
   return noutput_items;
 }
index 5212f641666819ad8eab01f6addcf9ca0d01073c..d86f38b686c6a7d217df57bae3db50b2ccecffe7 100644 (file)
@@ -31,7 +31,7 @@
 class trellis_encoder_bi;
 typedef boost::shared_ptr<trellis_encoder_bi> trellis_encoder_bi_sptr;
 
-trellis_encoder_bi_sptr trellis_make_encoder_bi (const fsm &FSM, const int ST);
+trellis_encoder_bi_sptr trellis_make_encoder_bi (const fsm &FSM, int ST);
 
 /*!
  * \brief Convolutional encoder.
@@ -42,10 +42,10 @@ trellis_encoder_bi_sptr trellis_make_encoder_bi (const fsm &FSM, const int ST);
 class trellis_encoder_bi : public gr_sync_block
 {
 private:
-  friend trellis_encoder_bi_sptr trellis_make_encoder_bi (const fsm &FSM, const int ST);
+  friend trellis_encoder_bi_sptr trellis_make_encoder_bi (const fsm &FSM, int ST);
   fsm d_FSM;
   int d_ST;
-  trellis_encoder_bi (const fsm &FSM, const int ST); 
+  trellis_encoder_bi (const fsm &FSM, int ST); 
 
 public:
   fsm FSM () const { return d_FSM; }
index 4fd389e943583e46730961b2712168a0e08d534d..06531196ecd583157d636a24491867996930ada3 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,encoder_bi);
 
-trellis_encoder_bi_sptr trellis_make_encoder_bi (const fsm &FSM, const int ST);
+trellis_encoder_bi_sptr trellis_make_encoder_bi (const fsm &FSM, int ST);
 
 class trellis_encoder_bi : public gr_sync_block
 {
 private:
-  trellis_encoder_bi (const fsm &FSM, const int ST);
+  trellis_encoder_bi (const fsm &FSM, int ST);
 public:
   fsm FSM () const { return d_FSM; }
   int ST () const { return d_ST; }
index 9546e3d9d7dbd6233d83c26cdb5f80b3d3d1b193..34876044bb908c93bbee07c824eaa04659735431 100644 (file)
 #include <iostream>
 
 trellis_encoder_bs_sptr 
-trellis_make_encoder_bs (const fsm &FSM, const int ST)
+trellis_make_encoder_bs (const fsm &FSM, int ST)
 {
   return trellis_encoder_bs_sptr (new trellis_encoder_bs (FSM,ST));
 }
 
-trellis_encoder_bs::trellis_encoder_bs (const fsm &FSM, const int ST)
+trellis_encoder_bs::trellis_encoder_bs (const fsm &FSM, int ST)
   : gr_sync_block ("encoder_bs",
                   gr_make_io_signature (1, -1, sizeof (unsigned char)),
                   gr_make_io_signature (1, -1, sizeof (short))),
@@ -50,26 +50,24 @@ trellis_encoder_bs::work (int noutput_items,
                        gr_vector_const_void_star &input_items,
                        gr_vector_void_star &output_items)
 {
-  int d_ST_tmp;
+  int ST_tmp;
 
   assert (input_items.size() == output_items.size());
   int nstreams = input_items.size();
 
-for (int m=0;m<nstreams;m++) {
-  const unsigned char *in = (const unsigned char *) input_items[m];
-  short *out = (short *) output_items[m];
-  d_ST_tmp = d_ST;
+  for (int m=0;m<nstreams;m++) {
+    const unsigned char *in = (const unsigned char *) input_items[m];
+    short *out = (short *) output_items[m];
+    ST_tmp = d_ST;
 
-// per stream processing
-
-  for (int i = 0; i < noutput_items; i++){
-    out[i] = (short) d_FSM.OS()[d_ST_tmp*d_FSM.I()+in[i]]; // direction of time?
-    d_ST_tmp = (int) d_FSM.NS()[d_ST_tmp*d_FSM.I()+in[i]];
+    // per stream processing
+    for (int i = 0; i < noutput_items; i++){
+      out[i] = (short) d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]]; // direction of time?
+      ST_tmp = (int) d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
+    }
+    // end per stream processing
   }
-
-// end per stream processing
-}
-  d_ST = d_ST_tmp;
+  d_ST = ST_tmp;
 
   return noutput_items;
 }
index 2ddf5505c6fc208e2b66f02dc00d7b32513bbe77..d0a99ffe7a1049dc76486bf87c28277bf49f5d1d 100644 (file)
@@ -31,7 +31,7 @@
 class trellis_encoder_bs;
 typedef boost::shared_ptr<trellis_encoder_bs> trellis_encoder_bs_sptr;
 
-trellis_encoder_bs_sptr trellis_make_encoder_bs (const fsm &FSM, const int ST);
+trellis_encoder_bs_sptr trellis_make_encoder_bs (const fsm &FSM, int ST);
 
 /*!
  * \brief Convolutional encoder.
@@ -42,10 +42,10 @@ trellis_encoder_bs_sptr trellis_make_encoder_bs (const fsm &FSM, const int ST);
 class trellis_encoder_bs : public gr_sync_block
 {
 private:
-  friend trellis_encoder_bs_sptr trellis_make_encoder_bs (const fsm &FSM, const int ST);
+  friend trellis_encoder_bs_sptr trellis_make_encoder_bs (const fsm &FSM, int ST);
   fsm d_FSM;
   int d_ST;
-  trellis_encoder_bs (const fsm &FSM, const int ST); 
+  trellis_encoder_bs (const fsm &FSM, int ST); 
 
 public:
   fsm FSM () const { return d_FSM; }
index 51fc1d481ed00f0e27e948afac221fd2ef97e6d4..5179aaa84ce8ca759512e3853528695000d107d9 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,encoder_bs);
 
-trellis_encoder_bs_sptr trellis_make_encoder_bs (const fsm &FSM, const int ST);
+trellis_encoder_bs_sptr trellis_make_encoder_bs (const fsm &FSM, int ST);
 
 class trellis_encoder_bs : public gr_sync_block
 {
 private:
-  trellis_encoder_bs (const fsm &FSM, const int ST);
+  trellis_encoder_bs (const fsm &FSM, int ST);
 public:
   fsm FSM () const { return d_FSM; }
   int ST () const { return d_ST; }
index 3469a235d8484c7dc536b6cce65ac59dd446cdf7..11e3a4fdb755c1d342eadf4835967340e791fe9e 100644 (file)
 #include <iostream>
 
 trellis_encoder_ii_sptr 
-trellis_make_encoder_ii (const fsm &FSM, const int ST)
+trellis_make_encoder_ii (const fsm &FSM, int ST)
 {
   return trellis_encoder_ii_sptr (new trellis_encoder_ii (FSM,ST));
 }
 
-trellis_encoder_ii::trellis_encoder_ii (const fsm &FSM, const int ST)
+trellis_encoder_ii::trellis_encoder_ii (const fsm &FSM, int ST)
   : gr_sync_block ("encoder_ii",
                   gr_make_io_signature (1, -1, sizeof (int)),
                   gr_make_io_signature (1, -1, sizeof (int))),
@@ -50,26 +50,24 @@ trellis_encoder_ii::work (int noutput_items,
                        gr_vector_const_void_star &input_items,
                        gr_vector_void_star &output_items)
 {
-  int d_ST_tmp;
+  int ST_tmp;
 
   assert (input_items.size() == output_items.size());
   int nstreams = input_items.size();
 
-for (int m=0;m<nstreams;m++) {
-  const int *in = (const int *) input_items[m];
-  int *out = (int *) output_items[m];
-  d_ST_tmp = d_ST;
+  for (int m=0;m<nstreams;m++) {
+    const int *in = (const int *) input_items[m];
+    int *out = (int *) output_items[m];
+    ST_tmp = d_ST;
 
-// per stream processing
-
-  for (int i = 0; i < noutput_items; i++){
-    out[i] = (int) d_FSM.OS()[d_ST_tmp*d_FSM.I()+in[i]]; // direction of time?
-    d_ST_tmp = (int) d_FSM.NS()[d_ST_tmp*d_FSM.I()+in[i]];
+    // per stream processing
+    for (int i = 0; i < noutput_items; i++){
+      out[i] = (int) d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]]; // direction of time?
+      ST_tmp = (int) d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
+    }
+    // end per stream processing
   }
-
-// end per stream processing
-}
-  d_ST = d_ST_tmp;
+  d_ST = ST_tmp;
 
   return noutput_items;
 }
index b0a9cee02af8c0926383d94ec8459f523e1c7553..091e3ede320eaf8fbc1b50f10d182062927cba99 100644 (file)
@@ -31,7 +31,7 @@
 class trellis_encoder_ii;
 typedef boost::shared_ptr<trellis_encoder_ii> trellis_encoder_ii_sptr;
 
-trellis_encoder_ii_sptr trellis_make_encoder_ii (const fsm &FSM, const int ST);
+trellis_encoder_ii_sptr trellis_make_encoder_ii (const fsm &FSM, int ST);
 
 /*!
  * \brief Convolutional encoder.
@@ -42,10 +42,10 @@ trellis_encoder_ii_sptr trellis_make_encoder_ii (const fsm &FSM, const int ST);
 class trellis_encoder_ii : public gr_sync_block
 {
 private:
-  friend trellis_encoder_ii_sptr trellis_make_encoder_ii (const fsm &FSM, const int ST);
+  friend trellis_encoder_ii_sptr trellis_make_encoder_ii (const fsm &FSM, int ST);
   fsm d_FSM;
   int d_ST;
-  trellis_encoder_ii (const fsm &FSM, const int ST); 
+  trellis_encoder_ii (const fsm &FSM, int ST); 
 
 public:
   fsm FSM () const { return d_FSM; }
index c05cbb36c70a8501113b7569261ead17ecbdfd63..aaf36d7819b0ea469d432f0db621f9f75e0a9f38 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,encoder_ii);
 
-trellis_encoder_ii_sptr trellis_make_encoder_ii (const fsm &FSM, const int ST);
+trellis_encoder_ii_sptr trellis_make_encoder_ii (const fsm &FSM, int ST);
 
 class trellis_encoder_ii : public gr_sync_block
 {
 private:
-  trellis_encoder_ii (const fsm &FSM, const int ST);
+  trellis_encoder_ii (const fsm &FSM, int ST);
 public:
   fsm FSM () const { return d_FSM; }
   int ST () const { return d_ST; }
index 581ffe28613e8e3193bf19cf3269ee3fe42f809e..c2b6463da5eb75ec305deec7c45f4f8f8a11ae7d 100644 (file)
 #include <iostream>
 
 trellis_encoder_si_sptr 
-trellis_make_encoder_si (const fsm &FSM, const int ST)
+trellis_make_encoder_si (const fsm &FSM, int ST)
 {
   return trellis_encoder_si_sptr (new trellis_encoder_si (FSM,ST));
 }
 
-trellis_encoder_si::trellis_encoder_si (const fsm &FSM, const int ST)
+trellis_encoder_si::trellis_encoder_si (const fsm &FSM, int ST)
   : gr_sync_block ("encoder_si",
                   gr_make_io_signature (1, -1, sizeof (short)),
                   gr_make_io_signature (1, -1, sizeof (int))),
@@ -50,26 +50,24 @@ trellis_encoder_si::work (int noutput_items,
                        gr_vector_const_void_star &input_items,
                        gr_vector_void_star &output_items)
 {
-  int d_ST_tmp;
+  int ST_tmp;
 
   assert (input_items.size() == output_items.size());
   int nstreams = input_items.size();
 
-for (int m=0;m<nstreams;m++) {
-  const short *in = (const short *) input_items[m];
-  int *out = (int *) output_items[m];
-  d_ST_tmp = d_ST;
+  for (int m=0;m<nstreams;m++) {
+    const short *in = (const short *) input_items[m];
+    int *out = (int *) output_items[m];
+    ST_tmp = d_ST;
 
-// per stream processing
-
-  for (int i = 0; i < noutput_items; i++){
-    out[i] = (int) d_FSM.OS()[d_ST_tmp*d_FSM.I()+in[i]]; // direction of time?
-    d_ST_tmp = (int) d_FSM.NS()[d_ST_tmp*d_FSM.I()+in[i]];
+    // per stream processing
+    for (int i = 0; i < noutput_items; i++){
+      out[i] = (int) d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]]; // direction of time?
+      ST_tmp = (int) d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
+    }
+    // end per stream processing
   }
-
-// end per stream processing
-}
-  d_ST = d_ST_tmp;
+  d_ST = ST_tmp;
 
   return noutput_items;
 }
index d42db7a99bf5f02b921084bf175c8e83039be072..969763dc1042344c4a0851d0432e92045dc6a62b 100644 (file)
@@ -31,7 +31,7 @@
 class trellis_encoder_si;
 typedef boost::shared_ptr<trellis_encoder_si> trellis_encoder_si_sptr;
 
-trellis_encoder_si_sptr trellis_make_encoder_si (const fsm &FSM, const int ST);
+trellis_encoder_si_sptr trellis_make_encoder_si (const fsm &FSM, int ST);
 
 /*!
  * \brief Convolutional encoder.
@@ -42,10 +42,10 @@ trellis_encoder_si_sptr trellis_make_encoder_si (const fsm &FSM, const int ST);
 class trellis_encoder_si : public gr_sync_block
 {
 private:
-  friend trellis_encoder_si_sptr trellis_make_encoder_si (const fsm &FSM, const int ST);
+  friend trellis_encoder_si_sptr trellis_make_encoder_si (const fsm &FSM, int ST);
   fsm d_FSM;
   int d_ST;
-  trellis_encoder_si (const fsm &FSM, const int ST); 
+  trellis_encoder_si (const fsm &FSM, int ST); 
 
 public:
   fsm FSM () const { return d_FSM; }
index e1166a6f203114dd6c5eff1bb455dadd1f1d296e..0d8a16bdcbc51178c608767ca31fd620126f5c45 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,encoder_si);
 
-trellis_encoder_si_sptr trellis_make_encoder_si (const fsm &FSM, const int ST);
+trellis_encoder_si_sptr trellis_make_encoder_si (const fsm &FSM, int ST);
 
 class trellis_encoder_si : public gr_sync_block
 {
 private:
-  trellis_encoder_si (const fsm &FSM, const int ST);
+  trellis_encoder_si (const fsm &FSM, int ST);
 public:
   fsm FSM () const { return d_FSM; }
   int ST () const { return d_ST; }
index 96604a34bb4085aef86bd8d136ab271fdc22f704..3d0016b62e42cc66ff1969943ba20bcdcaa95052 100644 (file)
 #include <iostream>
 
 trellis_encoder_ss_sptr 
-trellis_make_encoder_ss (const fsm &FSM, const int ST)
+trellis_make_encoder_ss (const fsm &FSM, int ST)
 {
   return trellis_encoder_ss_sptr (new trellis_encoder_ss (FSM,ST));
 }
 
-trellis_encoder_ss::trellis_encoder_ss (const fsm &FSM, const int ST)
+trellis_encoder_ss::trellis_encoder_ss (const fsm &FSM, int ST)
   : gr_sync_block ("encoder_ss",
                   gr_make_io_signature (1, -1, sizeof (short)),
                   gr_make_io_signature (1, -1, sizeof (short))),
@@ -50,26 +50,24 @@ trellis_encoder_ss::work (int noutput_items,
                        gr_vector_const_void_star &input_items,
                        gr_vector_void_star &output_items)
 {
-  int d_ST_tmp;
+  int ST_tmp;
 
   assert (input_items.size() == output_items.size());
   int nstreams = input_items.size();
 
-for (int m=0;m<nstreams;m++) {
-  const short *in = (const short *) input_items[m];
-  short *out = (short *) output_items[m];
-  d_ST_tmp = d_ST;
+  for (int m=0;m<nstreams;m++) {
+    const short *in = (const short *) input_items[m];
+    short *out = (short *) output_items[m];
+    ST_tmp = d_ST;
 
-// per stream processing
-
-  for (int i = 0; i < noutput_items; i++){
-    out[i] = (short) d_FSM.OS()[d_ST_tmp*d_FSM.I()+in[i]]; // direction of time?
-    d_ST_tmp = (int) d_FSM.NS()[d_ST_tmp*d_FSM.I()+in[i]];
+    // per stream processing
+    for (int i = 0; i < noutput_items; i++){
+      out[i] = (short) d_FSM.OS()[ST_tmp*d_FSM.I()+in[i]]; // direction of time?
+      ST_tmp = (int) d_FSM.NS()[ST_tmp*d_FSM.I()+in[i]];
+    }
+    // end per stream processing
   }
-
-// end per stream processing
-}
-  d_ST = d_ST_tmp;
+  d_ST = ST_tmp;
 
   return noutput_items;
 }
index 96e1a19bdf52dfd54e919751ce76c2c6b0261309..2254306eb40d3a313fdc089f7d63195642864b1f 100644 (file)
@@ -31,7 +31,7 @@
 class trellis_encoder_ss;
 typedef boost::shared_ptr<trellis_encoder_ss> trellis_encoder_ss_sptr;
 
-trellis_encoder_ss_sptr trellis_make_encoder_ss (const fsm &FSM, const int ST);
+trellis_encoder_ss_sptr trellis_make_encoder_ss (const fsm &FSM, int ST);
 
 /*!
  * \brief Convolutional encoder.
@@ -42,10 +42,10 @@ trellis_encoder_ss_sptr trellis_make_encoder_ss (const fsm &FSM, const int ST);
 class trellis_encoder_ss : public gr_sync_block
 {
 private:
-  friend trellis_encoder_ss_sptr trellis_make_encoder_ss (const fsm &FSM, const int ST);
+  friend trellis_encoder_ss_sptr trellis_make_encoder_ss (const fsm &FSM, int ST);
   fsm d_FSM;
   int d_ST;
-  trellis_encoder_ss (const fsm &FSM, const int ST); 
+  trellis_encoder_ss (const fsm &FSM, int ST); 
 
 public:
   fsm FSM () const { return d_FSM; }
index ac194306f10e9589e0013fca820a05af8ee9d46b..8cb1d8ef6e9348f0d087ca223cc71681e2c5fa1b 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,encoder_ss);
 
-trellis_encoder_ss_sptr trellis_make_encoder_ss (const fsm &FSM, const int ST);
+trellis_encoder_ss_sptr trellis_make_encoder_ss (const fsm &FSM, int ST);
 
 class trellis_encoder_ss : public gr_sync_block
 {
 private:
-  trellis_encoder_ss (const fsm &FSM, const int ST);
+  trellis_encoder_ss (const fsm &FSM, int ST);
 public:
   fsm FSM () const { return d_FSM; }
   int ST () const { return d_ST; }
index 2dd1adb12d658c3b3c5d534ce8f14cda83355565..7ace0298a575bd3a02e3957199ab51b706ef17d5 100644 (file)
 
 
 @SPTR_NAME@
-trellis_make_@BASE_NAME@ (const int O, const int D,  const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE)
+trellis_make_@BASE_NAME@ (int O, int D,  const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE)
 {
   return @SPTR_NAME@ (new @NAME@ (O,D,TABLE,TYPE));
 }
 
 
 
-@NAME@::@NAME@ (const int O, const int D,  const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE)
+@NAME@::@NAME@ (int O, int D,  const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE)
   : gr_block ("@BASE_NAME@",
              gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
              gr_make_io_signature (1, -1, sizeof (float))),
index 626791dd45348c76078d30f57afa8508ce8ba8c1..ef01793ab76296336a876f39dc5a93de85358143 100644 (file)
@@ -31,7 +31,7 @@
 class @NAME@;
 typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
 
-@SPTR_NAME@ trellis_make_@BASE_NAME@ (const int O, const int D,  const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE);
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (int O, int D,  const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE);
 
 /*!
  * \brief Evaluate metrics for use by the Viterbi algorithm.
@@ -45,8 +45,8 @@ class @NAME@ : public gr_block
   trellis_metric_type_t d_TYPE;
   std::vector<@I_TYPE@> d_TABLE;
 
-  friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (const int O, const int D,  const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE);
-  @NAME@ (const int O, const int D,  const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE);
+  friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (int O, int D,  const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE);
+  @NAME@ (int O, int D,  const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE);
 
 public:
   int O () const { return d_O; }
index 2fc3ba8ffb0d2f0afd3796392f66bfd4f83bce5c..1687d8fb4201cba753e66e41365d38d3d113924b 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@);
 
-@SPTR_NAME@ trellis_make_@BASE_NAME@ (const int O, const int D, const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE);
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (int O, int D, const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE);
 
 class @NAME@ : public gr_block
 {
 private:
-  @NAME@ (const int O, const int D, const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE);
+  @NAME@ (int O, int D, const std::vector<@I_TYPE@> &TABLE, trellis_metric_type_t TYPE);
 
 public:
   int O () const { return d_O; }
index ea1808e831908fd335292b0a7c9bf89401e2b471..d80f2e7d7b7386e9ec7213cbc0415864e2f6f8be 100644 (file)
 
 
 trellis_metrics_c_sptr
-trellis_make_metrics_c (const int O, const int D,  const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE)
+trellis_make_metrics_c (int O, int D,  const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE)
 {
   return trellis_metrics_c_sptr (new trellis_metrics_c (O,D,TABLE,TYPE));
 }
 
 
 
-trellis_metrics_c::trellis_metrics_c (const int O, const int D,  const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE)
+trellis_metrics_c::trellis_metrics_c (int O, int D,  const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE)
   : gr_block ("metrics_c",
              gr_make_io_signature (1, -1, sizeof (gr_complex)),
              gr_make_io_signature (1, -1, sizeof (float))),
index 5de578401f5144868e809db640a9b214714afbe7..57a549cb7e19b40a7aac3e0fa93c78f0ed9b95aa 100644 (file)
@@ -31,7 +31,7 @@
 class trellis_metrics_c;
 typedef boost::shared_ptr<trellis_metrics_c> trellis_metrics_c_sptr;
 
-trellis_metrics_c_sptr trellis_make_metrics_c (const int O, const int D,  const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE);
+trellis_metrics_c_sptr trellis_make_metrics_c (int O, int D,  const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE);
 
 /*!
  * \brief Evaluate metrics for use by the Viterbi algorithm.
@@ -45,8 +45,8 @@ class trellis_metrics_c : public gr_block
   trellis_metric_type_t d_TYPE;
   std::vector<gr_complex> d_TABLE;
 
-  friend trellis_metrics_c_sptr trellis_make_metrics_c (const int O, const int D,  const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE);
-  trellis_metrics_c (const int O, const int D,  const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE);
+  friend trellis_metrics_c_sptr trellis_make_metrics_c (int O, int D,  const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE);
+  trellis_metrics_c (int O, int D,  const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE);
 
 public:
   int O () const { return d_O; }
index 6813cb946e8e9942c5b17a2bcb16d1fcfeae8a2e..cb5a116d046dfe3ac829a7b5cce5a501cc02f2d5 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,metrics_c);
 
-trellis_metrics_c_sptr trellis_make_metrics_c (const int O, const int D, const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE);
+trellis_metrics_c_sptr trellis_make_metrics_c (int O, int D, const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE);
 
 class trellis_metrics_c : public gr_block
 {
 private:
-  trellis_metrics_c (const int O, const int D, const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE);
+  trellis_metrics_c (int O, int D, const std::vector<gr_complex> &TABLE, trellis_metric_type_t TYPE);
 
 public:
   int O () const { return d_O; }
index 2e148bbd550f2822a094ded4932d9a69781b8c7b..69e4a99df692a7ed63e9277cc7b4fb46c5734e86 100644 (file)
 
 
 trellis_metrics_f_sptr
-trellis_make_metrics_f (const int O, const int D,  const std::vector<float> &TABLE, trellis_metric_type_t TYPE)
+trellis_make_metrics_f (int O, int D,  const std::vector<float> &TABLE, trellis_metric_type_t TYPE)
 {
   return trellis_metrics_f_sptr (new trellis_metrics_f (O,D,TABLE,TYPE));
 }
 
 
 
-trellis_metrics_f::trellis_metrics_f (const int O, const int D,  const std::vector<float> &TABLE, trellis_metric_type_t TYPE)
+trellis_metrics_f::trellis_metrics_f (int O, int D,  const std::vector<float> &TABLE, trellis_metric_type_t TYPE)
   : gr_block ("metrics_f",
              gr_make_io_signature (1, -1, sizeof (float)),
              gr_make_io_signature (1, -1, sizeof (float))),
index b668c08d0628eb185a4ed0890b59789b708ed9db..44a9152f98c7e43fe892024adad8d183511a6bcf 100644 (file)
@@ -31,7 +31,7 @@
 class trellis_metrics_f;
 typedef boost::shared_ptr<trellis_metrics_f> trellis_metrics_f_sptr;
 
-trellis_metrics_f_sptr trellis_make_metrics_f (const int O, const int D,  const std::vector<float> &TABLE, trellis_metric_type_t TYPE);
+trellis_metrics_f_sptr trellis_make_metrics_f (int O, int D,  const std::vector<float> &TABLE, trellis_metric_type_t TYPE);
 
 /*!
  * \brief Evaluate metrics for use by the Viterbi algorithm.
@@ -45,8 +45,8 @@ class trellis_metrics_f : public gr_block
   trellis_metric_type_t d_TYPE;
   std::vector<float> d_TABLE;
 
-  friend trellis_metrics_f_sptr trellis_make_metrics_f (const int O, const int D,  const std::vector<float> &TABLE, trellis_metric_type_t TYPE);
-  trellis_metrics_f (const int O, const int D,  const std::vector<float> &TABLE, trellis_metric_type_t TYPE);
+  friend trellis_metrics_f_sptr trellis_make_metrics_f (int O, int D,  const std::vector<float> &TABLE, trellis_metric_type_t TYPE);
+  trellis_metrics_f (int O, int D,  const std::vector<float> &TABLE, trellis_metric_type_t TYPE);
 
 public:
   int O () const { return d_O; }
index e808af168882badae37338a103ddf96fbb463642..a0dac39f2b5cb62db221932faad275c207b99a6f 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,metrics_f);
 
-trellis_metrics_f_sptr trellis_make_metrics_f (const int O, const int D, const std::vector<float> &TABLE, trellis_metric_type_t TYPE);
+trellis_metrics_f_sptr trellis_make_metrics_f (int O, int D, const std::vector<float> &TABLE, trellis_metric_type_t TYPE);
 
 class trellis_metrics_f : public gr_block
 {
 private:
-  trellis_metrics_f (const int O, const int D, const std::vector<float> &TABLE, trellis_metric_type_t TYPE);
+  trellis_metrics_f (int O, int D, const std::vector<float> &TABLE, trellis_metric_type_t TYPE);
 
 public:
   int O () const { return d_O; }
index 5901c551366386e19af42aa33541a7e8f764c1da..b0fa85fa0b857e142cb2dc2ea6e96740cd910da8 100644 (file)
 
 
 trellis_metrics_i_sptr
-trellis_make_metrics_i (const int O, const int D,  const std::vector<int> &TABLE, trellis_metric_type_t TYPE)
+trellis_make_metrics_i (int O, int D,  const std::vector<int> &TABLE, trellis_metric_type_t TYPE)
 {
   return trellis_metrics_i_sptr (new trellis_metrics_i (O,D,TABLE,TYPE));
 }
 
 
 
-trellis_metrics_i::trellis_metrics_i (const int O, const int D,  const std::vector<int> &TABLE, trellis_metric_type_t TYPE)
+trellis_metrics_i::trellis_metrics_i (int O, int D,  const std::vector<int> &TABLE, trellis_metric_type_t TYPE)
   : gr_block ("metrics_i",
              gr_make_io_signature (1, -1, sizeof (int)),
              gr_make_io_signature (1, -1, sizeof (float))),
index c51e377e7055138406be24f68e9b549b88a154b9..6e46eef60a938a0a1841f4235fae1f850fa07eb0 100644 (file)
@@ -31,7 +31,7 @@
 class trellis_metrics_i;
 typedef boost::shared_ptr<trellis_metrics_i> trellis_metrics_i_sptr;
 
-trellis_metrics_i_sptr trellis_make_metrics_i (const int O, const int D,  const std::vector<int> &TABLE, trellis_metric_type_t TYPE);
+trellis_metrics_i_sptr trellis_make_metrics_i (int O, int D,  const std::vector<int> &TABLE, trellis_metric_type_t TYPE);
 
 /*!
  * \brief Evaluate metrics for use by the Viterbi algorithm.
@@ -45,8 +45,8 @@ class trellis_metrics_i : public gr_block
   trellis_metric_type_t d_TYPE;
   std::vector<int> d_TABLE;
 
-  friend trellis_metrics_i_sptr trellis_make_metrics_i (const int O, const int D,  const std::vector<int> &TABLE, trellis_metric_type_t TYPE);
-  trellis_metrics_i (const int O, const int D,  const std::vector<int> &TABLE, trellis_metric_type_t TYPE);
+  friend trellis_metrics_i_sptr trellis_make_metrics_i (int O, int D,  const std::vector<int> &TABLE, trellis_metric_type_t TYPE);
+  trellis_metrics_i (int O, int D,  const std::vector<int> &TABLE, trellis_metric_type_t TYPE);
 
 public:
   int O () const { return d_O; }
index dadd065770b68c8403a28a267f9d40952a7b7884..5e217d1db9f16f614b2e4409ede980cabb306bb4 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,metrics_i);
 
-trellis_metrics_i_sptr trellis_make_metrics_i (const int O, const int D, const std::vector<int> &TABLE, trellis_metric_type_t TYPE);
+trellis_metrics_i_sptr trellis_make_metrics_i (int O, int D, const std::vector<int> &TABLE, trellis_metric_type_t TYPE);
 
 class trellis_metrics_i : public gr_block
 {
 private:
-  trellis_metrics_i (const int O, const int D, const std::vector<int> &TABLE, trellis_metric_type_t TYPE);
+  trellis_metrics_i (int O, int D, const std::vector<int> &TABLE, trellis_metric_type_t TYPE);
 
 public:
   int O () const { return d_O; }
index 3bee2cc92a836773420ab181faa31c1b8fcaf861..07b4097262ba1c0d35e0dc18e6c303dfebbfde48 100644 (file)
 
 
 trellis_metrics_s_sptr
-trellis_make_metrics_s (const int O, const int D,  const std::vector<short> &TABLE, trellis_metric_type_t TYPE)
+trellis_make_metrics_s (int O, int D,  const std::vector<short> &TABLE, trellis_metric_type_t TYPE)
 {
   return trellis_metrics_s_sptr (new trellis_metrics_s (O,D,TABLE,TYPE));
 }
 
 
 
-trellis_metrics_s::trellis_metrics_s (const int O, const int D,  const std::vector<short> &TABLE, trellis_metric_type_t TYPE)
+trellis_metrics_s::trellis_metrics_s (int O, int D,  const std::vector<short> &TABLE, trellis_metric_type_t TYPE)
   : gr_block ("metrics_s",
              gr_make_io_signature (1, -1, sizeof (short)),
              gr_make_io_signature (1, -1, sizeof (float))),
index b4332bcc340534532e999a9e03d0605b39be1786..abd027e50b2c637b86d7613f248f9e62bae613be 100644 (file)
@@ -31,7 +31,7 @@
 class trellis_metrics_s;
 typedef boost::shared_ptr<trellis_metrics_s> trellis_metrics_s_sptr;
 
-trellis_metrics_s_sptr trellis_make_metrics_s (const int O, const int D,  const std::vector<short> &TABLE, trellis_metric_type_t TYPE);
+trellis_metrics_s_sptr trellis_make_metrics_s (int O, int D,  const std::vector<short> &TABLE, trellis_metric_type_t TYPE);
 
 /*!
  * \brief Evaluate metrics for use by the Viterbi algorithm.
@@ -45,8 +45,8 @@ class trellis_metrics_s : public gr_block
   trellis_metric_type_t d_TYPE;
   std::vector<short> d_TABLE;
 
-  friend trellis_metrics_s_sptr trellis_make_metrics_s (const int O, const int D,  const std::vector<short> &TABLE, trellis_metric_type_t TYPE);
-  trellis_metrics_s (const int O, const int D,  const std::vector<short> &TABLE, trellis_metric_type_t TYPE);
+  friend trellis_metrics_s_sptr trellis_make_metrics_s (int O, int D,  const std::vector<short> &TABLE, trellis_metric_type_t TYPE);
+  trellis_metrics_s (int O, int D,  const std::vector<short> &TABLE, trellis_metric_type_t TYPE);
 
 public:
   int O () const { return d_O; }
index d7529a3e11ee0de22e70ee97d0507f9150d6aa84..86830f7781fff60e742599e7d739921ada82df45 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,metrics_s);
 
-trellis_metrics_s_sptr trellis_make_metrics_s (const int O, const int D, const std::vector<short> &TABLE, trellis_metric_type_t TYPE);
+trellis_metrics_s_sptr trellis_make_metrics_s (int O, int D, const std::vector<short> &TABLE, trellis_metric_type_t TYPE);
 
 class trellis_metrics_s : public gr_block
 {
 private:
-  trellis_metrics_s (const int O, const int D, const std::vector<short> &TABLE, trellis_metric_type_t TYPE);
+  trellis_metrics_s (int O, int D, const std::vector<short> &TABLE, trellis_metric_type_t TYPE);
 
 public:
   int O () const { return d_O; }
index 78bdbaf461b181d75639c5743c4537a1702c73cd..88e546a49b31804a49eb45e5ddcd724544419b36 100644 (file)
 #include <iostream>
 
 trellis_permutation_sptr 
-trellis_make_permutation (const int K, const std::vector<int> &TABLE, const size_t NBYTES)
+trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT)
 {
-  return trellis_permutation_sptr (new trellis_permutation (K,TABLE,NBYTES));
+  return trellis_permutation_sptr (new trellis_permutation (K,TABLE,SYMS_PER_BLOCK,NBYTES_INOUT));
 }
 
-trellis_permutation::trellis_permutation (const int K, const std::vector<int> &TABLE, const size_t NBYTES)
+trellis_permutation::trellis_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT)
   : gr_sync_block ("permutation",
-                  gr_make_io_signature (1, -1, NBYTES),
-                  gr_make_io_signature (1, -1, NBYTES)),
+                  gr_make_io_signature (1, -1, NBYTES_INOUT),
+                  gr_make_io_signature (1, -1, NBYTES_INOUT)),
     d_K (K),
     d_TABLE (TABLE),
-    d_NBYTES (NBYTES)
+    d_SYMS_PER_BLOCK (SYMS_PER_BLOCK),
+    d_NBYTES_INOUT (NBYTES_INOUT)
 {
-    set_output_multiple (d_K);
+    set_output_multiple (d_K*SYMS_PER_BLOCK);
     //std::cout << d_K << "\n";
 }
 
@@ -56,16 +57,23 @@ trellis_permutation::work (int noutput_items,
   int nstreams = input_items.size();
   assert (input_items.size() == output_items.size());
   assert (noutput_items % d_K ==0);
-  //std::cout << noutput_items << "\n";
 
   for (int m=0;m<nstreams;m++) {
     const char *in = (const char *) input_items[m];
     char *out = (char *) output_items[m];
 
     // per stream processing
-    for (unsigned int i = 0; i < noutput_items; i++){
-      //std::cout << i << " " << i*d_NBYTES << " " << (d_K*(i/d_K)+d_TABLE[i%d_K])*d_NBYTES  << "\n";
-      memcpy(&(out[i*d_NBYTES]), &(in[(d_K*(i/d_K)+d_TABLE[i%d_K])*d_NBYTES]), d_NBYTES);
+    for (int i = 0; i < noutput_items/d_SYMS_PER_BLOCK; i++){
+      // Index i refers to blocks.
+      // Begining of packet (in blocks)
+      int i0 = d_K*(i/d_K); 
+      // position of block within packet (in blocks)
+      int j0 = i%d_K;
+      // new position of block within packet (in blocks)
+      int k0 = d_TABLE[j0];
+      memcpy(&(out[i*d_SYMS_PER_BLOCK*d_NBYTES_INOUT]), 
+             &(in[(i0+k0)*d_SYMS_PER_BLOCK*d_NBYTES_INOUT]), 
+             d_NBYTES_INOUT*d_SYMS_PER_BLOCK);
     }
     // end per stream processing
   }
index 815ed397683e642577c8bd10c7f572959d701758..39c5b7c9c37bc8d266c7469eaa15a6d7f50294c6 100644 (file)
@@ -30,7 +30,7 @@
 class trellis_permutation;
 typedef boost::shared_ptr<trellis_permutation> trellis_permutation_sptr;
 
-trellis_permutation_sptr trellis_make_permutation (const int K, const std::vector<int> &TABLE, const size_t NBYTES);
+trellis_permutation_sptr trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT);
 
 /*!
  * \brief Permutation.
@@ -41,16 +41,18 @@ trellis_permutation_sptr trellis_make_permutation (const int K, const std::vecto
 class trellis_permutation : public gr_sync_block
 {
 private:
-  friend trellis_permutation_sptr trellis_make_permutation (const int K, const std::vector<int> &TABLE, const size_t NBYTES);
+  friend trellis_permutation_sptr trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT);
   int d_K;
   std::vector<int> d_TABLE;
-  size_t d_NBYTES;
-  trellis_permutation (const int K, const std::vector<int> &TABLE, const size_t NBYTES); 
+  int d_SYMS_PER_BLOCK;
+  size_t d_NBYTES_INOUT;
+  trellis_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES); 
 
 public:
   int K () const { return d_K; }
   const std::vector<int> & TABLE () const { return d_TABLE; }
-  size_t NBYTES () const { return d_NBYTES; }
+  int SYMS_PER_BLOCK () const { return d_SYMS_PER_BLOCK; }
+  size_t NBYTES_INOUT () const { return d_NBYTES_INOUT; }
 
   int work (int noutput_items,
            gr_vector_const_void_star &input_items,
index db74cdf05bdfdd791ec5f7114486ad284418620a..4dbb92bea9e5d39917e3be05fd7171ad6d29bd8a 100644 (file)
 
 GR_SWIG_BLOCK_MAGIC(trellis,permutation);
 
-trellis_permutation_sptr trellis_make_permutation (const int K, const std::vector<int> &TABLE, const size_t NBYTES);
+trellis_permutation_sptr trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT);
 
 class trellis_permutation : public gr_sync_block
 {
 private:
   int d_K;
   std::vector<int> d_TABLE;
-  size_t d_NBYTES;
-  trellis_permutation (const int K, const std::vector<int> &TABLE, const size_t NBYTES); 
+  int d_SYMS_PER_BLOCK;
+  size_t d_NBYTES_INOUT;
+  trellis_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT); 
 
 public:
   int K () const { return d_K; }
   const std::vector<int> & TABLE () const { return d_TABLE; }
-  size_t NBYTES () const { return d_NBYTES; }
+  int SYMS_PER_BLOCK () const { return d_SYMS_PER_BLOCK; }
+  size_t NBYTES_INOUT () const { return d_NBYTES_INOUT; }
 };
diff --git a/gr-trellis/src/lib/trellis_siso_f.cc b/gr-trellis/src/lib/trellis_siso_f.cc
new file mode 100644 (file)
index 0000000..df364fc
--- /dev/null
@@ -0,0 +1,323 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <trellis_siso_f.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <assert.h>
+#include <iostream>
+  
+static const float INF = 1.0e9;
+
+trellis_siso_f_sptr 
+trellis_make_siso_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t SISO_TYPE)
+{
+  return trellis_siso_f_sptr (new trellis_siso_f (FSM,K,S0,SK,POSTI,POSTO,SISO_TYPE));
+}
+
+trellis_siso_f::trellis_siso_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t SISO_TYPE)
+  : gr_block ("siso_f",
+                         gr_make_io_signature (1, -1, sizeof (float)),
+                         gr_make_io_signature (1, -1, sizeof (float))),  
+  d_FSM (FSM),
+  d_K (K),
+  d_S0 (S0),
+  d_SK (SK),
+  d_POSTI (POSTI),
+  d_POSTO (POSTO),
+  d_SISO_TYPE (SISO_TYPE),
+  d_alpha(FSM.S()*(K+1)),
+  d_beta(FSM.S()*(K+1))
+{
+    int multiple;
+    if (d_POSTI && d_POSTO) 
+        multiple = d_FSM.I()+d_FSM.O();
+    else if(d_POSTI)
+        multiple = d_FSM.I();
+    else if(d_POSTO)
+        multiple = d_FSM.O();
+    else
+        throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+    //printf("constructor: Multiple = %d\n",multiple);
+    set_output_multiple (d_K*multiple);
+    //what is the meaning of relative rate for this?
+    // it was suggested to use the one furthest from 1.0
+    // let's do it.
+    set_relative_rate ( multiple / ((double) d_FSM.I()) );
+}
+
+
+void
+trellis_siso_f::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+  int multiple;
+  if (d_POSTI && d_POSTO)
+      multiple = d_FSM.I()+d_FSM.O();
+  else if(d_POSTI)
+      multiple = d_FSM.I();
+  else if(d_POSTO)
+      multiple = d_FSM.O();
+  else
+      throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+  //printf("forecast: Multiple = %d\n",multiple); 
+  assert (noutput_items % (d_K*multiple) == 0);
+  int input_required1 =  d_FSM.I() * (noutput_items/multiple) ;
+  int input_required2 =  d_FSM.O() * (noutput_items/multiple) ;
+  //printf("forecast: Output requirements:  %d\n",noutput_items);
+  //printf("forecast: Input requirements:  %d   %d\n",input_required1,input_required2);
+  unsigned ninputs = ninput_items_required.size();
+  assert(ninputs % 2 == 0);
+  for (unsigned int i = 0; i < ninputs/2; i++) {
+    ninput_items_required[2*i] = input_required1;
+    ninput_items_required[2*i+1] = input_required2;
+  }
+}
+
+inline float min(float a, float b)
+{
+  return a <= b ? a : b;
+}
+
+inline float min_star(float a, float b)
+{
+  return (a <= b ? a : b)-log(1+exp(a <= b ? a-b : b-a));
+}
+
+void siso_algorithm(int I, int S, int O, 
+             const std::vector<int> &NS,
+             const std::vector<int> &OS,
+             const std::vector<int> &PS,
+             const std::vector<int> &PI,
+             int K,
+             int S0,int SK,
+             bool POSTI, bool POSTO,
+             float (*p2mymin)(float,float),
+             const float *priori, const float *prioro, float *post,
+             std::vector<float> &alpha,
+             std::vector<float> &beta) 
+{
+  float norm,mm,minm;
+
+
+  if(S0<0) { // initial state not specified
+      for(int i=0;i<S;i++) alpha[0*S+i]=0;
+  }
+  else {
+      for(int i=0;i<S;i++) alpha[0*S+i]=INF;
+      alpha[0*S+S0]=0.0;
+  }
+
+  for(int k=0;k<K;k++) { // forward recursion
+      norm=INF;
+      for(int j=0;j<S;j++) {
+          minm=INF;
+          for(int i=0;i<I;i++) {
+              int i0 = j*I+i;
+              mm=alpha[k*S+PS[i0]]+priori[k*I+PI[i0]]+prioro[k*O+OS[PS[i0]*I+PI[i0]]];
+              minm=(*p2mymin)(minm,mm);
+          }
+          alpha[(k+1)*S+j]=minm;
+          if(minm<norm) norm=minm;
+      }
+      for(int j=0;j<S;j++) 
+          alpha[(k+1)*S+j]-=norm; // normalize total metrics so they do not explode
+  }
+
+  if(SK<0) { // final state not specified
+      for(int i=0;i<S;i++) beta[K*S+i]=0;
+  }
+  else {
+      for(int i=0;i<S;i++) beta[K*S+i]=INF;
+      beta[K*S+SK]=0.0;
+  }
+
+  for(int k=K-1;k>=0;k--) { // backward recursion
+      norm=INF;
+      for(int j=0;j<S;j++) { 
+          minm=INF;
+          for(int i=0;i<I;i++) {
+              int i0 = j*I+i;
+              mm=beta[(k+1)*S+NS[i0]]+priori[k*I+i]+prioro[k*O+OS[i0]];
+              minm=(*p2mymin)(minm,mm);
+          }
+          beta[k*S+j]=minm;
+          if(minm<norm) norm=minm;
+      }
+      for(int j=0;j<S;j++)
+          beta[k*S+j]-=norm; // normalize total metrics so they do not explode
+  }
+
+
+if (POSTI && POSTO)
+{
+  for(int k=0;k<K;k++) { // input combining
+      norm=INF;
+      for(int i=0;i<I;i++) {
+          minm=INF;
+          for(int j=0;j<S;j++) {
+              mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]];
+              minm=(*p2mymin)(minm,mm);
+          }
+          post[k*(I+O)+i]=minm;
+          if(minm<norm) norm=minm;
+      }
+      for(int i=0;i<I;i++)
+          post[k*(I+O)+i]-=norm; // normalize metrics
+  }
+
+
+  for(int k=0;k<K;k++) { // output combining
+      norm=INF;
+      for(int n=0;n<O;n++) {
+          minm=INF;
+          for(int j=0;j<S;j++) {
+              for(int i=0;i<I;i++) {
+                  mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF);
+                  minm=(*p2mymin)(minm,mm);
+              }
+          }
+          post[k*(I+O)+I+n]=minm;
+          if(minm<norm) norm=minm;
+      }
+      for(int n=0;n<O;n++)
+          post[k*(I+O)+I+n]-=norm; // normalize metrics
+  }
+} 
+else if(POSTI) 
+{
+  for(int k=0;k<K;k++) { // input combining
+      norm=INF;
+      for(int i=0;i<I;i++) {
+          minm=INF;
+          for(int j=0;j<S;j++) {
+              mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]];
+              minm=(*p2mymin)(minm,mm);
+          }
+          post[k*I+i]=minm;
+          if(minm<norm) norm=minm;
+      }
+      for(int i=0;i<I;i++)
+          post[k*I+i]-=norm; // normalize metrics
+  }
+}
+else if(POSTO)
+{
+  for(int k=0;k<K;k++) { // output combining
+      norm=INF;
+      for(int n=0;n<O;n++) {
+          minm=INF;
+          for(int j=0;j<S;j++) {
+              for(int i=0;i<I;i++) {
+                  mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF);
+                  minm=(*p2mymin)(minm,mm);
+              }
+          }
+          post[k*O+n]=minm;
+          if(minm<norm) norm=minm;
+      }
+      for(int n=0;n<O;n++)
+          post[k*O+n]-=norm; // normalize metrics
+  }
+}
+else
+    throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+
+}
+
+
+
+
+
+
+int
+trellis_siso_f::general_work (int noutput_items,
+                        gr_vector_int &ninput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  assert (input_items.size() == 2*output_items.size());
+  int nstreams = output_items.size();
+  //printf("general_work:Streams:  %d\n",nstreams); 
+  int multiple;
+  if (d_POSTI && d_POSTO)
+      multiple = d_FSM.I()+d_FSM.O();
+  else if(d_POSTI)
+      multiple = d_FSM.I();
+  else if(d_POSTO)
+      multiple = d_FSM.O();
+  else
+      throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+
+  assert (noutput_items % (d_K*multiple) == 0);
+  int nblocks = noutput_items / (d_K*multiple);
+  //printf("general_work:Blocks:  %d\n",nblocks); 
+  //for(int i=0;i<ninput_items.size();i++)
+      //printf("general_work:Input items available:  %d\n",ninput_items[i]);
+
+  float (*p2min)(float, float) = NULL; 
+  if(d_SISO_TYPE == TRELLIS_MIN_SUM)
+    p2min = &min;
+  else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+    p2min = &min_star;
+
+
+  for (int m=0;m<nstreams;m++) {
+    const float *in1 = (const float *) input_items[2*m];
+    const float *in2 = (const float *) input_items[2*m+1];
+    float *out = (float *) output_items[m];
+    for (int n=0;n<nblocks;n++) {
+      siso_algorithm(d_FSM.I(),d_FSM.S(),d_FSM.O(),
+        d_FSM.NS(),d_FSM.OS(),d_FSM.PS(),d_FSM.PI(),
+        d_K,d_S0,d_SK,
+        d_POSTI,d_POSTO,
+        p2min,
+        &(in1[n*d_K*d_FSM.I()]),&(in2[n*d_K*d_FSM.O()]),
+        &(out[n*d_K*multiple]),
+        d_alpha,d_beta);
+    }
+  }
+
+  for (unsigned int i = 0; i < input_items.size()/2; i++) {
+    consume(2*i,d_FSM.I() * noutput_items / multiple );
+    consume(2*i+1,d_FSM.O() * noutput_items / multiple );
+  }
+
+  return noutput_items;
+}
diff --git a/gr-trellis/src/lib/trellis_siso_f.h b/gr-trellis/src/lib/trellis_siso_f.h
new file mode 100644 (file)
index 0000000..3698125
--- /dev/null
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_TRELLIS_SISO_F_H
+#define INCLUDED_TRELLIS_SISO_F_H
+
+#include "fsm.h"
+#include "trellis_siso_type.h"
+#include <gr_block.h>
+
+class trellis_siso_f;
+typedef boost::shared_ptr<trellis_siso_f> trellis_siso_f_sptr;
+
+trellis_siso_f_sptr trellis_make_siso_f (
+    const fsm &FSM, 
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t d_SISO_TYPE);
+
+
+
+class trellis_siso_f : public gr_block
+{
+  fsm d_FSM;
+  int d_K;
+  int d_S0;
+  int d_SK;
+  bool d_POSTI;
+  bool d_POSTO;
+  trellis_siso_type_t d_SISO_TYPE;
+  std::vector<float> d_alpha;
+  std::vector<float> d_beta;
+
+  friend trellis_siso_f_sptr trellis_make_siso_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t d_SISO_TYPE);
+
+
+  trellis_siso_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t d_SISO_TYPE);
+
+
+public:
+  fsm FSM () const { return d_FSM; }
+  int K () const { return d_K; }
+  int S0 () const { return d_S0; }
+  int SK () const { return d_SK; }
+  bool POSTI () const { return d_POSTI; }
+  bool POSTO () const { return d_POSTO; }
+  trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+  void forecast (int noutput_items,
+                 gr_vector_int &ninput_items_required);
+  int general_work (int noutput_items,
+                    gr_vector_int &ninput_items,
+                    gr_vector_const_void_star &input_items,
+                    gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-trellis/src/lib/trellis_siso_f.i b/gr-trellis/src/lib/trellis_siso_f.i
new file mode 100644 (file)
index 0000000..534ac38
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(trellis,siso_f);
+
+trellis_siso_f_sptr trellis_make_siso_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t SISO_TYPE);
+
+
+class trellis_siso_f : public gr_block
+{
+private:
+  trellis_siso_f (
+    const fsm &FSM,
+    int K,
+    int S0,
+    int SK,
+    bool POSTI,
+    bool POSTO,
+    trellis_siso_type_t SISO_TYPE);
+
+public:
+    fsm FSM () const { return d_FSM; }
+    int K () const { return d_K; }
+    int S0 () const { return d_S0; }
+    int SK () const { return d_SK; }
+    bool POSTI () const { return d_POSTI; }
+    bool POSTO () const { return d_POSTO; }
+    trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+};
diff --git a/gr-trellis/src/lib/trellis_siso_f.lo b/gr-trellis/src/lib/trellis_siso_f.lo
new file mode 100644 (file)
index 0000000..2d24f85
--- /dev/null
@@ -0,0 +1,12 @@
+# trellis_siso_f.lo - a libtool object file
+# Generated by ltmain.sh - GNU libtool 1.5.6 (1.1220.2.95 2004/04/11 05:50:42)
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object='.libs/trellis_siso_f.o'
+
+# Name of the non-PIC object.
+non_pic_object=none
+
diff --git a/gr-trellis/src/lib/trellis_siso_type.h b/gr-trellis/src/lib/trellis_siso_type.h
new file mode 100644 (file)
index 0000000..6f72752
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_TRELLIS_SISO_TYPE_H
+#define INCLUDED_TRELLIS_SISO_TYPE_H
+
+typedef enum {
+  TRELLIS_MIN_SUM = 200, TRELLIS_SUM_PRODUCT
+} trellis_siso_type_t;
+
+#endif
+
index 0ab423b0ae2a44b775ff107325972f033eb0071b..8f02320d632e3911a7402ddd7b5482fcc07c8ef7 100644 (file)
@@ -34,18 +34,18 @@ static const float INF = 1.0e9;
 @SPTR_NAME@ 
 trellis_make_@BASE_NAME@ (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK)
+    int K,
+    int S0,
+    int SK)
 {
   return @SPTR_NAME@ (new @NAME@ (FSM,K,S0,SK));
 }
 
 @NAME@::@NAME@ (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK)
+    int K,
+    int S0,
+    int SK)
   : gr_block ("@BASE_NAME@",
                          gr_make_io_signature (1, -1, sizeof (float)),
                          gr_make_io_signature (1, -1, sizeof (@TYPE@))),  
@@ -74,13 +74,13 @@ void
 
 
 
-void viterbi_algorithm(const int I, const int S, const int O, 
+void viterbi_algorithm(int I, int S, int O, 
              const std::vector<int> &NS,
              const std::vector<int> &OS,
              const std::vector<int> &PS,
              const std::vector<int> &PI,
-             const int K,
-             const int S0,const int SK,
+             int K,
+             int S0,int SK,
              const float *in, @TYPE@ *out,
              std::vector<int> &trace) 
 {
index f1b8e00622eeeedfc1247cc0af30c9cb6e633e4f..f06fdfdcd2fc9d5d072e223173297d6801dd4eaa 100644 (file)
@@ -33,9 +33,9 @@ typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
 
 @SPTR_NAME@ trellis_make_@BASE_NAME@ (
     const fsm &FSM, 
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 
@@ -49,16 +49,16 @@ class @NAME@ : public gr_block
 
   friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
   @NAME@ (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 public:
index 605251e4d79e7a60b8b37088fabaa29a4cddac9a..99d899b9bed1b80965c7d72b8cc8a35d603691df 100644 (file)
@@ -26,9 +26,9 @@ GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@);
 
 @SPTR_NAME@ trellis_make_@BASE_NAME@ (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 class @NAME@ : public gr_block
@@ -36,9 +36,9 @@ class @NAME@ : public gr_block
 private:
   @NAME@ (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 public:
     fsm FSM () const { return d_FSM; }
index 2e005a316f5b3d4f2322b4f7265c6d8b924262ef..ce2778affb86ac7aa736dc58effa186193dafd5f 100644 (file)
@@ -34,18 +34,18 @@ static const float INF = 1.0e9;
 trellis_viterbi_b_sptr 
 trellis_make_viterbi_b (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK)
+    int K,
+    int S0,
+    int SK)
 {
   return trellis_viterbi_b_sptr (new trellis_viterbi_b (FSM,K,S0,SK));
 }
 
 trellis_viterbi_b::trellis_viterbi_b (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK)
+    int K,
+    int S0,
+    int SK)
   : gr_block ("viterbi_b",
                          gr_make_io_signature (1, -1, sizeof (float)),
                          gr_make_io_signature (1, -1, sizeof (unsigned char))),  
@@ -74,13 +74,13 @@ trellis_viterbi_b::forecast (int noutput_items, gr_vector_int &ninput_items_requ
 
 
 
-void viterbi_algorithm(const int I, const int S, const int O, 
+void viterbi_algorithm(int I, int S, int O, 
              const std::vector<int> &NS,
              const std::vector<int> &OS,
              const std::vector<int> &PS,
              const std::vector<int> &PI,
-             const int K,
-             const int S0,const int SK,
+             int K,
+             int S0,int SK,
              const float *in, unsigned char *out,
              std::vector<int> &trace) 
 {
index a4fa533e81738e41bc98f95d4fb9aca1ef1e46ea..c1c359b12048a61080dc0dad9a75126910e9c1f1 100644 (file)
@@ -33,9 +33,9 @@ typedef boost::shared_ptr<trellis_viterbi_b> trellis_viterbi_b_sptr;
 
 trellis_viterbi_b_sptr trellis_make_viterbi_b (
     const fsm &FSM, 
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 
@@ -49,16 +49,16 @@ class trellis_viterbi_b : public gr_block
 
   friend trellis_viterbi_b_sptr trellis_make_viterbi_b (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
   trellis_viterbi_b (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 public:
index 44fca365b45e67534e790030084ee9f846986a35..8f456b0bb203d2075cad6653bc6efcb129987711 100644 (file)
@@ -26,9 +26,9 @@ GR_SWIG_BLOCK_MAGIC(trellis,viterbi_b);
 
 trellis_viterbi_b_sptr trellis_make_viterbi_b (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 class trellis_viterbi_b : public gr_block
@@ -36,9 +36,9 @@ class trellis_viterbi_b : public gr_block
 private:
   trellis_viterbi_b (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 public:
     fsm FSM () const { return d_FSM; }
index 52e01026bea8af3043c05d6e0520be7f84ba0cb2..de2079ad07d316d801c3c3f984b6423fc3aee388 100644 (file)
@@ -34,24 +34,24 @@ static const float INF = 1.0e9;
 @SPTR_NAME@ 
 trellis_make_@BASE_NAME@ (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE)
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE)
 {
   return @SPTR_NAME@ (new @NAME@ (FSM,D,TABLE,K,S0,SK,TYPE));
 }
 
 @NAME@::@NAME@ (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE)
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE)
   : gr_block ("@BASE_NAME@",
                          gr_make_io_signature (1, -1, sizeof (float)),
                          gr_make_io_signature (1, -1, sizeof (@TYPE@))),  
@@ -83,16 +83,16 @@ void
 
 
 
-void viterbi_algorithm_combined(const int I, const int S, const int O, 
+void viterbi_algorithm_combined(int I, int S, int O, 
              const std::vector<int> &NS,
              const std::vector<int> &OS,
              const std::vector<int> &PS,
              const std::vector<int> &PI,
-             const int D,
+             int D,
              const std::vector<float> &TABLE,
-             const int K,
-             const int S0,const int SK,
-             const trellis_metric_type_t TYPE,
+             int K,
+             int S0,int SK,
+             trellis_metric_type_t TYPE,
              const float *in, @TYPE@ *out,
              std::vector<int> &trace) 
 {
index 8d7059a55b4ab3d32be3b8f47e89fbdb5934c3ef..14f565202cd7f06ad2fe747ee5728ce1a7a0ac59 100644 (file)
@@ -34,12 +34,12 @@ typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
 
 @SPTR_NAME@ trellis_make_@BASE_NAME@ (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 class @NAME@ : public gr_block
@@ -55,22 +55,22 @@ class @NAME@ : public gr_block
 
   friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
   @NAME@ (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 public:
index 388e0626e91a580487d030fac7a9cc952ea35646..e4b68402c517d1f3186d06310212937425151d92 100644 (file)
@@ -26,12 +26,12 @@ GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@);
 
 @SPTR_NAME@ trellis_make_@BASE_NAME@ (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 class @NAME@ : public gr_block
@@ -39,12 +39,12 @@ class @NAME@ : public gr_block
 private:
   @NAME@ (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 public:
     fsm FSM () const { return d_FSM; }
index 8c72b2a3c969f48061bfe3c44c8b778eb832339a..2d245f58ba329dea2ea1180ba95759dc23e0c3a7 100644 (file)
@@ -34,24 +34,24 @@ static const float INF = 1.0e9;
 trellis_viterbi_combined_b_sptr 
 trellis_make_viterbi_combined_b (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE)
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE)
 {
   return trellis_viterbi_combined_b_sptr (new trellis_viterbi_combined_b (FSM,D,TABLE,K,S0,SK,TYPE));
 }
 
 trellis_viterbi_combined_b::trellis_viterbi_combined_b (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE)
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE)
   : gr_block ("viterbi_combined_b",
                          gr_make_io_signature (1, -1, sizeof (float)),
                          gr_make_io_signature (1, -1, sizeof (unsigned char))),  
@@ -83,16 +83,16 @@ trellis_viterbi_combined_b::forecast (int noutput_items, gr_vector_int &ninput_i
 
 
 
-void viterbi_algorithm_combined(const int I, const int S, const int O, 
+void viterbi_algorithm_combined(int I, int S, int O, 
              const std::vector<int> &NS,
              const std::vector<int> &OS,
              const std::vector<int> &PS,
              const std::vector<int> &PI,
-             const int D,
+             int D,
              const std::vector<float> &TABLE,
-             const int K,
-             const int S0,const int SK,
-             const trellis_metric_type_t TYPE,
+             int K,
+             int S0,int SK,
+             trellis_metric_type_t TYPE,
              const float *in, unsigned char *out,
              std::vector<int> &trace) 
 {
index f523c5ce152e981563ce25ce65bea5a454d97b1c..5de0924d7c507c2b258702ccf2f10e439d786a67 100644 (file)
@@ -34,12 +34,12 @@ typedef boost::shared_ptr<trellis_viterbi_combined_b> trellis_viterbi_combined_b
 
 trellis_viterbi_combined_b_sptr trellis_make_viterbi_combined_b (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 class trellis_viterbi_combined_b : public gr_block
@@ -55,22 +55,22 @@ class trellis_viterbi_combined_b : public gr_block
 
   friend trellis_viterbi_combined_b_sptr trellis_make_viterbi_combined_b (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
   trellis_viterbi_combined_b (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 public:
index 44b4aa431290c55549f49e9ff54791e2245971dc..069860893bf21b69c7f70bdcab476bacfa864a06 100644 (file)
@@ -26,12 +26,12 @@ GR_SWIG_BLOCK_MAGIC(trellis,viterbi_combined_b);
 
 trellis_viterbi_combined_b_sptr trellis_make_viterbi_combined_b (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 class trellis_viterbi_combined_b : public gr_block
@@ -39,12 +39,12 @@ class trellis_viterbi_combined_b : public gr_block
 private:
   trellis_viterbi_combined_b (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 public:
     fsm FSM () const { return d_FSM; }
index 3301d028393614f3dba5d74d53068069d4a4ef44..4506fd127a0fc359a49fecb18e29c2c8de888250 100644 (file)
@@ -34,24 +34,24 @@ static const float INF = 1.0e9;
 trellis_viterbi_combined_i_sptr 
 trellis_make_viterbi_combined_i (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE)
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE)
 {
   return trellis_viterbi_combined_i_sptr (new trellis_viterbi_combined_i (FSM,D,TABLE,K,S0,SK,TYPE));
 }
 
 trellis_viterbi_combined_i::trellis_viterbi_combined_i (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE)
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE)
   : gr_block ("viterbi_combined_i",
                          gr_make_io_signature (1, -1, sizeof (float)),
                          gr_make_io_signature (1, -1, sizeof (int))),  
@@ -83,16 +83,16 @@ trellis_viterbi_combined_i::forecast (int noutput_items, gr_vector_int &ninput_i
 
 
 
-void viterbi_algorithm_combined(const int I, const int S, const int O, 
+void viterbi_algorithm_combined(int I, int S, int O, 
              const std::vector<int> &NS,
              const std::vector<int> &OS,
              const std::vector<int> &PS,
              const std::vector<int> &PI,
-             const int D,
+             int D,
              const std::vector<float> &TABLE,
-             const int K,
-             const int S0,const int SK,
-             const trellis_metric_type_t TYPE,
+             int K,
+             int S0,int SK,
+             trellis_metric_type_t TYPE,
              const float *in, int *out,
              std::vector<int> &trace) 
 {
index 171fcb93dfd4300a03c22603d98e16d3377a01a8..1ac5d7d1df975b6fa06ba831802f330e02167b3f 100644 (file)
@@ -34,12 +34,12 @@ typedef boost::shared_ptr<trellis_viterbi_combined_i> trellis_viterbi_combined_i
 
 trellis_viterbi_combined_i_sptr trellis_make_viterbi_combined_i (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 class trellis_viterbi_combined_i : public gr_block
@@ -55,22 +55,22 @@ class trellis_viterbi_combined_i : public gr_block
 
   friend trellis_viterbi_combined_i_sptr trellis_make_viterbi_combined_i (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
   trellis_viterbi_combined_i (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 public:
index 4b8355e0e8618aaa8d10439bb12f1708ef511604..05d68d580b64cd6bfdf44c7f37609e64e64b57ad 100644 (file)
@@ -26,12 +26,12 @@ GR_SWIG_BLOCK_MAGIC(trellis,viterbi_combined_i);
 
 trellis_viterbi_combined_i_sptr trellis_make_viterbi_combined_i (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 class trellis_viterbi_combined_i : public gr_block
@@ -39,12 +39,12 @@ class trellis_viterbi_combined_i : public gr_block
 private:
   trellis_viterbi_combined_i (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 public:
     fsm FSM () const { return d_FSM; }
index 46dda3d1d1924535e6da12a449eed357c5a9e536..f103db229ab998bb2e04929411ad7018893b879f 100644 (file)
@@ -34,24 +34,24 @@ static const float INF = 1.0e9;
 trellis_viterbi_combined_s_sptr 
 trellis_make_viterbi_combined_s (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE)
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE)
 {
   return trellis_viterbi_combined_s_sptr (new trellis_viterbi_combined_s (FSM,D,TABLE,K,S0,SK,TYPE));
 }
 
 trellis_viterbi_combined_s::trellis_viterbi_combined_s (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE)
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE)
   : gr_block ("viterbi_combined_s",
                          gr_make_io_signature (1, -1, sizeof (float)),
                          gr_make_io_signature (1, -1, sizeof (short))),  
@@ -83,16 +83,16 @@ trellis_viterbi_combined_s::forecast (int noutput_items, gr_vector_int &ninput_i
 
 
 
-void viterbi_algorithm_combined(const int I, const int S, const int O, 
+void viterbi_algorithm_combined(int I, int S, int O, 
              const std::vector<int> &NS,
              const std::vector<int> &OS,
              const std::vector<int> &PS,
              const std::vector<int> &PI,
-             const int D,
+             int D,
              const std::vector<float> &TABLE,
-             const int K,
-             const int S0,const int SK,
-             const trellis_metric_type_t TYPE,
+             int K,
+             int S0,int SK,
+             trellis_metric_type_t TYPE,
              const float *in, short *out,
              std::vector<int> &trace) 
 {
index 5b74b35a9895a929a5485719b6cfe27c5e08c2d0..c174c5f01d2a30a4ce60d29e43ed4fc6932d4993 100644 (file)
@@ -34,12 +34,12 @@ typedef boost::shared_ptr<trellis_viterbi_combined_s> trellis_viterbi_combined_s
 
 trellis_viterbi_combined_s_sptr trellis_make_viterbi_combined_s (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 class trellis_viterbi_combined_s : public gr_block
@@ -55,22 +55,22 @@ class trellis_viterbi_combined_s : public gr_block
 
   friend trellis_viterbi_combined_s_sptr trellis_make_viterbi_combined_s (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
   trellis_viterbi_combined_s (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 public:
index ddac52692e87f0ac52e19dc782cd8c9a90af7764..c1d5693a20c48b0a4ce5d631ddb202402334994c 100644 (file)
@@ -26,12 +26,12 @@ GR_SWIG_BLOCK_MAGIC(trellis,viterbi_combined_s);
 
 trellis_viterbi_combined_s_sptr trellis_make_viterbi_combined_s (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 
 class trellis_viterbi_combined_s : public gr_block
@@ -39,12 +39,12 @@ class trellis_viterbi_combined_s : public gr_block
 private:
   trellis_viterbi_combined_s (
     const fsm &FSM,
-    const int D,
+    int D,
     const std::vector<float> &TABLE,
-    const int K,
-    const int S0,
-    const int SK,
-    const trellis_metric_type_t TYPE);
+    int K,
+    int S0,
+    int SK,
+    trellis_metric_type_t TYPE);
 
 public:
     fsm FSM () const { return d_FSM; }
index 58a39f6e5d60a78ed632dfa0cafc638335e38d43..2ff304ebbb5ed636fb0de6ffc8701f770ad992e2 100644 (file)
@@ -34,18 +34,18 @@ static const float INF = 1.0e9;
 trellis_viterbi_i_sptr 
 trellis_make_viterbi_i (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK)
+    int K,
+    int S0,
+    int SK)
 {
   return trellis_viterbi_i_sptr (new trellis_viterbi_i (FSM,K,S0,SK));
 }
 
 trellis_viterbi_i::trellis_viterbi_i (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK)
+    int K,
+    int S0,
+    int SK)
   : gr_block ("viterbi_i",
                          gr_make_io_signature (1, -1, sizeof (float)),
                          gr_make_io_signature (1, -1, sizeof (int))),  
@@ -74,13 +74,13 @@ trellis_viterbi_i::forecast (int noutput_items, gr_vector_int &ninput_items_requ
 
 
 
-void viterbi_algorithm(const int I, const int S, const int O, 
+void viterbi_algorithm(int I, int S, int O, 
              const std::vector<int> &NS,
              const std::vector<int> &OS,
              const std::vector<int> &PS,
              const std::vector<int> &PI,
-             const int K,
-             const int S0,const int SK,
+             int K,
+             int S0,int SK,
              const float *in, int *out,
              std::vector<int> &trace) 
 {
index 5da0a38663a6f3094e7b6795998ec1375787d70e..86ac898761418ac4f350b2e6c6bd9024578b0588 100644 (file)
@@ -33,9 +33,9 @@ typedef boost::shared_ptr<trellis_viterbi_i> trellis_viterbi_i_sptr;
 
 trellis_viterbi_i_sptr trellis_make_viterbi_i (
     const fsm &FSM, 
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 
@@ -49,16 +49,16 @@ class trellis_viterbi_i : public gr_block
 
   friend trellis_viterbi_i_sptr trellis_make_viterbi_i (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
   trellis_viterbi_i (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 public:
index de402e36d0ffcaddc39745e2c068acf296118bc6..3b99f3173c40e136d27becd17f00c7de8ee378c4 100644 (file)
@@ -26,9 +26,9 @@ GR_SWIG_BLOCK_MAGIC(trellis,viterbi_i);
 
 trellis_viterbi_i_sptr trellis_make_viterbi_i (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 class trellis_viterbi_i : public gr_block
@@ -36,9 +36,9 @@ class trellis_viterbi_i : public gr_block
 private:
   trellis_viterbi_i (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 public:
     fsm FSM () const { return d_FSM; }
index f5a0705c2af67e22e9a6dc718761fdea45852b26..bb3dafa61051722a5f8a344c2f17be77df04076c 100644 (file)
@@ -34,18 +34,18 @@ static const float INF = 1.0e9;
 trellis_viterbi_s_sptr 
 trellis_make_viterbi_s (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK)
+    int K,
+    int S0,
+    int SK)
 {
   return trellis_viterbi_s_sptr (new trellis_viterbi_s (FSM,K,S0,SK));
 }
 
 trellis_viterbi_s::trellis_viterbi_s (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK)
+    int K,
+    int S0,
+    int SK)
   : gr_block ("viterbi_s",
                          gr_make_io_signature (1, -1, sizeof (float)),
                          gr_make_io_signature (1, -1, sizeof (short))),  
@@ -74,13 +74,13 @@ trellis_viterbi_s::forecast (int noutput_items, gr_vector_int &ninput_items_requ
 
 
 
-void viterbi_algorithm(const int I, const int S, const int O, 
+void viterbi_algorithm(int I, int S, int O, 
              const std::vector<int> &NS,
              const std::vector<int> &OS,
              const std::vector<int> &PS,
              const std::vector<int> &PI,
-             const int K,
-             const int S0,const int SK,
+             int K,
+             int S0,int SK,
              const float *in, short *out,
              std::vector<int> &trace) 
 {
index 2c3a61c9b55b29323e2234548330e8f180dfcaa4..6232ce5bfe0b48aac8729a789476e79f73e7f5f8 100644 (file)
@@ -33,9 +33,9 @@ typedef boost::shared_ptr<trellis_viterbi_s> trellis_viterbi_s_sptr;
 
 trellis_viterbi_s_sptr trellis_make_viterbi_s (
     const fsm &FSM, 
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 
@@ -49,16 +49,16 @@ class trellis_viterbi_s : public gr_block
 
   friend trellis_viterbi_s_sptr trellis_make_viterbi_s (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
   trellis_viterbi_s (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 public:
index 44e4372651104aaad6d33a0a6145e38da969571f..99b14db78f3fdaccad38dc8df1bff5f549ed41a5 100644 (file)
@@ -26,9 +26,9 @@ GR_SWIG_BLOCK_MAGIC(trellis,viterbi_s);
 
 trellis_viterbi_s_sptr trellis_make_viterbi_s (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 
 class trellis_viterbi_s : public gr_block
@@ -36,9 +36,9 @@ class trellis_viterbi_s : public gr_block
 private:
   trellis_viterbi_s (
     const fsm &FSM,
-    const int K,
-    const int S0,
-    const int SK);
+    int K,
+    int S0,
+    int SK);
 
 public:
     fsm FSM () const { return d_FSM; }