MATLAB: Incorrect phase from fourier transform

digital signal processingfftsignal

  • I make a few sinusoids of different frequencies with different phase offsets.
  • Add them to make a waveform
  • Fast Fourier Transform.
  • Then get the phase from the complex number given by the FFT – but it doesn't always match the phase that it originally had…why?
  • Code below with a plot – Its annotated well and outputs the phases
clear all
freq_range = (3:5)
Fs =10*max(freq_range);
Ts = 1/Fs;
end_time = 5;
n = 0 : Ts : end_time-Ts;
%Make the number of waves in the frequency range
for a = 1:length(freq_range)
random_phase(a) = 2*pi*rand(1,1);
y(a,:) = cos(2*pi .* freq_range(a) .* n + random_phase(a)) ; %Polar form
%Sum all the waves together to make a waveform
waveform = sum(y);
%Setup Fast Fourier Transform
freq_domain = (0:N/2); %Show positive frequency only
freq_domain = freq_domain * Fs / N;
%Fast Fourier Transform
ft = fft(waveform)/N;
ft_spectrum = 2*abs(ft); %2* to compensate for negative frequency
ft_spectrum = ft_spectrum(1:N/2+1); %Show positive Frequency Only
ft_phase = angle(ft(1:N/2+1));
%Get Phase
Bins_per_freq= (N/Fs);
freq_bins = Bins_per_freq * (freq_range) +1; %Domain starts at 0, so add 1
random_phase %The phase offset the cosine waves orignally had
phase = angle(ft(freq_bins)) %The Phase from the fft
%They do not match... but sometimes they do... why?
subplot(3,1,1);plot(n,waveform);title('Time Domain Signal');
subplot(3,1,2);plot(freq_domain,ft_spectrum);title('Frequency Domain');
subplot(3,1,3);plot(freq_domain,ft_phase);title('Phase on Frequency Domain');

Best Answer

Hi Nathan,
If you check you will see that the difference between random_phase and phase is always either 0 or 2pi. This is because random_phase is constructed so that 0 <= random_phase <= 2*pi, whereas the output of the angle function has -pi < angle <= pi. When random_phase is between 0 and pi things agree, and when random_phase is between pi and 2pi then there is a difference of 2pi between that and the angle function.
If you define random_phase such that -pi <= random_phase <= pi, you'll always get agreement.