Scaling issues when using IFFT to convert frequency signal to time signal

10 visualizzazioni (ultimi 30 giorni)
I am trying to convert a frequency signal to a time signal using the inverse fast fourier transform. I need to ensure correct units and amplitude values in both domains.
I have a set of frequency values denoted by variable Aaf and a respective sets of phase angles denoted by variable Aazeta. I was using the following code to get my time signal using the IFFT function:
Aareal(1)=0;
Aaimag(1)=0;
for i=2:NT/2 % NT = number of points in time domain
j=i-2;
Aareal(i)=Aa*cos(Aszeta(i));
Aareal(NT-j)=Aa*cos(Aszeta(i));
Aaimag(i)=Aa*sin(Aszeta(i));
Aaimag(NT-j)=-1*Aa*sin(Aszeta(i));
end
at=ifft(complex(Aareal,Aaimag))*NT % at = time domain signal
From what I could gather from reading MANY MANY MANY matlab forums and looking at various websites, I needed to scale my IFFT result by the number of time domain data points (in this case NT) to get the answer. When I do this, using the above code, my time domain signal seems correct (i.e. the values, maximums, minimums etc. all seem ok). However when I (a) calculate the variance (i.e. energy content) of my frequency domain signal by summing up the spectral densities of the signal and then (b) calculate the variance (i.e. energy content) of my time domain signal I get different values. They're different by a factor of 4. I am using the following code:
% frequencyt doamin
variance=0;
for i=1:NT/2
variance=variance+(Aareal(i)^2+Aaimag(i)^2)/2;
end
% time domain
for i=1:NT
variance=variance+(1/NT)*(at(i)-mean(at))^2;
end
I thought the variance should be the same using both of these two approaches?
So I decided to write my own piece of code to do an inverse fourier transform (below). When I use this code to calculate my time domain signal, my variance (i.e. energy content) calculated in both the frequency domain and time domain are the same - as I expected. However using this approach my time domain signal does not seem correct (i.e. the values, maximums, minimum etc. all seem INCORRECT).
function X=FTinverse(a,b,zeta,N)
% This function performs a inverse fourier transform.
% frequency domain --> time domain
X=zeros(N,1);
for j=1:N
X(j)=a(1);
for i=2:N/2
X(j)=X(j)+sqrt(a(i)^2+b(i)^2)*cos(2*pi*(i-1)*(j-1)/N-zeta(i));
end
end
So, in summary, my question is why (a) when I use the first approach using the IFFT function and multiplying the answer by NT (number of points) I get the correct time domain answer, however my variance when calculated in the frequency domain and the time domain DO NOT equal each other (they are different by a factor of 4) and (b) when I use the second approach for doing the inverse fourier transform my time domain answer is incorrect, however my variance when calculated in the frequency domain and the time domain DO equal each other...

Risposte (1)

David Goodmanson
David Goodmanson il 18 Set 2016
It's commendable that you're verifying that the energies of the time and frequency arrays are equal. A lot of people wouldn't bother.
I believe your first method is basically correct, with a few changes.
[1] the sums need to include the entire array on each side, i.e. sum to N instead of N/2.
[2] you don't need the factor of 1/2 in the frequency domain calculation. This is because each frequency component represents exp(i*2pift) = cos(2pift) + i*sin(2pift) which squares out to an average value of 1, unlike cos(2pift) which squares out to an average value of 1/2.
[3] this calculation is more like energy than variance, so you should not subtract the mean of a(t) before you square the term. Mean(a(t)) = 0 in this case, but in general the mean (which is the zero-frequency term) contains energy. Do those changes and you should get agreement.
In case you want to do this in a more vectorized Matlab way ( which of course you do! ), you can do
at2 = at.^2;
Et = sum(at2)/NT % energy in time domain
where as you probably know the .^ tells Matlab to square each element of 'at' individually to make a new array of squared elements, at2. In practice this would become
Et = sum(at.^2)/NT
which is cleaner than a 'for' loop and runs faster. Similarly
Ef = sum(Aareal.^2 + Aaimag.^2) % energy in freq domain
You can do similar things in the top half of your program to get rid of 'for' loops altogether.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by