Several enhancements to gr-trellis and gnuradio-examples/python/channel-coding:
[debian/gnuradio] / gr-trellis / src / lib / trellis_calc_metric.cc
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).");