Added support for concatenated codes
[debian/gnuradio] / gr-trellis / src / lib / trellis_calc_metric.cc
index c6d2ce98cb8435f50b48c0e5f1f09a0fafa52f0e..ae25a67bad4bd2a2b215ae65cd40dc76fdb6bea6 100644 (file)
 #include <stdexcept>
 #include "trellis_calc_metric.h"
 
-// soft decisions (Eucledean distance squared)
+// 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)
+{
+  float minm = FLT_MAX;
+  int minmi = 0;
+
+  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;
+       }
+    }
+    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;
+       }
+    }
+    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).");
+    break;
+  default:
+    throw std::runtime_error ("Invalid metric type.");
+  }
+}
+
+
+
+// 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)
+{
+  float minm = FLT_MAX;
+  int minmi = 0;
+
+  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;
+       }
+    }
+    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;
+       }
+    }
+    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).");
+    break;
+  default:
+    throw std::runtime_error ("Invalid metric type.");
+  }
+}
+
+
+
+
+
+
+
+// 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)
 {
   float minm = FLT_MAX;
@@ -65,7 +153,7 @@ void calc_metric_f(const int O, const int D, const std::vector<float> &TABLE, co
 }
 
 
-// soft decisions (Eucledean distance squared)
+// 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)
 {
   float minm = FLT_MAX;