shift the elements of a vector by non-integer shif

2019-07-18 04:24发布

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?

2条回答
等我变得足够好
2楼-- · 2019-07-18 04:35

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.

查看更多
叛逆
3楼-- · 2019-07-18 04:57

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.

查看更多
登录 后发表回答