From 96a174f10af9b9b16cbb921622672ab6fedc822d Mon Sep 17 00:00:00 2001
From: Achilleas Anastasopoulos <anastas@umich.edu>
Date: Mon, 21 Feb 2011 18:58:58 -0500
Subject: added pccc decoder + examples

---
 gr-trellis/src/lib/core_algorithms.cc | 252 ++++++++++++++++++++++++++--------
 1 file changed, 196 insertions(+), 56 deletions(-)

(limited to 'gr-trellis/src/lib/core_algorithms.cc')

diff --git a/gr-trellis/src/lib/core_algorithms.cc b/gr-trellis/src/lib/core_algorithms.cc
index b7037926e5..91ac8fbdf9 100644
--- a/gr-trellis/src/lib/core_algorithms.cc
+++ b/gr-trellis/src/lib/core_algorithms.cc
@@ -22,6 +22,8 @@
 
 #include <cstring>
 #include <stdexcept>
+//#include <cstdio>
+#include <iostream>
 #include "core_algorithms.h"
 #include "calc_metric.h"
 
@@ -976,93 +978,92 @@ void sccc_decoder(
       const float *iprioro, T *data
 )
 {
-
-//allocate space for priori, and posti of inner FSM
-std::vector<float> ipriori(blocklength*FSMi.I(),0.0);
-std::vector<float> iposti(blocklength*FSMi.I());
-
-//allocate space for priori, prioro and posto of outer FSM
-std::vector<float> opriori(blocklength*FSMo.I(),0.0);
-std::vector<float> oprioro(blocklength*FSMo.O());
-std::vector<float> oposti(blocklength*FSMo.I());
-std::vector<float> oposto(blocklength*FSMo.O());
-
-for(int rep=0;rep<repetitions;rep++) {
-  // run inner SISO
-  siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(),
+  //allocate space for priori, and posti of inner FSM
+  std::vector<float> ipriori(blocklength*FSMi.I(),0.0);
+  std::vector<float> iposti(blocklength*FSMi.I());
+
+  //allocate space for priori, prioro and posto of outer FSM
+  std::vector<float> opriori(blocklength*FSMo.I(),0.0);
+  std::vector<float> oprioro(blocklength*FSMo.O());
+  std::vector<float> oposti(blocklength*FSMo.I());
+  std::vector<float> oposto(blocklength*FSMo.O());
+
+  for(int rep=0;rep<repetitions;rep++) {
+    // run inner SISO
+    siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(),
              FSMi.NS(), FSMi.OS(), FSMi.PS(), FSMi.PI(),
              blocklength,
              STi0,STiK,
              true, false,
              p2mymin,
              &(ipriori[0]),  &(iprioro[0]), &(iposti[0])
-  );
+    );
 
-  //interleave soft info inner -> outer
-  for(int k=0;k<blocklength;k++) {
-    int ki = INTERLEAVER.DEINTER()[k];
-    //for(int i=0;i<FSMi.I();i++) {
-      //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i];
-    //}
-    memcpy(&(oprioro[k*FSMi.I()]),&(iposti[ki*FSMi.I()]),FSMi.I()*sizeof(float));
-  } 
+    //interleave soft info inner -> outer
+    for(int k=0;k<blocklength;k++) {
+      int ki = INTERLEAVER.DEINTER()[k];
+      //for(int i=0;i<FSMi.I();i++) {
+        //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i];
+      //}
+      memcpy(&(oprioro[k*FSMi.I()]),&(iposti[ki*FSMi.I()]),FSMi.I()*sizeof(float));
+    } 
 
-  // run outer SISO
+    // run outer SISO
 
-  if(rep<repetitions-1) { // do not produce posti
-    siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
+    if(rep<repetitions-1) { // do not produce posti
+      siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
              FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(),
              blocklength,
              STo0,SToK,
              false, true,
              p2mymin,
              &(opriori[0]),  &(oprioro[0]), &(oposto[0])
-    );
-
-    //interleave soft info outer --> inner
-    for(int k=0;k<blocklength;k++) {
-      int ki = INTERLEAVER.DEINTER()[k];
-      //for(int i=0;i<FSMi.I();i++) {
-        //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i];
-      //}
-      memcpy(&(ipriori[ki*FSMi.I()]),&(oposto[k*FSMi.I()]),FSMi.I()*sizeof(float));
-    } 
-  }
-  else // produce posti but not posto
+      );
+
+      //interleave soft info outer --> inner
+      for(int k=0;k<blocklength;k++) {
+        int ki = INTERLEAVER.DEINTER()[k];
+        //for(int i=0;i<FSMi.I();i++) {
+          //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i];
+        //}
+        memcpy(&(ipriori[ki*FSMi.I()]),&(oposto[k*FSMi.I()]),FSMi.I()*sizeof(float));
+      } 
+    }
+    else {// produce posti but not posto
     
-    siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
+      siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
              FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(),
              blocklength,
              STo0,SToK,
              true, false,
              p2mymin,
              &(opriori[0]),  &(oprioro[0]), &(oposti[0])
-    );
+      );
    
-    /*
-    viterbi_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
+      /*
+      viterbi_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
              FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(),
              blocklength,
              STo0,SToK,
              &(oprioro[0]), data
-    );
-    */
-
-}
+      );
+      */
+    }
 
+  } // end repetitions
 
-// generate hard decisions
-for(int k=0;k<blocklength;k++) {
-  float min=INF;
-  int mini=0;
-  for(int i=0;i<FSMo.I();i++) {
-    if(oposti[k*FSMo.I()+i]<min) {
-      min=oposti[k*FSMo.I()+i];
-      mini=i;
+  // generate hard decisions
+  for(int k=0;k<blocklength;k++) {
+    float min=INF;
+    int mini=0;
+    for(int i=0;i<FSMo.I();i++) {
+      if(oposti[k*FSMo.I()+i]<min) {
+        min=oposti[k*FSMo.I()+i];
+        mini=i;
+      }
     }
+    data[k]=(T)mini;
   }
-  data[k]=(T)mini;
-}
 
 
 
@@ -1097,3 +1098,142 @@ void sccc_decoder<int>(
       const float *iprioro, int *data
 );
 
+
+//====================================================
+
+template<class T>
+void pccc_decoder(
+      const fsm &FSM1, int ST10, int ST1K,
+      const fsm &FSM2, int ST20, int ST2K,
+      const interleaver &INTERLEAVER, int blocklength, int repetitions,
+      float (*p2mymin)(float,float),
+      const float *cprioro, T *data
+)
+{
+
+  //allocate space for priori, prioro and posti of FSM1
+  std::vector<float> priori1(blocklength*FSM1.I(),0.0);
+  std::vector<float> prioro1(blocklength*FSM1.O());
+  std::vector<float> posti1(blocklength*FSM1.I());
+
+  //allocate space for priori, prioro and posti of FSM2
+  std::vector<float> priori2(blocklength*FSM2.I(),0.0);
+  std::vector<float> prioro2(blocklength*FSM2.O());
+  std::vector<float> posti2(blocklength*FSM2.I());
+ 
+  //generate prioro1,2 (metrics are not updated per iteration: this is not the best you can do...)
+  for (int k=0;k<blocklength;k++) {
+    //std::cout << k << std::endl;
+    for(int i=0;i<FSM1.O();i++) {
+      float x=cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+0];
+      for(int j=1;j<FSM2.O();j++)
+        x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+j]);
+      prioro1[k*FSM1.O()+i]=x;
+      //std::cout <<  prioro1[k*FSM1.O()+i] << ", ";
+    }
+    //std::cout << std::endl;
+    for(int i=0;i<FSM2.O();i++) {
+      float x=cprioro[k*FSM1.O()*FSM2.O()+0*FSM1.O()+i];
+      for(int j=1;j<FSM1.O();j++)
+        x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+j*FSM1.O()+i]);
+      prioro2[k*FSM2.O()+i]=x;
+    }
+  }
+
+  for(int rep=0;rep<repetitions;rep++) {
+    // run  SISO 1
+    siso_algorithm(FSM1.I(),FSM1.S(),FSM1.O(),
+             FSM1.NS(), FSM1.OS(), FSM1.PS(), FSM1.PI(),
+             blocklength,
+             ST10,ST1K,
+             true, false,
+             p2mymin,
+             &(priori1[0]),  &(prioro1[0]), &(posti1[0])
+    );
+   
+    //for(int k=0;k<blocklength;k++){
+      //for(int i=0;i<FSM1.I();i++)
+        //std::cout << posti1[k*FSM1.I()+i] << ", ";
+      //std::cout << std::endl;
+    //}
+
+    //interleave soft info 1 -> 2
+    for(int k=0;k<blocklength;k++) {
+      int ki = INTERLEAVER.INTER()[k];
+      //for(int i=0;i<FSMi.I();i++) {
+        //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i];
+      //}
+      memcpy(&(priori2[k*FSM2.I()]),&(posti1[ki*FSM1.I()]),FSM1.I()*sizeof(float));
+    } 
+
+    // run SISO 2
+    siso_algorithm(FSM2.I(),FSM2.S(),FSM2.O(),
+           FSM2.NS(), FSM2.OS(), FSM2.PS(), FSM2.PI(),
+           blocklength,
+           ST20,ST2K,
+           true, false,
+           p2mymin,
+           &(priori2[0]),  &(prioro2[0]), &(posti2[0])
+    );
+
+    //interleave soft info 2 --> 1
+    for(int k=0;k<blocklength;k++) {
+      int ki = INTERLEAVER.INTER()[k];
+      //for(int i=0;i<FSMi.I();i++) {
+        //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i];
+      //}
+      memcpy(&(priori1[ki*FSM1.I()]),&(posti2[k*FSM2.I()]),FSM1.I()*sizeof(float));
+    }
+
+  } // end repetitions
+
+  // generate hard decisions
+  for(int k=0;k<blocklength;k++) {
+    for(int i=0;i<FSM1.I();i++)
+      posti1[k*FSM1.I()+i]  = (*p2mymin)(priori1[k*FSM1.I()+i],posti1[k*FSM1.I()+i]);
+    float min=INF;
+    int mini=0;
+    for(int i=0;i<FSM1.I();i++) {
+      if(posti1[k*FSM1.I()+i]<min) {
+        min=posti1[k*FSM1.I()+i];
+        mini=i;
+      }
+    }
+    data[k]=(T)mini;
+    //std::cout << data[k] << ", "<< std::endl;
+  }
+  //std::cout << std::endl;
+
+
+
+}
+
+//----------------
+
+template
+void pccc_decoder<unsigned char>(
+      const fsm &FSM1, int ST10, int ST1K,
+      const fsm &FSM2, int ST20, int ST2K,
+      const interleaver &INTERLEAVER, int blocklength, int repetitions,
+      float (*p2mymin)(float,float),
+      const float *cprioro, unsigned char *data
+);
+
+template
+void pccc_decoder<short>(
+      const fsm &FSM1, int ST10, int ST1K,
+      const fsm &FSM2, int ST20, int ST2K,
+      const interleaver &INTERLEAVER, int blocklength, int repetitions,
+      float (*p2mymin)(float,float),
+      const float *cprioro, short *data
+);
+
+template
+void pccc_decoder<int>(
+      const fsm &FSM1, int ST10, int ST1K,
+      const fsm &FSM2, int ST20, int ST2K,
+      const interleaver &INTERLEAVER, int blocklength, int repetitions,
+      float (*p2mymin)(float,float),
+      const float *cprioro, int *data
+);
+
-- 
cgit v1.2.3