implementation using templates
[debian/gnuradio] / gr-trellis / src / lib / trellis_calc_metric.cc
index 5faa4b7c70bd4c3d2a1ab02da6f9d9383fd068e0..ec2ed794d3e42ea50fcb5a1371fbb754d13a431e 100644 (file)
  * 
  * 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.
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
  */
 
 #include <float.h>
 #include <stdexcept>
 #include "trellis_calc_metric.h"
 
-void calc_metric_s(int O, int D, const std::vector<short> &TABLE, const short *in, float *metric, trellis_metric_type_t type)
+
+
+template <class T> 
+void calc_metric(int O, int D, const std::vector<T> &TABLE, const T *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++) {
+        T s=in[m]-TABLE[o*D+m];
+        //gr_complex sc(1.0*s,0);
+        //metric[o]+=(sc*conj(sc)).real();
+        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++) {
+        T s=in[m]-TABLE[o*D+m];
+        //gr_complex sc(1.0*s,0);
+        //metric[o]+=(sc*conj(sc)).real();
+        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.");
+  }
+}
+
+
+
+template
+void calc_metric<short>(int O, int D, const std::vector<short> &TABLE, const short *in, float *metric, trellis_metric_type_t type);
+
+template
+void calc_metric<int>(int O, int D, const std::vector<int> &TABLE, const int *in, float *metric, trellis_metric_type_t type);
+
+template
+void calc_metric<float>(int O, int D, const std::vector<float> &TABLE, const float *in, float *metric, trellis_metric_type_t type);
+
+
+/*
+void calc_metric(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;
@@ -64,8 +123,7 @@ void calc_metric_s(int O, int D, const std::vector<short> &TABLE, const short *i
 }
 
 
-
-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(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;
@@ -106,7 +164,7 @@ void calc_metric_i(int O, int D, const std::vector<int> &TABLE, const int *in, f
 
 
 
-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(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;
@@ -144,9 +202,13 @@ void calc_metric_f(int O, int D, const std::vector<float> &TABLE, const float *i
     throw std::runtime_error ("Invalid metric 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)
+void calc_metric(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;