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