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