3 * Copyright 2006 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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)
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.
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.
27 #include <code_metrics.h>
32 code_metric_ff::code_metric_ff
33 (pdf_fcn_t pdf_fcn_0_bit,
34 pdf_fcn_t pdf_fcn_1_bit,
36 pdf_fcn_io_t min_sample,
37 pdf_fcn_io_t max_sample)
40 fprintf (stderr, "code_metric_f32:: n_samples "
41 "must be at least 2.\n");
44 if (min_sample >= max_sample) {
45 fprintf (stderr, "code_metric_f32:: min_sample must be "
46 "less than max_sample.\n");
49 if (! pdf_fcn_0_bit) {
50 fprintf (stderr, "code_metric_f32:: pdf_fcn_0_bit must be "
51 "a non-null pointer to function.\n");
54 if (! pdf_fcn_1_bit) {
55 fprintf (stderr, "code_metric_f32:: pdf_fcn_0_bit must be "
56 "a non-null pointer to function.\n");
60 d_n_samples = n_samples;
61 d_max_sample = max_sample;
62 d_min_sample = min_sample;
63 d_delta = (max_sample - min_sample) / (n_samples - 1);
64 d_pdf_fcn_0_bit = pdf_fcn_0_bit;
65 d_pdf_fcn_1_bit = pdf_fcn_1_bit;
66 d_metric_table_0_bit.assign (n_samples, 0);
67 d_metric_table_1_bit.assign (n_samples, 0);
69 pdf_fcn_io_t l_val = min_sample;
70 for (size_t m = 0; m < n_samples; m++) {
71 d_metric_table_0_bit[m] = logf ((*pdf_fcn_0_bit)(l_val));
72 d_metric_table_1_bit[m] = logf ((*pdf_fcn_1_bit)(l_val));
77 void code_metric_ff::lookup
82 metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
83 metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
85 if (sym <= d_min_sample) {
86 *l_bit_0 = d_metric_table_0_bit[0];
87 *l_bit_1 = d_metric_table_1_bit[0];
90 if (sym >= d_max_sample) {
91 *l_bit_0 = d_metric_table_0_bit.back ();
92 *l_bit_1 = d_metric_table_1_bit.back ();
96 size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
97 *l_bit_0 = d_metric_table_0_bit[l_ndx];
98 *l_bit_1 = d_metric_table_1_bit[l_ndx];
101 void code_metric_ff::convert
107 metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
108 metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
110 for (size_t m = n_syms; m > 0; m--)
111 lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
114 code_metric_fl::code_metric_fl
115 (pdf_fcn_t pdf_fcn_0_bit,
116 pdf_fcn_t pdf_fcn_1_bit,
118 pdf_fcn_io_t min_sample,
119 pdf_fcn_io_t max_sample,
120 int sample_precision)
123 fprintf (stderr, "code_metric_fl:: n_samples "
124 "must be at least 2.\n");
127 if (min_sample >= max_sample) {
128 fprintf (stderr, "code_metric_fl:: min_sample must be "
129 "less than max_sample.\n");
132 if (! pdf_fcn_0_bit) {
133 fprintf (stderr, "code_metric_fl:: pdf_fcn_0_bit must be "
134 "a non-null pointer to function.\n");
137 if (! pdf_fcn_1_bit) {
138 fprintf (stderr, "code_metric_fl:: pdf_fcn_0_bit must be "
139 "a non-null pointer to function.\n");
142 if (sample_precision < 16 || sample_precision > 32) {
143 fprintf (stderr, "code_metric_fl:: sample_precision must be "
144 "between 16 and 32 for this class.\n");
148 d_sample_precision = sample_precision;
149 d_n_samples = n_samples;
150 d_max_sample = max_sample;
151 d_min_sample = min_sample;
152 d_delta = (max_sample - min_sample) / (n_samples - 1);
153 d_pdf_fcn_0_bit = pdf_fcn_0_bit;
154 d_pdf_fcn_1_bit = pdf_fcn_1_bit;
155 d_metric_table_0_bit.assign (n_samples, 0);
156 d_metric_table_1_bit.assign (n_samples, 0);
158 // get the scale factor for converting from float to sample_precision
160 // logf (pdf_fcn_0_bit->eval (d_min_sample)) -> l_min_map
161 // logf (pdf_fcn_0_bit->eval (d_max_sample)) -> l_max_map
163 metric_t l_min_map = - (1 << (sample_precision - 1));
165 pdf_fcn_io_t l_min_log_val_0 = logf ((*pdf_fcn_0_bit)(d_min_sample));
166 pdf_fcn_io_t l_max_log_val_0 = logf ((*pdf_fcn_0_bit)(d_max_sample));
167 pdf_fcn_io_t l_slope_0 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
168 (l_max_log_val_0 - l_min_log_val_0));
169 pdf_fcn_io_t l_min_log_val_1 = logf ((*pdf_fcn_1_bit)(d_min_sample));
170 pdf_fcn_io_t l_max_log_val_1 = logf ((*pdf_fcn_1_bit)(d_max_sample));
171 pdf_fcn_io_t l_slope_1 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
172 (l_max_log_val_1 - l_min_log_val_1));
174 pdf_fcn_io_t l_val = d_min_sample;
175 for (size_t m = 0; m < d_n_samples; m++) {
176 d_metric_table_0_bit[m] =
177 (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
178 (l_slope_0 * (logf ((*pdf_fcn_0_bit)(l_val)) -
180 d_metric_table_1_bit[m] =
181 (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
182 (l_slope_1 * (logf ((*pdf_fcn_1_bit)(l_val)) -
188 void code_metric_fl::lookup
193 metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
194 metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
196 if (sym <= d_min_sample) {
197 *l_bit_0 = d_metric_table_0_bit[0];
198 *l_bit_1 = d_metric_table_1_bit[0];
201 if (sym >= d_max_sample) {
202 *l_bit_0 = d_metric_table_0_bit.back ();
203 *l_bit_1 = d_metric_table_1_bit.back ();
207 size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
208 *l_bit_0 = d_metric_table_0_bit[l_ndx];
209 *l_bit_1 = d_metric_table_1_bit[l_ndx];
212 void code_metric_fl::convert
218 metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
219 metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
221 for (size_t m = n_syms; m > 0; m--)
222 lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
225 code_metric_fs::code_metric_fs
226 (pdf_fcn_t pdf_fcn_0_bit,
227 pdf_fcn_t pdf_fcn_1_bit,
229 pdf_fcn_io_t min_sample,
230 pdf_fcn_io_t max_sample,
231 int sample_precision)
234 fprintf (stderr, "code_metric_fs:: n_samples "
235 "must be at least 2.\n");
238 if (min_sample >= max_sample) {
239 fprintf (stderr, "code_metric_fs:: min_sample must be "
240 "less than max_sample.\n");
243 if (! pdf_fcn_0_bit) {
244 fprintf (stderr, "code_metric_fs:: pdf_fcn_0_bit must be "
245 "a non-null pointer to function.\n");
248 if (! pdf_fcn_1_bit) {
249 fprintf (stderr, "code_metric_fs:: pdf_fcn_0_bit must be "
250 "a non-null pointer to function.\n");
253 if (sample_precision < 9 || sample_precision > 16) {
254 fprintf (stderr, "code_metric_fs:: sample_precision must be "
255 "between 9 and 16 for this class.\n");
259 d_sample_precision = sample_precision;
260 d_n_samples = n_samples;
261 d_max_sample = max_sample;
262 d_min_sample = min_sample;
263 d_delta = (max_sample - min_sample) / (n_samples - 1);
264 d_pdf_fcn_0_bit = pdf_fcn_0_bit;
265 d_pdf_fcn_1_bit = pdf_fcn_1_bit;
266 d_metric_table_0_bit.assign (n_samples, 0);
267 d_metric_table_1_bit.assign (n_samples, 0);
269 // get the scale factor for converting from float to sample_precision
271 // logf (pdf_fcn_0_bit->eval (d_min_sample)) -> l_min_map
272 // logf (pdf_fcn_0_bit->eval (d_max_sample)) -> l_max_map
274 metric_t l_min_map = - (1 << (sample_precision - 1));
276 pdf_fcn_io_t l_min_log_val_0 = logf ((*pdf_fcn_0_bit)(d_min_sample));
277 pdf_fcn_io_t l_max_log_val_0 = logf ((*pdf_fcn_0_bit)(d_max_sample));
278 pdf_fcn_io_t l_slope_0 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
279 (l_max_log_val_0 - l_min_log_val_0));
280 pdf_fcn_io_t l_min_log_val_1 = logf ((*pdf_fcn_1_bit)(d_min_sample));
281 pdf_fcn_io_t l_max_log_val_1 = logf ((*pdf_fcn_1_bit)(d_max_sample));
282 pdf_fcn_io_t l_slope_1 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
283 (l_max_log_val_1 - l_min_log_val_1));
285 pdf_fcn_io_t l_val = d_min_sample;
286 for (size_t m = 0; m < d_n_samples; m++) {
287 d_metric_table_0_bit[m] =
288 (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
289 (l_slope_0 * (logf ((*pdf_fcn_0_bit)(l_val)) -
291 d_metric_table_1_bit[m] =
292 (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
293 (l_slope_1 * (logf ((*pdf_fcn_1_bit)(l_val)) -
299 void code_metric_fs::lookup
304 metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
305 metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
307 if (sym <= d_min_sample) {
308 *l_bit_0 = d_metric_table_0_bit[0];
309 *l_bit_1 = d_metric_table_1_bit[0];
312 if (sym >= d_max_sample) {
313 *l_bit_0 = d_metric_table_0_bit.back ();
314 *l_bit_1 = d_metric_table_1_bit.back ();
318 size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
319 *l_bit_0 = d_metric_table_0_bit[l_ndx];
320 *l_bit_1 = d_metric_table_1_bit[l_ndx];
323 void code_metric_fs::convert
329 metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
330 metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
332 for (size_t m = n_syms; m > 0; m--)
333 lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
336 code_metric_fb::code_metric_fb
337 (pdf_fcn_t pdf_fcn_0_bit,
338 pdf_fcn_t pdf_fcn_1_bit,
340 pdf_fcn_io_t min_sample,
341 pdf_fcn_io_t max_sample,
342 int sample_precision)
345 fprintf (stderr, "code_metric_fb:: n_samples "
346 "must be at least 2.\n");
349 if (min_sample >= max_sample) {
350 fprintf (stderr, "code_metric_fb:: min_sample must be "
351 "less than max_sample.\n");
354 if (! pdf_fcn_0_bit) {
355 fprintf (stderr, "code_metric_fb:: pdf_fcn_0_bit must be "
356 "a non-null pointer to function.\n");
359 if (! pdf_fcn_1_bit) {
360 fprintf (stderr, "code_metric_fb:: pdf_fcn_0_bit must be "
361 "a non-null pointer to function.\n");
364 if (sample_precision < 1 || sample_precision > 8) {
365 fprintf (stderr, "code_metric_fb:: sample_precision must be "
366 "between 1 and 8 for this class.\n");
370 d_sample_precision = sample_precision;
371 d_n_samples = n_samples;
372 d_max_sample = max_sample;
373 d_min_sample = min_sample;
374 d_delta = (max_sample - min_sample) / (n_samples - 1);
375 d_pdf_fcn_0_bit = pdf_fcn_0_bit;
376 d_pdf_fcn_1_bit = pdf_fcn_1_bit;
377 d_metric_table_0_bit.assign (n_samples, 0);
378 d_metric_table_1_bit.assign (n_samples, 0);
380 // get the scale factor for converting from float to sample_precision
382 // logf (pdf_fcn_0_bit->eval (d_min_sample)) -> l_min_map
383 // logf (pdf_fcn_0_bit->eval (d_max_sample)) -> l_max_map
385 metric_t l_min_map = - (1 << (sample_precision - 1));
387 pdf_fcn_io_t l_min_log_val_0 = logf ((*pdf_fcn_0_bit)(d_min_sample));
388 pdf_fcn_io_t l_max_log_val_0 = logf ((*pdf_fcn_0_bit)(d_max_sample));
389 pdf_fcn_io_t l_slope_0 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
390 (l_max_log_val_0 - l_min_log_val_0));
391 pdf_fcn_io_t l_min_log_val_1 = logf ((*pdf_fcn_1_bit)(d_min_sample));
392 pdf_fcn_io_t l_max_log_val_1 = logf ((*pdf_fcn_1_bit)(d_max_sample));
393 pdf_fcn_io_t l_slope_1 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
394 (l_max_log_val_1 - l_min_log_val_1));
396 pdf_fcn_io_t l_val = d_min_sample;
397 for (size_t m = 0; m < d_n_samples; m++) {
398 d_metric_table_0_bit[m] =
399 (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
400 (l_slope_0 * (logf ((*pdf_fcn_0_bit)(l_val)) -
402 d_metric_table_1_bit[m] =
403 (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
404 (l_slope_1 * (logf ((*pdf_fcn_1_bit)(l_val)) -
410 void code_metric_fb::lookup
415 metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
416 metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
418 if (sym <= d_min_sample) {
419 *l_bit_0 = d_metric_table_0_bit[0];
420 *l_bit_1 = d_metric_table_1_bit[0];
423 if (sym >= d_max_sample) {
424 *l_bit_0 = d_metric_table_0_bit.back ();
425 *l_bit_1 = d_metric_table_1_bit.back ();
429 size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
430 *l_bit_0 = d_metric_table_0_bit[l_ndx];
431 *l_bit_1 = d_metric_table_1_bit[l_ndx];
434 void code_metric_fb::convert
440 metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
441 metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
443 for (size_t m = n_syms; m > 0; m--)
444 lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);