Several enhancements to gr-trellis and gnuradio-examples/python/channel-coding:
[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 void calc_metric_s(int O, int D, const std::vector<short> &TABLE, const short *in, float *metric, trellis_metric_type_t type)
28 {
29   float minm = FLT_MAX;
30   int minmi = 0;
31
32   switch (type){
33   case TRELLIS_EUCLIDEAN:
34     for(int o=0;o<O;o++) {
35       metric[o]=0.0;
36       for (int m=0;m<D;m++) {
37         float s=in[m]-TABLE[o*D+m];
38         metric[o]+=s*s;
39       }
40     }
41     break;
42   case TRELLIS_HARD_SYMBOL:
43     for(int o=0;o<O;o++) {
44       metric[o]=0.0;
45       for (int m=0;m<D;m++) {
46         float s=in[m]-TABLE[o*D+m];
47         metric[o]+=s*s;
48       }
49       if(metric[o]<minm) {
50         minm=metric[o];
51         minmi=o;
52       }
53     }
54     for(int o=0;o<O;o++) {
55       metric[o] = (o==minmi?0.0:1.0);
56     }
57     break;
58   case TRELLIS_HARD_BIT:
59     throw std::runtime_error ("Invalid metric type (not yet implemented).");
60     break;
61   default:
62     throw std::runtime_error ("Invalid metric type.");
63   }
64 }
65
66
67
68 void calc_metric_i(int O, int D, const std::vector<int> &TABLE, const int *in, float *metric, trellis_metric_type_t type)
69 {
70   float minm = FLT_MAX;
71   int minmi = 0;
72
73   switch (type){
74   case TRELLIS_EUCLIDEAN:
75     for(int o=0;o<O;o++) {
76       metric[o]=0.0;
77       for (int m=0;m<D;m++) {
78         float s=in[m]-TABLE[o*D+m];
79         metric[o]+=s*s;
80       }
81     }
82     break;
83   case TRELLIS_HARD_SYMBOL:
84     for(int o=0;o<O;o++) {
85       metric[o]=0.0;
86       for (int m=0;m<D;m++) {
87         float s=in[m]-TABLE[o*D+m];
88         metric[o]+=s*s;
89       }
90       if(metric[o]<minm) {
91         minm=metric[o];
92         minmi=o;
93       }
94     }
95     for(int o=0;o<O;o++) {
96       metric[o] = (o==minmi?0.0:1.0);
97     }
98     break;
99   case TRELLIS_HARD_BIT:
100     throw std::runtime_error ("Invalid metric type (not yet implemented).");
101     break;
102   default:
103     throw std::runtime_error ("Invalid metric type.");
104   }
105 }
106
107
108
109 void calc_metric_f(int O, int D, const std::vector<float> &TABLE, const float *in, float *metric, trellis_metric_type_t type)
110 {
111   float minm = FLT_MAX;
112   int minmi = 0;
113
114   switch (type){
115   case TRELLIS_EUCLIDEAN:
116     for(int o=0;o<O;o++) {
117       metric[o]=0.0;
118       for (int m=0;m<D;m++) {
119         float s=in[m]-TABLE[o*D+m];
120         metric[o]+=s*s;
121       }
122     } 
123     break;
124   case TRELLIS_HARD_SYMBOL:
125     for(int o=0;o<O;o++) {
126       metric[o]=0.0;
127       for (int m=0;m<D;m++) {
128         float s=in[m]-TABLE[o*D+m];
129         metric[o]+=s*s;
130       }
131       if(metric[o]<minm) {
132         minm=metric[o];
133         minmi=o;
134       }
135     }
136     for(int o=0;o<O;o++) {
137       metric[o] = (o==minmi?0.0:1.0);
138     }
139     break;
140   case TRELLIS_HARD_BIT:
141     throw std::runtime_error ("Invalid metric type (not yet implemented).");
142     break;
143   default:
144     throw std::runtime_error ("Invalid metric type.");
145   }
146 }
147
148
149 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)
150 {
151   float minm = FLT_MAX;
152   int minmi = 0;
153
154   switch (type){
155   case TRELLIS_EUCLIDEAN:
156     for(int o=0;o<O;o++) {
157       metric[o]=0.0;
158       for (int m=0;m<D;m++) {
159         gr_complex s=in[m]-TABLE[o*D+m];
160         metric[o]+=s.real()*s.real()+s.imag()*s.imag();
161       }
162     }
163   case TRELLIS_HARD_SYMBOL:
164     for(int o=0;o<O;o++) {
165       metric[o]=0.0;
166       for (int m=0;m<D;m++) {
167         gr_complex s=in[m]-TABLE[o*D+m];
168         metric[o]+=s.real()*s.real()+s.imag()*s.imag();
169       }
170       if(metric[o]<minm) {
171         minm=metric[o];
172         minmi=o;
173       }
174     }
175     for(int o=0;o<O;o++) {
176       metric[o] = (o==minmi?0.0:1.0);
177     }
178     break;
179   case TRELLIS_HARD_BIT:
180     throw std::runtime_error ("Invalid metric type (not yet implemented).");
181     break;
182   default:
183     throw std::runtime_error ("Invalid metric type.");
184   }
185 }