0
$\begingroup$

I know how to change the phase of a complex number by multiplying by $\cos \theta + i \sin \theta$. And I understand that the phase of a sine wave is reflected in its Fourier transform. So, I am trying to phase-shift a signal by changing the phase of its Fourier transform..

This works for "synthetic" Fourier transforms, but when I try to FFT a signal, apply the phase change, and invert the FFT, I don't get the expected result. I am using MATLAB in the examples below.

Fs = 1000;
Tmax = 2;
L = Tmax * Fs;

For example, I'll build a synthetic Fourier sequence. The frequency intervals are 0.5 Hz, so a 10Hz component is at the 20th position after DC. (I'm just spitballing here; I know there's better ways to pick frequency bins than hand-jamming 21.)

Ysynth = zeros(1, L);
Ysynth(21) = 1000;

And rotate it by 45°:

Ysynth = Ysynth * exp(j * pi/4);

It has a 45° phase on the 10-Hz component:

polarscatter(angle(Ysynth), abs(Ysynth))

1

Now take its inverse FFT:

Xsynth = ifft(Ysynth);

So far so good. The generated signal has a phase shift of 45°. MATLAB does complain about the presence of an imaginary part when I plot it; I think this is because I didn't bother with the negative frequency component.

t = (0:L-1)/Fs;
plot(t, Xsynth)

2

Now, I would expect the same principle to apply to a frequency spectrum taken from an actual signal. But I do not get similar results. Quickly:

X = cos(2*pi * 10 * t);
Y = fft(X);
Yshift = Y * exp(j * pi/4);
Xshift = ifft(Yshift);

There is an imaginary component in Xshift, which I do not expect, and again MATLAB complains about.

plot(t, [Xshift; X])

3

There is no phase shift here, and the amplitude (of the real part) is different.

I must be misunderstanding something about phase representation in FFTs. Why doesn't my transformation produce a phase-shifted version of the original?

$\endgroup$
  • $\begingroup$ I think the problem is that you're shifting both positive and negative frequencies by the same amount. $\endgroup$ – MBaz Feb 8 '18 at 17:32
  • $\begingroup$ first check your FFT's sanity: do nothing in frequency domain, just IFFT. Notice that what you're doing (multiplication with a scalar) makes no difference whether you do it in time or frequency domain. $\endgroup$ – Marcus Müller Feb 8 '18 at 17:36
  • $\begingroup$ @mbaz oh, that's a good point. Is the overall approach valid? If so, should I multiply the negative frequencies by the negative, or the conjugate, of the positive freqs' multiplier? $\endgroup$ – thirtythreeforty Feb 8 '18 at 17:49
2
$\begingroup$

If you want a phase-shifted strictly-real result, then you have to make sure the data you feed to the IFFT is conjugate symmetric. So make sure to reflect the complex conjugate of any phase changes you make. e.g. Make the upper or negative half of your IFFT input vector mirror the complex conjugate of the bottom or positive half of the input vector.

Added: (Also, "mirror" usually means the array index goes in the opposite direction.)

$\endgroup$
  • $\begingroup$ Does that mean if I have some shift multiplier for the frequency bins that I have not yet reflected, then I should essentially do shift(end/2:end) = conj(shift(end/2:end))? $\endgroup$ – thirtythreeforty Feb 8 '18 at 22:40
1
$\begingroup$

The negative frequency component is why you are getting messed up. You need to phase shift it in the opposite direction in order for it to remain the complex conjugate in the DFT. This technique will only work on whole integer frequency real valued pure tones.

It will work on any pure complex tone. This is because the formula for a bin value of a complex tone has the phase term $ e^{i \phi} $ completely factored out. In other words, when you phase shift a pure complex tone, all the DFT bins rotate in parallel. This does not happen with a real valued signal.

See my articles DFT Bin Value Formulas for Pure Complex Tones and DFT Bin Value Formulas for Pure Real Tones to compare how a complex pure tone behaves in a DFT compared to a real valued one. For a frequency shift, that is a change in $\phi$, in the complex case it will factor out cleanly which is not true in the real case.

Hope this helps,

Ced

$\endgroup$
  • $\begingroup$ Thanks, that does help. Why does it only work for integer frequencies? I was under the impression that frequencies that don't have a precise bin appear in the nearest components. And for a sufficiently fine-grained FFT, that problem is minimized. $\endgroup$ – thirtythreeforty Feb 8 '18 at 18:08
  • $\begingroup$ @thirtythreeforty, That isn't correct. If there is any leakage, it goes all the way around the DFT. The nearby bins have larger magnitudes. For an integer frequency tone, a phase shift results in a DFT bin value rotation. For non-integer frequency, the rotation will be close to the phase shift, but not match it at the peak bin. The amount of rotation will taper off until there is none at the DC and Nyquist bins. A phase shift does not result in a parallel rotation of all the bins, so the parallel rotation of all the bins will not produce a phase shift. $\endgroup$ – Cedron Dawg Feb 8 '18 at 18:47
  • $\begingroup$ Gotcha. That is a rather frustrating property, especially given that it works for complex tones. I will have to find another approach. Thanks! $\endgroup$ – thirtythreeforty Feb 8 '18 at 18:59
0
$\begingroup$

A very readable reference related to this topic in the context of how to delay a signal less than a sample point

Laakso, Timo I., et al. "Splitting the unit delay [FIR/all pass filters design]." IEEE Signal Processing Magazine 13.1 (1996): 30-60.

You can get a good idea for cases beyond what is covered in the paper, in terms of symmetry and how to implement filters in both time and frequency domains. Signal Processing Magazine is mostly accessible to a majority of dsp engineers.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.