Merged anastas/wip changes r3156:3218 into trunk.
[debian/gnuradio] / gr-trellis / src / lib / trellis_calc_metric.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2004 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <float.h>
24 #include <stdexcept>
25 #include "trellis_calc_metric.h"
26
27 // soft decisions (Eucledean distance squared)
28 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)
29 {
30   float minm = FLT_MAX;
31   int minmi = 0;
32
33   switch (type){
34   case TRELLIS_EUCLIDEAN:
35     for(int o=0;o<O;o++) {
36        metric[o]=0.0;
37        for (int m=0;m<D;m++) {
38            float s=in[m]-TABLE[o*D+m];
39            metric[o]+=s*s;
40        }
41     } 
42     break;
43   case TRELLIS_HARD_SYMBOL:
44     for(int o=0;o<O;o++) {
45        metric[o]=0.0;
46        for (int m=0;m<D;m++) {
47            float s=in[m]-TABLE[o*D+m];
48            metric[o]+=s*s;
49        }
50        if(metric[o]<minm) {
51          minm=metric[o];
52          minmi=o;
53        }
54     }
55     for(int o=0;o<O;o++) {
56       metric[o] = (o==minmi?0.0:1.0);
57     }
58     break;
59   case TRELLIS_HARD_BIT:
60     throw std::runtime_error ("Invalid metric type (not yet implemented).");
61     break;
62   default:
63     throw std::runtime_error ("Invalid metric type.");
64   }
65 }
66
67
68 // soft decisions (Eucledean distance squared)
69 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)
70 {
71   float minm = FLT_MAX;
72   int minmi = 0;
73
74   switch (type){
75   case TRELLIS_EUCLIDEAN:
76     for(int o=0;o<O;o++) {
77       metric[o]=0.0;
78       for (int m=0;m<D;m++) {
79         gr_complex s=in[m]-TABLE[o*D+m];
80         metric[o]+=s.real()*s.real()+s.imag()*s.imag();
81       }
82     }
83   case TRELLIS_HARD_SYMBOL:
84     throw std::runtime_error ("Invalid metric type (not yet implemented).");
85     break;
86   case TRELLIS_HARD_BIT:
87     throw std::runtime_error ("Invalid metric type (not yet implemented).");
88     break;
89   default:
90     throw std::runtime_error ("Invalid metric type.");
91   }
92 }