Refactored some common functions for metric calculations. Updated the documentation.
[debian/gnuradio] / gr-trellis / doc / gr-trellis.xml
index f65b953565322df1715957a725b230b02141cf27..e33a94a2d7d70934114aca5f2bf66a3e60c4acf4 100644 (file)
@@ -341,26 +341,113 @@ In this section we give a brief description of the basic blocks implemented that
 
 <!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
 <sect2 id="encoder"><title>Trellis Encoder</title>
-
 <para>
 The trellis.encoder_XX(FSM, ST) block instantiates an FSM encoder corresponding to the fsm FSM and having initial state ST. The input and output is a sequence of bytes, shorts or integers. 
 </para>
-
 </sect2>
 
 <!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
 <sect2 id="decoder"><title>Viterbi Decoder</title>
+<para>
+The trellis.viterbi_X(FSM, K, S0, SK) block instantiates a Viterbi decoder 
+for a sequence of K trellis steps generated by the given FSM and with initial and final states set to S0 and SK, respectively (S0 and/or SK are set to -1
+if the corresponding states are not fixed/known at the receiver side).
+The output of this block is a sequence of K bytes, shorts or integers representing the estimated input (i.e., uncoded) sequence.
+The input is a sequence of K x FSM.O( ) floats, where the k x K + i 
+float represents the cost associated with the k-th
+step in the trellis and the i-th FSM output.
+Observe that these inputs are generated externally and thus the Viterbi block is not informed of their meaning (they can be genarated as soft or hard inputs, etc); the only requirement is that they represent additive costs.
+</para>
+</sect2>
+
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
+<sect2 id="metrics"><title>Metrics Calculator</title>
+<para>
+The trellis.metrics_X(O,D,TABLE,TYPE) block is responsible for 
+transforming the channel output to the stream of metrics appropriate as 
+inputs to the Viterbi block described above. For each D input bytes/shorts/integers/floats/complexes it produces O output floats 
+
+</para>
 
 <para>
-The trellis.viterbi_X(FSM, K, S0, SK) block instantiates a Viterbi decoder
-for an underlying ...
+
+The parameter TYPE dictates how these metrics are generated:
+
+<itemizedlist>
+<listitem><para>
+TRELLIS_EUCLIDEAN: for each D-dimensional vector 
+r<subscript>k</subscript>=
+(r<subscript>k,1</subscript>,r<subscript>k,2</subscript>,...,r<subscript>k,D</subscript>) 
+evaluates
+</para>
+<para>
+||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> = sum<subscript>j=1</subscript><superscript>D</superscript> |r<subscript>k,j</subscript>-c<subscript>i,j</subscript>|<superscript>2</superscript>
 </para>
+<para>
+for each of the O hypothesized ouput
+symbols c<subscript>i</subscript> = (c<subscript>i,1</subscript>,c<subscript>i,2</subscript>,...,c<subscript>i,D</subscript>) defined in the vector TABLE,
+where TABLE[i * D + j] = c<subscript>i,j</subscript>.
+</para></listitem>
+
 
+<listitem><para>
+TRELLIS_HARD_SYMBOL: for each D-dimensional vector 
+r<subscript>k</subscript>=
+(r<subscript>k,1</subscript>,r<subscript>k,2</subscript>,...,r<subscript>k,D</subscript>) 
+evaluates
+</para>
+<para>
+i<subscript>0</subscript>= argmax<subscript>i</subscript> ||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> = 
+argmax<subscript>i</subscript> sum<subscript>j=1</subscript><superscript>D</superscript> |r<subscript>k,j</subscript>-c<subscript>i,j</subscript>|<superscript>2</superscript>
+</para>
+<para>
+and outputs a sequence of O floats of the form (0,...,0,1,0,...,0), where the 
+i<subscript>0</subscript> position is set to 1. This corresponds to generating hard inputs (based on the symbol-wise Hamming distance) to the Viterbi algorithm.
+</para></listitem>
+
+
+<listitem><para>
+TRELLIS_HARD_BIT (not yet implemented): for each D-dimensional vector 
+r<subscript>k</subscript>=
+(r<subscript>k,1</subscript>,r<subscript>k,2</subscript>,...,r<subscript>k,D</subscript>) 
+evaluates
+</para>
+<para>
+i<subscript>0</subscript>= argmax<subscript>i</subscript> ||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> = 
+argmax<subscript>i</subscript> sum<subscript>j=1</subscript><superscript>D</superscript> (r<subscript>k,j</subscript>-c<subscript>i,j</subscript>)<superscript>2</superscript>
+</para>
+<para>
+and outputs a sequence of O floats of the form (d<subscript>1</subscript>,d<subscript>2</subscript>,...,d<subscript>O</subscript>), where the 
+d<subscript>i</subscript> is the bitwise Hamming distance between i and  i<subscript>0</subscript>. This corresponds to generating hard inputs (based on the bit-wise Hamming distance) to the Viterbi algorithm.
+</para></listitem>
+
+
+</itemizedlist>
+
+
+</para>
 </sect2>
 
 
 
 
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
+<sect2 id="viterbi_combined"><title>Combined Metrics Calculator and Viterbi Decoder</title>
+<para>
+Although the separation of metric calculation and Viterbi algorithm blocks
+is consistent with our goal of providing general blocks that can be easily 
+reused, this separation might result in large input/output buffer sizes
+betwen blocks. Indeed for an FSM with a large output alphabet, the 
+output of the metric block/input of the Viterbi block is FSM.O( ) floats for
+each trellis step. Sometimes this results in buffer overflow even for
+moderate sequence lengths.
+To overcome this problem we provide a block that incorporates the metric calculation and Viterbi algorithm into a single GNU Radio block, namely
+trellis.viterbi_combined_X( FSM, K, S0, SK, D, TABLE, TYPE) where the arguments are exactly those used in the aforementioned two blocks.
+</para>
+</sect2>
+
+
+
 
 
 </sect1>
@@ -400,7 +487,7 @@ error rate.
 The FSM is first intantiated in "main" by 
 </para>
 <programlisting>
- 62      f=trellis.fsm(fname) # get the FSM specification from a file (will hopefully be automated in the future...)
+ 62      f=trellis.fsm(fname) # get the FSM specification from a file
 </programlisting>
 
 
@@ -426,11 +513,11 @@ symbols that will drive the FSM encoder.
 
 
 <para>
-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 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, D-dimensional
+modulation is completely specified by a set of M, D-dimensional real vectors. In "fsm_utils.py" file we give a number of useful modulations with the following format: modulation = (D,constellation), where
+constellation=[c11,c12,...,c1D,c21,c22,...,c2D,...,cM1,cM2,...cMD].
 The meaning of the above is that every constellation point c_i
-is an N-dimnsional vector c_i=(ci1,ci2,...,ciN)
+is an D-dimnsional vector c_i=(ci1,ci2,...,ciD)
 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.
@@ -487,7 +574,7 @@ and an initial state (which is set to 0 in this example).
 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 
+outputs a sequence of D numbers ci1,ci2,...,ciD  representing the 
 coordianates of the constellation symbol c_i with i=y_k.
 </para>
 <programlisting>
@@ -496,8 +583,8 @@ coordianates of the constellation symbol c_i with i=y_k.
 
 <para>
 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).
+For each transmitted symbol c_k=(ck1,ck2,...,ckD) we receive a noisy version
+r_k=(rk1,rk2,...,rkD).
 </para>
 <programlisting>
  22      # CHANNEL
@@ -522,10 +609,10 @@ 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.
+taking D inputs at a time and producing O outputs. The D inputs are
+rk1,rk2,...,rkD.
 The O outputs
-are the costs associated with observations rk1,rk2,...,rkN and
+are the costs associated with observations rk1,rk2,...,rkD 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,
@@ -592,7 +679,7 @@ automate fsm generation from rational functions
 
 <listitem>
 <para>
-Optimize the VA code.
+Optimize the VA code if possible.
 </para>
 </listitem>