]> git.gag.com Git - debian/gnuradio/commitdiff
Merged changeset r4153:4167 on n4hy/iir into trunk.
authorn4hy <n4hy@221aa14e-8319-0410-a670-987f0aec2ac5>
Thu, 21 Dec 2006 19:41:29 +0000 (19:41 +0000)
committern4hy <n4hy@221aa14e-8319-0410-a670-987f0aec2ac5>
Thu, 21 Dec 2006 19:41:29 +0000 (19:41 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@4182 221aa14e-8319-0410-a670-987f0aec2ac5

gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc
gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h
gnuradio-core/src/lib/filter/gri_iir.h
gnuradio-core/src/python/gnuradio/gr/qa_iir.py

index be1cfbc470566691feb6d2e65372e726199e2686..1a1a28f031c40ece3603a9d7f4b7e15269df1fab 100644 (file)
@@ -57,11 +57,6 @@ void
 gr_iir_filter_ffd::set_taps (const std::vector<double> &fftaps,
                             const std::vector<double> &fbtaps) throw (std::invalid_argument)
 {
-  if (fftaps.size () != fbtaps.size ()){
-    fprintf (stderr,
-     "gr_iir_filter_ffd::set_taps: fftaps and fbtaps must have the same number of elements.\n");
-    throw std::invalid_argument ("gr_iir_filter_ffd::set_taps");
-  }
   
   d_new_fftaps = fftaps;
   d_new_fbtaps = fbtaps;
@@ -76,7 +71,6 @@ gr_iir_filter_ffd::work (int noutput_items,
   const float *in = (const float *) input_items[0];
   float *out = (float *) output_items[0];
 
-  // fprintf (stderr, "gr_iir_filter_ffd::work noutput_items = %d\n", noutput_items);
 
   if (d_updated){
     d_iir.set_taps (d_new_fftaps, d_new_fbtaps);
index 4e8c8ebcd5abd017e63b95b9e4de703f94fcbed4..8e98758ec170a1a4bf52bd5411a61bf5c6148452 100644 (file)
@@ -40,12 +40,11 @@ gr_make_iir_filter_ffd (const std::vector<double> &fftaps,
  * This filter uses the Direct Form I implementation, where
  * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones.
  *
- * \p fftaps and \p fbtaps must have equal numbers of taps
- *
+ * 
  * The input and output satisfy a difference equation of the form
 
  \f[
- y[n] - \sum_{k=1}^{N} a_k y[n-k] = \sum_{k=0}^{M} b_k x[n-k]
+ y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k]
  \f]
 
  * with the corresponding rational system function
index d52c95f02e21d963545a6ac82893d2b21c15b6da..587bd102f2ebd5ecb1a9120acc4c350ef4013e0f 100644 (file)
@@ -43,13 +43,13 @@ public:
    * The input and output satisfy a difference equation of the form
 
    \f[
-   y[n] - \sum_{k=1}^{N} a_k y[n-k] = \sum_{k=0}^{M} b_k x[n-k]
+   y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k]
    \f]
 
    * with the corresponding rational system function
 
    \f[
-   H(z) = \frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}}
+   H(z) = \frac{\sum_{k=0}^{N} b_k z^{-k}}{1 - \sum_{k=1}^{M} a_k z^{-k}}
    \f]
 
    * Note that some texts define the system function with a + in the denominator.
@@ -61,7 +61,7 @@ public:
     set_taps (fftaps, fbtaps);
   }
 
-  gri_iir () : d_latest(0) { }
+  gri_iir () : d_latest_n(0),d_latest_m(0) { }
 
   ~gri_iir () {}
 
@@ -80,7 +80,8 @@ public:
   /*!
    * \return number of taps in filter.
    */
-  unsigned ntaps () const { return d_fftaps.size (); }
+  unsigned ntaps_ff () const { return d_fftaps.size (); }
+  unsigned ntaps_fb () const { return d_fbtaps.size (); }
 
   /*!
    * \brief install new taps.
@@ -88,19 +89,22 @@ public:
   void set_taps (const std::vector<tap_type> &fftaps, 
                 const std::vector<tap_type> &fbtaps) throw (std::invalid_argument)
   { 
-    if (fftaps.size () != fbtaps.size ())
-      throw std::invalid_argument ("gri_iir::set_taps");
 
-    d_latest = 0;
+
+    d_latest_n = 0;
+    d_latest_m = 0;
     d_fftaps = fftaps; 
     d_fbtaps = fbtaps; 
 
     int n = fftaps.size ();
+    int m = fbtaps.size ();
     d_prev_input.resize (2 * n);
-    d_prev_output.resize (2 * n);
+    d_prev_output.resize (2 * m);
 
     for (int i = 0; i < 2 * n; i++){
       d_prev_input[i] = 0;
+     }
+    for (int i = 0; i < 2 * m; i++){
       d_prev_output[i] = 0;
     }
   }
@@ -108,7 +112,8 @@ public:
 protected:
   std::vector<tap_type>        d_fftaps;
   std::vector<tap_type>        d_fbtaps;
-  int                  d_latest;
+  int                  d_latest_n;
+  int                  d_latest_m;
   std::vector<tap_type>        d_prev_output;
   std::vector<i_type>  d_prev_input;
 };
@@ -123,29 +128,36 @@ gri_iir<i_type, o_type, tap_type>::filter (const i_type input)
 {
   tap_type     acc;
   unsigned     i = 0;
-  unsigned     n = ntaps ();
+  unsigned     n = ntaps_ff ();
+  unsigned      m = ntaps_fb ();
 
   if (n == 0)
     return (o_type) 0;
 
-  int latest = d_latest;
+  int latest_n = d_latest_n;
+  int latest_m = d_latest_m;
   
   acc = d_fftaps[0] * input;
   for (i = 1; i < n; i ++)
-    acc += (d_fftaps[i] * d_prev_input[latest + i]
-           + d_fbtaps[i] * d_prev_output[latest + i]);
+    acc += (d_fftaps[i] * d_prev_input[latest_n + i]);
+  for (i = 1; i < m; i ++)
+    acc += (d_fbtaps[i] * d_prev_output[latest_m + i]);
 
   // store the values twice to avoid having to handle wrap-around in the loop
-  d_prev_output[latest] = acc;
-  d_prev_output[latest+n] = acc;
-  d_prev_input[latest] = input;
-  d_prev_input[latest+n] = input;
-
-  latest--;
-  if (latest < 0)
-    latest += n;
-
-  d_latest = latest;
+  d_prev_output[latest_m] = acc;
+  d_prev_output[latest_m+m] = acc;
+  d_prev_input[latest_n] = input;
+  d_prev_input[latest_n+n] = input;
+
+  latest_n--;
+  latest_m--;
+  if (latest_n < 0)
+    latest_n += n;
+  if (latest_m < 0)
+    latest_m += m;
+
+  d_latest_m = latest_m;
+  d_latest_n = latest_n;
   return (o_type) acc;
 }
 
index 43f2aa2191ec0496b84c6195d73952cf21b166f2..426c73b58f8a05a3077bb8f348324ba5234d9d98 100755 (executable)
@@ -101,11 +101,6 @@ class test_iir (gr_unittest.TestCase):
         self.assertFloatTuplesAlmostEqual (expected_result, result_data)
 
     def test_iir_direct_006 (self):
-        fftaps = (2, 11,  0)
-        fbtaps = (0,  -1)
-        self.assertRaises ((RuntimeError, ValueError), gr.iir_filter_ffd, fftaps, fbtaps)
-
-    def test_iir_direct_007 (self):
         src_data = (1, 2, 3, 4, 5, 6, 7, 8)
         expected_result = (2, 13, 21, 59, 58, 186, 68, 583)
         fftaps = (2, 1)
@@ -122,13 +117,42 @@ class test_iir (gr_unittest.TestCase):
         result_data = dst.data ()
         self.assertFloatTuplesAlmostEqual (expected_result, result_data)
 
-    def test_iir_direct_008 (self):
+    def test_iir_direct_007 (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+        expected_result = (2,2,5,5,8,8,11,11)
         fftaps = (2, 1)
         fbtaps = (0, -1)
+        src = gr.vector_source_f (src_data)
         op = gr.iir_filter_ffd (fftaps, fbtaps)
-        fftaps = (2, 11)
-        fbtaps = (0,  -1, 3)
-        self.assertRaises ((RuntimeError, ValueError), op.set_taps, fftaps, fbtaps)
+        fftaps = (2,0,1)
+        fbtaps = (0, -1)
+        op.set_taps (fftaps, fbtaps)
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+        
+    def test_iir_direct_008 (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+        expected_result = (2,4,4,10,18,14,26,56)
+        fftaps = (2,)
+        fbtaps = (0, 1)
+        src = gr.vector_source_f (src_data)
+        op = gr.iir_filter_ffd (fftaps, fbtaps)
+        fftaps_data = (1)
+        fbtaps = (0,0, -1,3)
+        op.set_taps (fftaps, fbtaps)
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+        
+        
+
 
 if __name__ == '__main__':
     gr_unittest.main ()