Mercurial > hg > octave-lyh
changeset 17181:3a23cbde59d5
interpft.m: Fix interpolation to preserve spectral symmetry (bug #39566)
* interpft.m: Fix interpolation to preserve spectral symmetry, be compatible
with Matlab. Add test cases.
author | Mike Miller <mtmiller@ieee.org> |
---|---|
date | Sun, 04 Aug 2013 17:27:40 -0400 |
parents | 1d5c0c9b3e99 |
children | c3c1ebfaa7dc |
files | scripts/general/interpft.m |
diffstat | 1 files changed, 25 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/general/interpft.m +++ b/scripts/general/interpft.m @@ -70,7 +70,7 @@ inc = ceil (m/n); y = fft (x) / m; - k = floor (m / 2); + k = ceil (m / 2); sz = size (x); sz(1) = n * inc - m; @@ -79,6 +79,18 @@ z = cat (1, y(idx{:}), zeros (sz)); idx{1} = k+1:m; z = cat (1, z, y(idx{:})); + + ## When m is an even number of rows, the FFT has a single Nyquist bin. + ## If zero-padded above, distribute the value of the Nyquist bin evenly + ## between the new corresponding positive and negative frequency bins. + if (sz(1) > 0 && k == m/2) + idx{1} = n * inc - k + 1; + tmp = z(idx{:}) / 2; + z(idx{:}) = tmp; + idx{1} = k + 1; + z(idx{:}) = tmp; + endif + z = n * ifft (z); if (inc != 1) @@ -108,6 +120,18 @@ %!assert (interpft (y', n), y', 20*eps); %!assert (interpft ([y,y],n), [y,y], 20*eps); +%% Test case with complex input from bug #39566 +%!test +%! x = (1 + j) * [1:4]'; +%! y = ifft ([15 + 15*j; -6; -1.5 - 1.5*j; 0; -1.5 - 1.5*j; -6*j]); +%! assert (interpft (x, 6), y, 10*eps); + +%% Test for correct spectral symmetry with even/odd lengths +%!assert (max (abs (imag (interpft ([1:8], 20)))), 0, 2*eps); +%!assert (max (abs (imag (interpft ([1:8], 21)))), 0, 2*eps); +%!assert (max (abs (imag (interpft ([1:9], 20)))), 0, 2*eps); +%!assert (max (abs (imag (interpft ([1:9], 21)))), 0, 2*eps); + %% Test input validation %!error interpft () %!error interpft (1)