]> git.gag.com Git - debian/gnuradio/blob - gr-trellis/src/lib/trellis_calc_metric.cc
ae25a67bad4bd2a2b215ae65cd40dc76fdb6bea6
[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 (Euclidean distance squared)
28 void calc_metric_s(const int O, const int D, const std::vector<short> &TABLE, const short *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
69 // soft decisions (Euclidean distance squared)
70 void calc_metric_i(const int O, const int D, const std::vector<int> &TABLE, const int *in, float *metric, trellis_metric_type_t type)
71 {
72   float minm = FLT_MAX;
73   int minmi = 0;
74
75   switch (type){
76   case TRELLIS_EUCLIDEAN:
77     for(int o=0;o<O;o++) {
78        metric[o]=0.0;
79        for (int m=0;m<D;m++) {
80            float s=in[m]-TABLE[o*D+m];
81            metric[o]+=s*s;
82        }
83     }
84     break;
85   case TRELLIS_HARD_SYMBOL:
86     for(int o=0;o<O;o++) {
87        metric[o]=0.0;
88        for (int m=0;m<D;m++) {
89            float s=in[m]-TABLE[o*D+m];
90            metric[o]+=s*s;
91        }
92        if(metric[o]<minm) {
93          minm=metric[o];
94          minmi=o;
95        }
96     }
97     for(int o=0;o<O;o++) {
98       metric[o] = (o==minmi?0.0:1.0);
99     }
100     break;
101   case TRELLIS_HARD_BIT:
102     throw std::runtime_error ("Invalid metric type (not yet implemented).");
103     break;
104   default:
105     throw std::runtime_error ("Invalid metric type.");
106   }
107 }
108
109
110
111
112
113
114
115 // soft decisions (Euclidean distance squared)
116 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)
117 {
118   float minm = FLT_MAX;
119   int minmi = 0;
120
121   switch (type){
122   case TRELLIS_EUCLIDEAN:
123     for(int o=0;o<O;o++) {
124        metric[o]=0.0;
125        for (int m=0;m<D;m++) {
126            float s=in[m]-TABLE[o*D+m];
127            metric[o]+=s*s;
128        }
129     } 
130     break;
131   case TRELLIS_HARD_SYMBOL:
132     for(int o=0;o<O;o++) {
133        metric[o]=0.0;
134        for (int m=0;m<D;m++) {
135            float s=in[m]-TABLE[o*D+m];
136            metric[o]+=s*s;
137        }
138        if(metric[o]<minm) {
139          minm=metric[o];
140          minmi=o;
141        }
142     }
143     for(int o=0;o<O;o++) {
144       metric[o] = (o==minmi?0.0:1.0);
145     }
146     break;
147   case TRELLIS_HARD_BIT:
148     throw std::runtime_error ("Invalid metric type (not yet implemented).");
149     break;
150   default:
151     throw std::runtime_error ("Invalid metric type.");
152   }
153 }
154
155
156 // soft decisions (Euclidean distance squared)
157 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)
158 {
159   float minm = FLT_MAX;
160   int minmi = 0;
161
162   switch (type){
163   case TRELLIS_EUCLIDEAN:
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     }
171   case TRELLIS_HARD_SYMBOL:
172     throw std::runtime_error ("Invalid metric type (not yet implemented).");
173     break;
174   case TRELLIS_HARD_BIT:
175     throw std::runtime_error ("Invalid metric type (not yet implemented).");
176     break;
177   default:
178     throw std::runtime_error ("Invalid metric type.");
179   }
180 }