Imported Upstream version 3.2.2
[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 3, 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., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include <float.h>
24 #include <stdexcept>
25 #include "trellis_calc_metric.h"
26
27
28
29 template <class T> 
30 void calc_metric(int O, int D, const std::vector<T> &TABLE, const T *in, float *metric, trellis_metric_type_t type)
31 {
32   float minm = FLT_MAX;
33   int minmi = 0;
34   
35
36   switch (type){
37   case TRELLIS_EUCLIDEAN:
38     for(int o=0;o<O;o++) {
39       metric[o]=0.0;
40       for (int m=0;m<D;m++) {
41         T s=in[m]-TABLE[o*D+m];
42         //gr_complex sc(1.0*s,0);
43         //metric[o]+=(sc*conj(sc)).real();
44         metric[o]+= s * s;
45       }
46     }
47     break;
48   case TRELLIS_HARD_SYMBOL:
49     for(int o=0;o<O;o++) {
50       metric[o]=0.0;
51       for (int m=0;m<D;m++) {
52         T s=in[m]-TABLE[o*D+m];
53         //gr_complex sc(1.0*s,0);
54         //metric[o]+=(sc*conj(sc)).real();
55         metric[o]+= s * s;
56       }
57       if(metric[o]<minm) {
58         minm=metric[o];
59         minmi=o;
60       }
61     }
62     for(int o=0;o<O;o++) {
63       metric[o] = (o==minmi?0.0:1.0);
64     }
65     break;
66   case TRELLIS_HARD_BIT:
67     throw std::runtime_error ("Invalid metric type (not yet implemented).");
68     break;
69   default:
70     throw std::runtime_error ("Invalid metric type.");
71   }
72 }
73
74
75
76 template
77 void calc_metric<short>(int O, int D, const std::vector<short> &TABLE, const short *in, float *metric, trellis_metric_type_t type);
78
79 template
80 void calc_metric<int>(int O, int D, const std::vector<int> &TABLE, const int *in, float *metric, trellis_metric_type_t type);
81
82 template
83 void calc_metric<float>(int O, int D, const std::vector<float> &TABLE, const float *in, float *metric, trellis_metric_type_t type);
84
85
86 /*
87 void calc_metric(int O, int D, const std::vector<short> &TABLE, const short *in, float *metric, trellis_metric_type_t type)
88 {
89   float minm = FLT_MAX;
90   int minmi = 0;
91
92   switch (type){
93   case TRELLIS_EUCLIDEAN:
94     for(int o=0;o<O;o++) {
95       metric[o]=0.0;
96       for (int m=0;m<D;m++) {
97         float s=in[m]-TABLE[o*D+m];
98         metric[o]+=s*s;
99       }
100     }
101     break;
102   case TRELLIS_HARD_SYMBOL:
103     for(int o=0;o<O;o++) {
104       metric[o]=0.0;
105       for (int m=0;m<D;m++) {
106         float s=in[m]-TABLE[o*D+m];
107         metric[o]+=s*s;
108       }
109       if(metric[o]<minm) {
110         minm=metric[o];
111         minmi=o;
112       }
113     }
114     for(int o=0;o<O;o++) {
115       metric[o] = (o==minmi?0.0:1.0);
116     }
117     break;
118   case TRELLIS_HARD_BIT:
119     throw std::runtime_error ("Invalid metric type (not yet implemented).");
120     break;
121   default:
122     throw std::runtime_error ("Invalid metric type.");
123   }
124 }
125
126
127 void calc_metric(int O, int D, const std::vector<int> &TABLE, const int *in, float *metric, trellis_metric_type_t type)
128 {
129   float minm = FLT_MAX;
130   int minmi = 0;
131
132   switch (type){
133   case TRELLIS_EUCLIDEAN:
134     for(int o=0;o<O;o++) {
135       metric[o]=0.0;
136       for (int m=0;m<D;m++) {
137         float s=in[m]-TABLE[o*D+m];
138         metric[o]+=s*s;
139       }
140     }
141     break;
142   case TRELLIS_HARD_SYMBOL:
143     for(int o=0;o<O;o++) {
144       metric[o]=0.0;
145       for (int m=0;m<D;m++) {
146         float s=in[m]-TABLE[o*D+m];
147         metric[o]+=s*s;
148       }
149       if(metric[o]<minm) {
150         minm=metric[o];
151         minmi=o;
152       }
153     }
154     for(int o=0;o<O;o++) {
155       metric[o] = (o==minmi?0.0:1.0);
156     }
157     break;
158   case TRELLIS_HARD_BIT:
159     throw std::runtime_error ("Invalid metric type (not yet implemented).");
160     break;
161   default:
162     throw std::runtime_error ("Invalid metric type.");
163   }
164 }
165
166
167
168 void calc_metric(int O, int D, const std::vector<float> &TABLE, const float *in, float *metric, trellis_metric_type_t type)
169 {
170   float minm = FLT_MAX;
171   int minmi = 0;
172
173   switch (type){
174   case TRELLIS_EUCLIDEAN:
175     for(int o=0;o<O;o++) {
176       metric[o]=0.0;
177       for (int m=0;m<D;m++) {
178         float s=in[m]-TABLE[o*D+m];
179         metric[o]+=s*s;
180       }
181     } 
182     break;
183   case TRELLIS_HARD_SYMBOL:
184     for(int o=0;o<O;o++) {
185       metric[o]=0.0;
186       for (int m=0;m<D;m++) {
187         float s=in[m]-TABLE[o*D+m];
188         metric[o]+=s*s;
189       }
190       if(metric[o]<minm) {
191         minm=metric[o];
192         minmi=o;
193       }
194     }
195     for(int o=0;o<O;o++) {
196       metric[o] = (o==minmi?0.0:1.0);
197     }
198     break;
199   case TRELLIS_HARD_BIT:
200     throw std::runtime_error ("Invalid metric type (not yet implemented).");
201     break;
202   default:
203     throw std::runtime_error ("Invalid metric type.");
204   }
205 }
206 */
207
208
209
210
211
212 void calc_metric(int O, int D, const std::vector<gr_complex> &TABLE, const gr_complex *in, float *metric, trellis_metric_type_t type)
213 {
214   float minm = FLT_MAX;
215   int minmi = 0;
216
217
218   switch (type){
219   case TRELLIS_EUCLIDEAN:
220     for(int o=0;o<O;o++) {
221       metric[o]=0.0;
222       for (int m=0;m<D;m++) {
223         gr_complex s=in[m]-TABLE[o*D+m];
224         metric[o]+=s.real()*s.real()+s.imag()*s.imag();
225       }
226     }
227     break;
228   case TRELLIS_HARD_SYMBOL:
229     for(int o=0;o<O;o++) {
230       metric[o]=0.0;
231       for (int m=0;m<D;m++) {
232         gr_complex s=in[m]-TABLE[o*D+m];
233         metric[o]+=s.real()*s.real()+s.imag()*s.imag();
234       }
235       if(metric[o]<minm) {
236         minm=metric[o];
237         minmi=o;
238       }
239     }
240     for(int o=0;o<O;o++) {
241       metric[o] = (o==minmi?0.0:1.0);
242     }
243     break;
244   case TRELLIS_HARD_BIT:
245     throw std::runtime_error ("Invalid metric type (not yet implemented).");
246     break;
247   default:
248     throw std::runtime_error ("Invalid metric type.");
249   }
250 }