📄 qa_gr_fir_ccc.cc
字号:
/* -*- c++ -*- *//* * Copyright 2002 Free Software Foundation, Inc. * * This file is part of GNU Radio * * GNU Radio is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GNU Radio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Radio; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * FIXME. This code is virtually identical to qa_gr_fir_?CC.cc * Kludge up some kind of macro to handle the minor differences. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <gr_types.h>typedef gr_complex i_type;typedef gr_complex o_type;typedef gr_complex tap_type;typedef gr_complex acc_type;#include <qa_gr_fir_ccc.h>#include <gr_fir_ccc.h>#include <gr_fir_util.h>#include <string.h>#include <iostream>#include <cmath>#include <gr_types.h>#include <cppunit/TestAssert.h>#include <random.h>using std::vector;#define ERR_DELTA (1e-5)#define NELEM(x) (sizeof (x) / sizeof (x[0]))//// typedef for something logically "pointer to constructor".// there may be a better way, please let me know...//typedef gr_fir_ccc* (*fir_maker_t)(const std::vector<tap_type> &taps);static floatuniform (){ return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)}static voidrandom_input (i_type *buf, unsigned n){ for (unsigned i = 0; i < n; i++) buf[i] = (i_type) rint (uniform () * 32767);}static voidrandom_complex (gr_complex *buf, unsigned n){ for (unsigned i = 0; i < n; i++){ float re = rint (uniform () * 32767); float im = rint (uniform () * 32767); buf[i] = gr_complex (re, im); }}static o_typeref_dotprod (const i_type input[], const tap_type taps[], int ntaps){ acc_type sum = 0; for (int i = 0; i < ntaps; i++) sum += input[i] * taps[i]; return sum;}//// Test for ntaps in [0,9], and input lengths in [0,17].// This ensures that we are building the shifted taps correctly,// and exercises all corner cases on input alignment and length.//static voidtest_random_io (fir_maker_t maker) { const int MAX_TAPS = 9; const int OUTPUT_LEN = 17; const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN; i_type input[INPUT_LEN]; o_type expected_output[OUTPUT_LEN]; o_type actual_output[OUTPUT_LEN]; tap_type taps[MAX_TAPS]; srandom (0); // we want reproducibility for (int n = 0; n <= MAX_TAPS; n++){ for (int ol = 0; ol <= OUTPUT_LEN; ol++){ // cerr << "@@@ n:ol " << n << ":" << ol << endl; // build random test case random_input (input, INPUT_LEN); random_complex (taps, MAX_TAPS); // compute expected output values for (int o = 0; o < ol; o++){ expected_output[o] = ref_dotprod (&input[o], taps, n); } // build filter vector<tap_type> f1_taps (&taps[0], &taps[n]); gr_fir_ccc *f1 = maker (f1_taps); // zero the output, then do the filtering memset (actual_output, 0, sizeof (actual_output)); f1->filterN (actual_output, input, ol); // check results // // we use a sloppy error margin because on the x86 architecture, // our reference implementation is using 80 bit floating point // arithmetic, while the SSE version is using 32 bit float point // arithmetic. for (int o = 0; o < ol; o++){ ASSERT_COMPLEXES_EQUAL (expected_output[o], actual_output[o], abs (expected_output[o]) * ERR_DELTA); } delete f1; } }}static voidfor_each (void (*f)(fir_maker_t)){ std::vector<gr_fir_ccc_info> info; gr_fir_util::get_gr_fir_ccc_info (&info); // get all known ccc implementations for (std::vector<gr_fir_ccc_info>::iterator p = info.begin (); p != info.end (); ++p){ std::cerr << " [" << p->name << "]"; f (p->create); } std::cerr << std::endl;}voidqa_gr_fir_ccc::t1 (){ for_each (test_random_io);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -