diff options
author | Doug Geiger <doug.geiger@bioradiation.net> | 2015-09-21 18:08:46 -0400 |
---|---|---|
committer | Doug Geiger <doug.geiger@bioradiation.net> | 2015-09-21 18:08:46 -0400 |
commit | edd7be6ce3de8e13100d0d27ead108ad4a42b950 (patch) | |
tree | 2afe1d1f567192174d160af359d7620bc1bb09c1 /gr-fft | |
parent | a03893d51553eb74ac348ee88d4dd879b0a253c8 (diff) |
Fix the VOLKized fft_vcc_fftw and QA code
The QA code did not cover all the cases being VOLKized, and thus failed to notice the incorrect pointer math.
This QA code (correctly!) fails on the previous commit, and (correctly!) passes with this fix to fft_vcc_fftw.cc.
Thanks to awalls-cx18 for noticing this, and providing the correct array indexing call to VOLK.
Fixes issue #844
Diffstat (limited to 'gr-fft')
-rw-r--r-- | gr-fft/lib/fft_vcc_fftw.cc | 4 | ||||
-rwxr-xr-x | gr-fft/python/fft/qa_fft.py | 64 |
2 files changed, 62 insertions, 6 deletions
diff --git a/gr-fft/lib/fft_vcc_fftw.cc b/gr-fft/lib/fft_vcc_fftw.cc index 37c0d28736..3b23058df5 100644 --- a/gr-fft/lib/fft_vcc_fftw.cc +++ b/gr-fft/lib/fft_vcc_fftw.cc @@ -103,8 +103,8 @@ namespace gr { if(!d_forward && d_shift) { unsigned int offset = (!d_forward && d_shift)?(d_fft_size/2):0; int fft_m_offset = d_fft_size - offset; - volk_32fc_32f_multiply_32fc(&dst[fft_m_offset], in, &d_window[0], offset); - volk_32fc_32f_multiply_32fc(&dst[0], in, &d_window[0], d_fft_size); + volk_32fc_32f_multiply_32fc(&dst[fft_m_offset], &in[0], &d_window[0], offset); + volk_32fc_32f_multiply_32fc(&dst[0], &in[offset], &d_window[offset], d_fft_size-offset); } else { volk_32fc_32f_multiply_32fc(&dst[0], in, &d_window[0], d_fft_size); diff --git a/gr-fft/python/fft/qa_fft.py b/gr-fft/python/fft/qa_fft.py index ec731fdf6a..db3ca7778d 100755 --- a/gr-fft/python/fft/qa_fft.py +++ b/gr-fft/python/fft/qa_fft.py @@ -21,6 +21,15 @@ from gnuradio import gr, gr_unittest, fft, blocks +# Note: Octave code to verify these results: +# primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, +# 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311] +# src_data = primes(1:2:end) + primes(2:2:end)*i +# forward = fft(src_data(:)) +# reverse = ifft(forward(:)) +# windowed = fft(src_data(:).*hamming(32)) +# reverse_window_shift = ifft(fftshift(forward.*hamming(32))) + primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, @@ -73,7 +82,7 @@ class test_fft(gr_unittest.TestCase): self.assertComplexTuplesAlmostEqual2(expected_result, result_data, abs_eps=1e-9, rel_eps=4e-4) - def test_001(self): + def test_forward(self): src_data = tuple([complex(primes[2 * i], primes[2 * i + 1]) for i in range(self.fft_size)]) expected_result = primes_transformed @@ -87,7 +96,7 @@ class test_fft(gr_unittest.TestCase): result_data = dst.data() self.assert_fft_ok2(expected_result, result_data) - def test_002(self): + def test_reverse(self): src_data = tuple([x / self.fft_size for x in primes_transformed]) expected_result = tuple([complex(primes[2 * i], primes[2 * i + 1]) for i in range(self.fft_size)]) @@ -101,7 +110,7 @@ class test_fft(gr_unittest.TestCase): result_data = dst.data() self.assert_fft_ok2(expected_result, result_data) - def test_003(self): + def test_multithreaded(self): # Same test as above, only use 2 threads src_data = tuple([x / self.fft_size for x in primes_transformed]) expected_result = tuple([complex(primes[2 * i], primes[2 * i + 1]) for i in range(self.fft_size)]) @@ -117,7 +126,7 @@ class test_fft(gr_unittest.TestCase): result_data = dst.data() self.assert_fft_ok2(expected_result, result_data) - def test_windows(self): + def test_window(self): src_data = tuple([complex(primes[2 * i], primes[2 * i + 1]) for i in range(self.fft_size)]) expected_result = ((2238.9174 + 2310.4750j), (-1603.7416 - 466.7420j), @@ -163,5 +172,52 @@ class test_fft(gr_unittest.TestCase): result_data = dst.data() self.assert_fft_ok2(expected_result, result_data) + def test_reverse_window_shift(self): + src_data = tuple([x / self.fft_size for x in primes_transformed]) + expected_result = ((-74.8629 - 63.2502j), + (-3.5446 - 2.0365j), + (2.9231 + 1.6827j), + (-2.7852 - 0.8613j), + (2.4763 + 2.7881j), + (-2.7457 - 3.2602j), + (4.7748 + 2.4145j), + (-2.8807 - 4.5313j), + (5.9949 + 4.1976j), + (-6.1095 - 6.0681j), + (5.2248 + 5.7743j), + (-6.0436 - 6.3773j), + (9.7184 + 9.2482j), + (-8.2791 - 8.6507j), + (6.3273 + 6.1560j), + (-12.2841 - 12.4692j), + (10.5816 + 10.0241j), + (-13.0312 - 11.9451j), + (12.2983 + 13.3644j), + (-13.0372 - 14.0795j), + (14.4682 + 13.3079j), + (-16.7673 - 16.7287j), + (14.3946 + 11.5916j), + (-16.8368 - 21.3156j), + (20.4528 + 16.8499j), + (-18.4075 - 18.2446j), + (17.7507 + 19.2109j), + (-21.5207 - 20.7159j), + (22.2183 + 19.8012j), + (-22.2144 - 20.0343j), + (17.0359 + 17.6910j), + (-91.8955 - 103.1093j)) + window = fft.window_hamming(ntaps=self.fft_size) + + src = blocks.vector_source_c(src_data) + s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) + op = fft.fft_vcc(self.fft_size, False, window, True) + v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, self.fft_size) + dst = blocks.vector_sink_c() + self.tb.connect(src, s2v, op, v2s, dst) + self.tb.run() + result_data = dst.data() + self.assert_fft_ok2(expected_result, result_data) + + if __name__ == '__main__': gr_unittest.run(test_fft, "test_fft.xml") |