The previous fractional shift code was still not handling properly the 
endpoints.
Herein an improvement.
Fourier is still used but the sample laying between end and start points is 
interpolated.

// START OF CODE
// Circular fractional shift (R.Guerra, rev1, 02-Jun-2018)

function v=cfshift(y, s)
    // y: 1D series values
    // s: shift, decimal number of samples
    // v: y series shifted by s samples
    N0 = length(y);
    y2 = [y y($:-1:1)]; // make input even and continuous
    N = length(y2);
    m = N/2;
    dw = -%i*2*%pi/N;
    ix1 = 1:m;
    ix = [0, ix1, -ix1(m-1:-1:1)];
    s = modulo(s,N0);
    lph = exp(ix*dw*s);
    v0 = real((ifft(fft(y2).*lph)));
    n0 = floor(s);
    xi = s - n0;
    yi = y(1) + xi*(y($)-y(1)); //interpolates sample between end and start
    if n0>=0 then
       v = [v0(N0+1:N0+n0) yi v0(n0+2:N0)];
    else
       v = [v0(1:N0+n0) yi v0(N+n0+2:N)];
    end
endfunction

clf
n = 30;  // number of input samples
x = 1:n;  // domain of the series, with unit sampling rate
sn = -33;  // ex.1: negative integer shift (modulo(sn,n) = -3)
sp = 10.5; // ex.2: positive fractional shift
y = cos(1.8*%pi*(x-10)/n); // input series, discontinuous at endpoints

vi = cfshift(y, sn);  
vf = cfshift(y, sp);

plot(x,y,'blacko',x,y,'black--',x,vi,'bo',x,vi,'b--',x,vf,'ro',x,vf,'r--');
xgrid
title("Original series (black), with circular integer shift = " + string(sn) + 
" (blue) and circular fractional shift = " + string(sp) +" (red)", 
"fontsize",4);
gca().data_bounds = [0.5,-1.1;n+0.5,1.1]
gca().tight_limits="on";

// END OF CODE

Regards,
Rafael
_______________________________________________
users mailing list
users@lists.scilab.org
http://lists.scilab.org/mailman/listinfo/users

Reply via email to