Changeset 9384

Show
Ignore:
Timestamp:
08/23/08 15:26:19
Author:
eb
Message:

Fix for ticket:214, gr_rotate speedup. We now normalize once every
512 cycles. We also now compute the return value based on the
preincremented phase value, thus shortening the dependency chain.
This does put the computed result 1 tick ahead of the previous version
of the code, but none of the code in the tree depends on the absolute
phase. If yours does, sorry. You can work around it by initializing
the phase to conj(gr_expj(phase_incr)) instead of gr_complex(1,0).
Added QA code to ensure I didn't break anything.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gnuradio/trunk/gnuradio-core/src/lib/filter/Makefile.am

    r9336 r9384  
    231231        qa_gr_fir_ccc.cc                \ 
    232232        qa_gr_fir_scc.cc                \ 
     233        qa_gr_rotator.cc                \ 
    233234        qa_gri_mmse_fir_interpolator.cc \ 
    234235        qa_gri_mmse_fir_interpolator_cc.cc       
     
    318319        qa_gr_fir_ccc.h                 \ 
    319320        qa_gr_fir_scc.h                 \ 
     321        qa_gr_rotator.h                 \ 
    320322        qa_gri_mmse_fir_interpolator.h  \ 
    321323        qa_gri_mmse_fir_interpolator_cc.h        
  • gnuradio/trunk/gnuradio-core/src/lib/filter/gr_rotator.h

    r6044 r9384  
    11/* -*- c++ -*- */ 
    22/* 
    3  * Copyright 2003 Free Software Foundation, Inc. 
     3 * Copyright 2003,2008 Free Software Foundation, Inc. 
    44 *  
    55 * This file is part of GNU Radio 
     
    2929  gr_complex    d_phase; 
    3030  gr_complex    d_phase_incr; 
     31  unsigned int  d_counter; 
    3132 
    3233 public: 
    33   gr_rotator () : d_phase (1), d_phase_incr (0) { } 
     34  gr_rotator () : d_phase (1), d_phase_incr (1), d_counter(0) { } 
    3435 
    35   void set_phase (gr_complex phase)     { d_phase = phase; } 
    36   void set_phase_incr (gr_complex incr) { d_phase_incr = incr; } 
     36  void set_phase (gr_complex phase)     { d_phase = phase / abs(phase); } 
     37  void set_phase_incr (gr_complex incr) { d_phase_incr = incr / abs(incr); } 
    3738 
    3839  gr_complex rotate (gr_complex in){ 
    39     d_phase *= d_phase_incr;   // incr our phase (complex mult == add phases) 
     40    d_counter++; 
    4041 
    41     d_phase /= abs(d_phase);    // ensure multiplication is rotation 
    42                                 // FIXME.  This is expensive.  Maybe workaround using 
    43                                 // double precision complex??? 
     42    gr_complex z = in * d_phase;    // rotate in by phase 
     43    d_phase *= d_phase_incr;        // incr our phase (complex mult == add phases) 
    4444 
    45     return in * d_phase;        // rotate in by phase 
     45    if ((d_counter % 512) == 0) 
     46      d_phase /= abs(d_phase);      // Normalize to ensure multiplication is rotation 
     47 
     48    return z; 
    4649  } 
    4750 
  • gnuradio/trunk/gnuradio-core/src/lib/filter/qa_filter.cc

    r9336 r9384  
    3636#include <qa_gri_mmse_fir_interpolator.h> 
    3737#include <qa_gri_mmse_fir_interpolator_cc.h> 
     38#include <qa_gr_rotator.h> 
    3839 
    3940CppUnit::TestSuite * 
     
    5051  s->addTest (qa_gri_mmse_fir_interpolator::suite ()); 
    5152  s->addTest (qa_gri_mmse_fir_interpolator_cc::suite ()); 
     53  s->addTest (qa_gr_rotator::suite ()); 
    5254 
    5355  return s; 
  • gnuradio/trunk/gnuradio-core/src/lib/filter/qa_gr_rotator.cc

    r9378 r9384  
    2222 
    2323#include <cppunit/TestAssert.h> 
    24 #include <qa_gri_mmse_fir_interpolator.h> 
    25 #include <gri_mmse_fir_interpolator.h> 
     24#include <qa_gr_rotator.h> 
     25#include <gr_rotator.h> 
    2626#include <stdio.h> 
    2727#include <cmath> 
    28  
    29 #define NELEM(x) (sizeof (x) / sizeof (x[0])) 
     28#include <gr_expj.h> 
    3029 
    3130 
    32 static float 
    33 test_fcn (double index) 
     31// error vector magnitude 
     32__attribute__((unused)) static float 
     33error_vector_mag(gr_complex a, gr_complex b)  
    3434{ 
    35   return (2 * sin (index * 0.25 * 2 * M_PI + 0.125 * M_PI) 
    36           + 3 * sin (index * 0.077 * 2 * M_PI + 0.3 * M_PI)); 
     35  return abs(a-b); 
    3736} 
    3837 
     38void 
     39qa_gr_rotator::t1 () 
     40{ 
     41  static const unsigned int N = 100000; 
    3942 
    40 void 
    41 qa_gri_mmse_fir_interpolator::t1 () 
    42 
    43   static const unsigned N = 100; 
    44   float input[N + 10]; 
     43  gr_rotator    r; 
    4544 
    46   for (unsigned i = 0; i < NELEM(input); i++) 
    47     input[i] = test_fcn ((double) i)
     45  double phase_incr = 2*M_PI / 1003; 
     46  double phase = 0
    4847 
    49   gri_mmse_fir_interpolator     intr; 
    50   float inv_nsteps = 1.0 / intr.nsteps (); 
     48  // Old code: We increment then return the rotated value, thus we need to start one tick back 
     49  // r.set_phase(gr_complex(1,0) * conj(gr_expj(phase_incr))); 
     50 
     51  r.set_phase(gr_complex(1,0)); 
     52  r.set_phase_incr(gr_expj(phase_incr)); 
    5153 
    5254  for (unsigned i = 0; i < N; i++){ 
    53     for (unsigned imu = 0; imu <= intr.nsteps (); imu += 1){ 
    54       float expected = test_fcn ((i + 3) + imu * inv_nsteps); 
    55       float actual = intr.interpolate (&input[i], imu * inv_nsteps); 
     55    gr_complex expected = gr_expj(phase); 
     56    gr_complex actual = r.rotate(gr_complex(1, 0)); 
    5657 
    57       CPPUNIT_ASSERT_DOUBLES_EQUAL (expected, actual, 0.004); 
    58       // printf ("%9.6f  %9.6f  %9.6f\n", expected, actual, expected - actual); 
    59     } 
     58#if 0 
     59    float evm = error_vector_mag(expected, actual); 
     60    printf("[%6d] expected: (%8.6f, %8.6f)  actual: (%8.6f, %8.6f)  evm: %8.6f\n", 
     61           i, expected.real(), expected.imag(), actual.real(), actual.imag(), evm); 
     62#endif 
     63 
     64    CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected, actual, 0.0001); 
     65 
     66    phase += phase_incr; 
     67    if (phase >= 2*M_PI) 
     68      phase -= 2*M_PI; 
    6069  } 
    6170} 
    62  
  • gnuradio/trunk/gnuradio-core/src/lib/filter/qa_gr_rotator.h

    r9378 r9384  
    11/* -*- c++ -*- */ 
    22/* 
    3  * Copyright 2002 Free Software Foundation, Inc. 
     3 * Copyright 2008 Free Software Foundation, Inc. 
    44 *  
    55 * This file is part of GNU Radio 
     
    2020 * Boston, MA 02110-1301, USA. 
    2121 */ 
    22 #ifndef _QA_GRI_MMSE_FIR_INTERPOLATOR_H_ 
    23 #define _QA_GRI_MMSE_FIR_INTERPOLATOR_H_ 
     22#ifndef _QA_GR_ROTATOR_H_ 
     23#define _QA_GR_ROTATOR_H_ 
    2424 
    2525#include <cppunit/extensions/HelperMacros.h> 
    2626#include <cppunit/TestCase.h> 
    2727 
    28 class qa_gri_mmse_fir_interpolator : public CppUnit::TestCase { 
     28class qa_gr_rotator : public CppUnit::TestCase { 
    2929 
    30   CPPUNIT_TEST_SUITE (qa_gri_mmse_fir_interpolator); 
     30  CPPUNIT_TEST_SUITE (qa_gr_rotator); 
    3131  CPPUNIT_TEST (t1); 
    3232  CPPUNIT_TEST_SUITE_END (); 
     
    3737}; 
    3838 
    39  
    40 #endif /* _QA_GRI_MMSE_FIR_INTERPOLATOR_H_ */ 
     39#endif /* _QA_GR_ROTATOR_H_ */