shift the elements of a vector by non-integer shift in matlab

你。 提交于 2019-12-24 04:44:09

问题


I want to shift a vector by non-integer shift, linear interpolation seems to be not very accurate so I'm trying to use sinc interpolation by the following code which uses Fourier transform.

function y = fshift(x,s)
% FSHIFT Fractional circular shift
%   Syntax:
%
%       >> y = fshift(x,s)
%
%   FSHIFT circularly shifts the elements of vector x by a (possibly
%   non-integer) number of elements s. FSHIFT works by applying a linear
%   phase in the spectrum domain and is equivalent to CIRCSHIFT for integer
%   values of argument s (to machine precision).


needtr = 0; if size(x,1) == 1; x = x(:); needtr = 1; end;
N = size(x,1); 
r = floor(N/2)+1; f = ((1:N)-r)/(N/2); 
p = exp(-j*s*pi*f)'; 
y = ifft(fft(x).*ifftshift(p)); if isreal(x); y = real(y); end;
if needtr; y = y.'; end;

there is no problem in the code when i shift a square wave by integer shift but when the shift is non-integer the output suffers from significant fluctuations i.e.,

s=[zeros(1,20) ones(1,20) zeros(1,20)];
b=fshift(s,3.5);
stem(b)

How to overcome this problem and is there any other accurate method?


回答1:


Try this:

Let's say you are shifting by 3.5. Figure out what the oversampling value is (i.e. what value will change the shift into an integer - in this case it is 2).

ov = 2;
a = 3.5*ov;
y = downsample(circshift(interp(s,2).', -a),ov);

This still has some ringing at the edges, but much less than your sinc approach. I'm not sure if this is due to the gibbs phenomenon since you are essentially truncating or leakage, as mentioned in a comment.




回答2:


You can do this with the fourier shift theorem as you do, but with added filtering. I asked a similar question here. The reason that the result looks 'wrong' is because your input vector is not continuous. The result you are getting really is 'correct' (or at least true).

The problem you are seeing is called Gibbs Ringing. You can make this less extreme by using a low pass filter (this wikipedia link explains the solution pretty well) that has no ringing in its step response. Try your code with and without a gaussian filter. This artefact is often seen in MRI imaging (and many other signal processing situations) and is sometimes alleviated by filtering.



来源:https://stackoverflow.com/questions/21830878/shift-the-elements-of-a-vector-by-non-integer-shift-in-matlab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!