from DFT relation for cosine function we have
DFT( cos(2*pifin) )=.5*( delta(f-fi)+delta(f+fi) )
as we can see the phase of the DFT is zero. However, when I use FFT in matlab, fft coefficients are complex which means the phase of the DFT is not zero. please help me to solve this contradiction.
The phase of an FFT result only corresponds exactly to the phase of the input cosines if the period of the input cosines are exact integer submultiples of the FFT length.
Another source of complex FFT results is rounding error. You can usually ignore values that are comparatively tiny (10e-13, etc.) relative to the average magnitudes, and the phase of two tiny rounding errors is indeterminate (same as the phase of a complex zero). Perhaps just assume zero.
When computing the DTFT of a cosine function, the phase is zero due to its symmetry. However, when using the FFT, the obtained phase is not zero because the FFT treat the sequence from 0 to L-1, that is, there is a shift, which turns to phase shift in the frequency domain. Nevertheless, the non-zero phase is linear.
You can compute the DTFT of two rectangular sequences, the one is symmetric and the other is from 0 to L-1.
Related
I try to do an extrapolation with the FFT method thanks to this code: https://gist.github.com/tartakynov/83f3cd8f44208a1856ce
and i would like to knw how can i select only the highest frequencies of the data serie because this code don't give me good result.
The basis vectors of an FFT are all circularly periodic, thus poorly model any edge transients or circular discontinuities between the beginning and end of a rectangular window which is the same length as the FFT (unless the full data set is purely integer periodic in FFT length, extremely unlikely for real financial data sets).
You could try windowing your data (with a non-rectangular window, such as a Von Hann, Tukey or Planck-taper window), possibly in conjunction with using a longer zero-padded FFT.
Another possibility is to use polynomial regression (perhaps somewhat underfit) on some portion of your data to generate an estimator, extend that polynomial into the region into which you wish to extrapolate, and then take the (windowed) FFT of that polynomial range instead of your original time series.
Can QR algorithm find repeat eigenvalues (https://en.wikipedia.org/wiki/QR_algorithm) ? I.e. Does it support the case when not all N eigen value for real matrix N x N are distinct?
How extend QR algorithm to support finding complex eigenvalues?
In principle yes. It will work if the eigenvalues are really all eigenvalues, i.e., the algebraic and geometric multiplicity are the same.
If the multiple eigenvalue occurs in an Jordan-block of size s, then the unavoidable floating point error during the iteration will almost surely result in a star-shaped perturbation into an eigenvalue cluster with relative error of size mu^(1/s) where mu is the machine constant of the floating point data type.
The reason this happens is that on the irreducible invariant subspace corresponding to a Jordan block of size s the characteristic polynomial of the reduction of the linear operator to this subspace has is (λ-λ[j])^s. During the computation this gets perturbed to (λ-λ[j])^s+μq(λ) which in first approximation has roots close to λ[j]+μ^(1/s)*z[k], where z[k] denotes the s roots of 0=z^s+q(λ[k]). What the perturbation function q is is quite random, accumulated floating point truncation errors, and depends on details of the method.
I get how the DFT via correlation works, and use that as a basis for understanding the results of the FFT. If I have a discrete signal that was sampled at 44.1kHz, then that means if I were to take 1s of data, I would have 44,100 samples. In order to run the FFT on that, I would have to have an array of 44,100 and a DFT with N=44,100 in order to get the resolution necessary to detect a frequencies up to 22kHz, right? (Because the FFT can only correlate the input with sinusoidal components up to a frequency of N/2)
That's obviously a lot of data points and calculation time, and I have read that this is where the Short-time FT (STFT) comes in. If I then take the first 1024 samples (~23ms) and run the FFT on that, then take an overlapping 1024 samples, I can get the continuous frequency domain of the signal every 23ms. Then how do I interpret the output? If the output of the FFT on static data is N/2 data points with fs/(N/2) bandwidth, what is the bandwidth of the STFT's frequency output?
Here's an example that I ran in Mathematica:
100Hz sine wave at 44.1kHz sample rate:
Then I run the FFT on only the first 1024 points:
The frequency of interest is then at data point 3, which should somehow correspond to 100Hz. I think 44100/1024 = 43 is something like a scaling factor, which means that a signal with 1Hz in this little window will then correspond to a signal of 43Hz in the full data array. However, this would give me an output of 43Hz*3 = 129Hz. Is my logic correct but not my implementation?
As I have already stated in my earlier comments, the variable N affects the resolution achievable by the output frequency spectrum and not the range of frequencies you can detect.A larger N gives you a higher resolution at the expense of higher computation time and a lower N gives you lower computation time but can cause spectral leakage, which is the effect you have seen in your last figure.
As for your other question, well, theoretically the bandwidth of an FFT is infinite but we band-limit our result to the band of frequencies in the range [-fs/2 to fs/2] because all frequencies outside that band are susceptible to aliasing and are therefore of no use.Furthermore, if the input signal is real (which is true in most cases including ours) then the frequencies from [-fs/2 to 0] are just a reflection of the frequencies from [0 to fs/2] and so some FFT procedures just output the FFT spectrum from [0 to fs/2], which I think applies to your case.This means that the N/2 data points that you received as output represent the frequencies in the range [0 to fs/2] so that is the bandwidth you are working with in the case of the FFT and also in the case of the STFT (the STFT is just a series of FFT's, each FFT in a STFT will give you a spectrum with data points in this band).
I would also like to point out that the STFT will most likely not reduce your computation time if your input is a varying signal such as music because in that case you will need to take perform it several times over the duration of the song for it to be of any use, it will however enable you to understand the frequency characteristics of your song much better that you would do if you just performed one FFT.
To visualise the results of an FFT you use frequency (and/or phase) spectrum plots but in order to visualise the results of an STFT you will most probably need to create a spectrogram which is basically a graph can is made by just basically putting the individual FFT spectrums side by side.The process of creating a spectrogram can be seen in the figure below (Source: Dan Ellis - Introduction to Speech Processing).The spectrogram will show you how your signal's frequency characteristics change over time and how you interpret it will depend on what specific features you are looking to extract/detect from the audio.You might want to look at the spectrogram wikipedia page for more information.
I have a simple sine function as sin(2*pift+phi). I want to obtain the phase signal phi.
I tried to use FFT to calculate phi. In matlab I do the following
f=200; %frequency of sine wave
overSampRate=30; %oversampling rate
fs=overSampRate*f; %sampling frequency
phase = 3/5*pi; %desired phase shift in radians
nCyl = 5; %to generate five cycles of sine wave
t=0:1/fs:nCyl*1/f; %time base
x=sin(2*pi*f*t+phase); %replace with cos if a cosine wave is desired
NFFT=1024; %NFFT-point DFT
X=fft(x,NFFT); %compute DFT using FFT
XX=2*abs(X(1:NFFT/2+1));
[tt ind]=max(XX);
phase_Estimate=angle(X(ind);
This result makes almost no sense to me. For example, when phi=0.523, phase_Estimate is obtained -0.98.
Using an non-interpolated FFT result phase only works if the period of sinusoid is exactly an integer submultiple of the FFT length. In your example, the sine wave isn't integer periodic in aperture.
If not, you will need to interpolate the phase to get a better estimate. Here's one method to get an better interpolated phase:
First fftshift (rotate by N/2) the data to move the zero phase reference point to the center of the window before doing the FFT. (This is needed to keep the phase from flipping/alternating between adjacent FFT result bins. * )
Then do the FFT and estimate the frequency of the sinusoid by parabolic or, better yet, Sinc interpolation.
Then use the estimated frequency to linearly interpolate the phase between the nearest two FFT result bin phases. Update: Or better yet, use Sinc interpolation of the real and imaginary components of the FFT result separately, then use atan2 on the interpolated IQ components to get an interpolated phase.
Then use the estimated frequency and phase at the center of the window to calculate the phase at some other point, such as the beginning of the FFT window.
Also note that the phase of a sine is different from the phase of a cosine wave by pi/2. atan(im,re) returns the cosine phase.
(* as an alternative to pre-fftshit-ing the data, one could also post-flip the phase of the odd FFT result bins.)
This is actually much more difficult question to answer than it first seems.
The answer #hotpaw2 gives is completely correct and spells it out way better than any other resource I found, but it is still only an outline and it took me a few hours to put all the meat to it's bones.
In the hopes that someone else will also find the question relevant (and for future reference for myself), here is a bit more thorough explanation:
Suppose you have a (local) maximum at index ind (as in the case of question).
Step 1: try to interpolate the more precise location of the maximum by using the two surrounding values. This is well explained in many, many places such as https://www.dsprelated.com/freebooks/sasp/Quadratic_Interpolation_Spectral_Peaks.html has a good explanation for how to do that, but TL:DR version is:
delta = 0.5*(X[ind-1]-X[ind+1])/(X[ind-1]-2*X[ind]+X[ind+1])
p0 = ind+delta
with the estimated peak at p0
(If you want a more precise estimate, use log(X[ind-1]) instead, or go full out and use sinc function, but for most purposes, the delta above is sufficient)
Step 2: the tricky part: use that location to interpolate the phase.
The first instinct is to do simple linear interpolation using the delta we just found:
i0 = floor(p0); w = p0-i0; wp = 1-w
ang = wp*angle(X[i0]) + w*angle(X[i0+1])
This WILL NOT WORK for multiple reasons, most of which were outlined by #hotpaw2. The first of them is that this is not how you average angles, as they wrap modulo 2pi so 0 and 2pi should be similar. The more correct approach is to average the normalized complex numbers instead:
ang = angle(wp*X[i0]/abs(X[i0]) + w*X[i0+1]/abs(X[i0+1]))
However, this is still not correct, because if a peak is between i0 and i0+1, the phase flips 180 degrees (pi radians) there, making the average very misleading. To fix this "phase flip", you either have to (a) perform fftshift before fft (yes, in time-domain) or (b) flip the phase of every odd-indexed value of X (achieved by multiplying the complex number with -1) or (in case you are reluctant to touch the FFT as I was), you can also just (c) mock the approach (b) with the following code:
i0 = floor(p0); w = p0-i0; wp = 1-w
if (i0 % 2 == 1) { w*=-1; wp*=-1 } # Flip both if i0 odd
ang = angle(wp*X[i0]/abs(X[i0]) - w*X[i0+1]/abs(X[i0+1])) # Note the "-" here!
This will give you a (mostly) correct phase, but for a cosine and at the center of fft window.
Step 3 (Optional): If you need the phase for sine and from the beginning of the window, you need to add a correction factor:
ang_beg = ang - (2*pi*p0/N)*N/2 + pi*0.5 = ang - pi*(p0 - 0.5)
(0.5*pi converts cos to sin, and -p0*pi translates to beginning of window).
This seemed to work, at least in the Phase Vocoder I needed it in. Hopefully someone else will also find this useful.
As an aside, the phase interpolation is not needed for a pure sine wave, as angle(X[i0]) = angle(-X[i0+1]) so you can just use it directly. With actual signals, there is likely to be some deviation so interpolation adds some robustness which is usually a good idea, although using w and wp and normalizing is likely overkill and angle(sgn*(X[i0]-X[i0+1)) is usually enough.
Any comments to all this are very welcome. I am not a DSP specialist, so I may well be wrong in some details, bu this does seem to work, so hopefully someone else will also find it useful.
You're trying to get the phase from the power spectrum (XX) when you should be getting it from the FFT (X). Change:
phase_Estimate=angle(XX(ind));
to:
phase_Estimate=angle(X(ind));
It maybe late, but I changed Your script a little
f=200; %frequency of sine wave
overSampRate=30; %oversampling rate
fs=overSampRate*f; %sampling frequency
shift = 30
phase = shift*pi/180; %desired phase shift in radians
nCyl = 5; %to generate five cycles of sine wave
t=0:1/fs:nCyl*1/f; %time base
x=cos(2*pi*f*t+phase); %replace with cos if a cosine wave is desired
NFFT=4096; %NFFT-point DFT
X=fft(x,NFFT); %compute DFT using FFT
XX=2*abs(X(1:NFFT/2+1));
[tt, ind]=max(XX);
phase_Estimate = angle(X(ind)) * 360/(2*pi)
It spits out quite close results to what I would expect.
I changed the x vector generation to cosine, calculated degrees in phase_Estimate instead of radians, and made it easy to change input phase shift.
I'm just getting into signal processing and need to do some DFT/FFT work.
If I take a signal with two freqs of 2Hz and 5Hz: x(t)=sin(2*2pi*t)+sin(5*2pi*t). I sample at 100Hz for 5 sec (so my DFT size is 500).
Because my inputs are real values I get a symmetric DFT, so can discard the 2nd half and convert the DFT values into magnitude by doing sqrt(re^2+c^2).
My bin widths are 100/500 = 0.2Hz, and so I get:
With peaks at 2Hz and 5Hz as expected.
My question is: why are the magnitudes different?
On a related note, why are there not two perfect spikes at 2hz and 5Hz, i.ee the graph has non-zero values at 1.5 and 2.5 etc. Is this spectral leakage?
I expect your 500 data points are being processed as a 512 point FFT (most FFT libraries do not support arbitrary size inputs and so typically they zero pad to the next highest power of 2). If that is the case then you will be seeing the effects of spectral leakage. Applying a window function prior to the FFT should fix this. Note that you will still see "skirts" on either side of your peaks - this is due to the uncertainty introduced by a finite sampling window.