26

The shift theorem says:

Multiplying $x_n$ by a linear phase $e^{\frac{2\pi i}{N}n m}$ for some integer m corresponds to a circular shift of the output $X_k$: $X_k$ is replaced by $X_{k-m}$, where the subscript is interpreted modulo N (i.e., periodically).

Ok, that works fine:

plot a

arbitrary 9-sample signal

N = 9
k = [0, 1, 2, 3, 4, 5, 6, 7, 8]
plot ifft(fft(a)*exp(-1j*2*pi*3*k/N))

signal shifted by 3 samples in the frequency domain

It shifted by 3 samples, as I expected.

I thought you could also do this to shift by fractions of a sample, but when I try it, my signal becomes imaginary and not at all like the original:

plot real(ifft(fft(a)*exp(-1j*2*pi*3.5*k/N)))
plot imag(ifft(fft(a)*exp(-1j*2*pi*3.5*k/N))), 'b--'

signal after multiplying by 3.5 complex exponential

I didn't expect this at all. Isn't this equivalent to convolving with a real impulse that's been shifted by 3.5 samples? So the impulse should still be real, and the result should still be real? And it should have more or less the same shape as the original, but sinc interpolated?

endolith
  • 15,759
  • 8
  • 67
  • 118
  • Here's a Matlab File Exchange submission that calculates the correct modulation for even/odd-length real/complex signals and fractional-delays them: http://www.mathworks.com/matlabcentral/fileexchange/7886-fshift – Ahmed Fasih Aug 06 '15 at 15:34

1 Answers1

16

If you want the shifted output of the IFFT to be real, the phase twist/rotation in the frequency domain has to be conjugate symmetric, as well as the data. This can be accomplished by adding an appropriate offset to your complex exp()'s exponent, for the given phase slope, so that the phase of the upper (or negative) half, modulo 2 Pi, mirrors the lower half in the FFT aperture. The complex exponential shift function can also be made conjugate symmetric by indexing it from -N/2 to N/2 with a phase of zero at index 0.

It just so happens that the appropriate offset for phase twists or spirals, that complete an exact integer multiples of 2 Pi rotations in aperture, to be conjugate symmetric in aperture, is zero.

With a conjugate symmetric phase twist vector, the result should then end up as a circular Sinc interpolation for non-integer shifts.

Elaboration by OP:

Your choice of k = [0, 1, 2, 3, 4, 5, 6, 7, 8] is producing an asymmetrical complex exponential:

asymmetrical complex exponential 0.5 sample shift attempt, with imaginary part as dashed line

If you use k = [0, 1, 2, 3, 4, -4, -3, -2, -1] instead, you get a Hermite-symmetric complex exponential:

plot(fftshift(exp(-1j * 2*pi * 0.5/N * k)))

Hermite-symmetric complex exponential for 0.5 sample shift, with imaginary part as dashed line

and now when you use the same exponential formula to shift by 0.5 or 3.5 samples, you get a real result:

plot ifft(fft(a)*exp(-1j * 2 * pi * 0.5/N *k))
plot ifft(fft(a)*exp(-1j * 2 * pi * 3.5/N *k))

shift by 0.5 and 3.5 samples, with original as dotted line

hotpaw2
  • 35,346
  • 9
  • 47
  • 90
  • Aha! Instead of k = [0, 1, 2, 3, 4], I should be using k = [0, 1, 2, -2, -1] – endolith Aug 09 '13 at 13:33
  • @endolith / hotpaw2, In other words it is all about the indexing of the time-domain samples? – TheGrapeBeyond Aug 09 '13 at 14:58
  • @TheGrapeBeyond: In this case, they are frequency domain samples of a complex exponential, in order to get a time domain shift, but you can swap the time and frequency domains and do the opposite as well. I was originally creating the complex exponential using the wrong frequency vector, basically. – endolith Aug 09 '13 at 17:10
  • What happens if the signal is even length, instead of odd, so can't be symmetric about a "center"? – Ahmed Fasih Aug 05 '15 at 19:40
  • 1
    Symmetry around bin 0 will also provide symmetry around N/2, even if N/2 isn't an integer. – hotpaw2 Aug 05 '15 at 20:19
  • Thanks for responding after all these years! I'm glad to hear that even N isn't a problem. But while k = [0, 1, 2, 3, 4, -4, -3, -2, -1] works for 9 samples, what would be k for 8 samples? Neither [0:3 -4:-1] nor [0:4 -3:-1] give real outputs when used as above. That is, ifft(exp(-2j * pi * 0.5 * k / 8)) is complex for both those alternative k. – Ahmed Fasih Aug 06 '15 at 01:37
  • 2
    I found a function that applies the correct modulation on Matlab File Exchange: http://www.mathworks.com/matlabcentral/fileexchange/7886-fshift ! – Ahmed Fasih Aug 06 '15 at 15:39
  • 1
    does this equally hold for complex signals? – Leo Aug 24 '17 at 14:30
  • I didn't quite understand it, yet: so that the phase of the upper (or negative) half, modulo 2 Pi, mirrors the lower half in the FFT aperture. – Eduardo Reis Sep 08 '20 at 22:00
  • So, Are there 3 ways to get this shift to work? 1-phase twist/rotation in the frequency domain has to be conjugate symmetric, as well as the data. 2-adding an appropriate offset to your complex exp()'s exponent, for the given phase slope, so that the phase of the upper (or negative) half, modulo 2 Pi, mirrors the lower half in the FFT aperture. 3-The complex exponential shift function can also be made conjugate symmetric by indexing it from -N/2 to N/2 with a phase of zero at index 0.. – Eduardo Reis Sep 08 '20 at 22:02