MATLAB Code Clarification - matlab

I recently visited this page in order to determine the frequency from signal data in MATLAB:
Determine frequency from signal data in MATLAB
And in this page, an answerer responded with the following code:
[maxValue,indexMax] = max(abs(fft(signal-mean(signal))));
From what I can see, a Fast Fourier Transform is taken on a signal named signal, its magnitude is kept by using 'abs', and the max value is computed. The max value will be in maxValue, and the indexMax will contain the position of the maxValue. However, can someone explain what is meant by signal-mean, and what the purpose of it?

It basically normalize the vector signal so it has mean zero (subtracts the mean from signal). So signal - mean(signal) looks like signal except that is shifted on the y axis so it has a zero mean. Hope it is clear.
In the example you posted in the link, the mean of the signal is around -2, so by subtracting the mean you end up with a the signal shifted up around the y=0 axis.

As stated in vsoftco's answer, signal-mean(signal) subtracts the mean of the signal.
However, the key point is: why is this is done? If you don't subtract the mean, it's very likely that the maximum peak in the FFT appears at frequency 0 (DC component). But you don't want to detect that as the "frequency" of your signal, even if it truly is the highest spectral component. So you remove that zero-frequency component by subtracting the mean. That way, the max operation will detect the maximum non-zero frequency component, which is probably what you want.

Related

If we take STFT of a single sinusoid, and plot the value corresponding to carrier frequency in real imaginary plane, how many points should it be?

I created a sinusoid with frequency 550Hz that goes for 1 second
fs=44100;
Duration=1; %second
Len=Duration * fs; %length of sinusoid
t=(0:Len-1)/fs;
x=sin(2*pi*550*t);
for the purpose of exploring and learning, I have decided to take the short time Fourier transform of this signal. I did it as below:
window_len=0.02*fs; %length of the window
hop=window_len/3; %hop size
nfft=2^nextpow2(window_len);
window=hamming(window_len,'periodic');
[S,f,t]=spectrogram(x,window,hop,nfft,fs);
Now I want to plot the real versus imaginary value of S for the frequency equal to 550 and see what happens. First of all, in the frequency vector I didn’t have the exact 550. There was one 516.5 and 559.6. So, I just looked at the spectrogram and chose whichever that was close to it and picked that. When I tried to plot real vs imaginary of S for the frequency I chose (over all time frames), the values all fall in 3 points as it shows in the attached plot. Why three points?
Each STFT window can have a different complex phase depending on how the start (or middle) of the window is synchronized (or not) with the sinusoids period. So the real-complex IQ plot for the peak magnitude DFT result bin can be a circular scatter plot, depending on the number of DFT windows and the ratio between the stepping distance (or length - overlap) and the period of the sinusoid.
The phase of the STFT coefficients for the different windows depends on which data exactly the window "sees". So for your particular choice of window length and hop, it so happens that as you slide through your single-frequency sinusoid, there only three different data chunks that you window "sees". To see what I mean, just plot:
plot(x(1:window_len),'x')
plot(x(1+hop:window_len+hop),'x')
plot(x(1+2*hop:window_len+2*hop),'x')
plot(x(1+3*hop:window_len+3*hop),'x')
.. and if you continue you will see that the pattern repeats itself, i.e., the first plot for instance is the same as the fourth, the second as the fifth etc. Therefore you only have three different real-imaginary part combinations.
Of course, this will change if you change the window length and the hopsize, and you will get more points. For instance, try
window_len =nfft;
hop=ceil(window_len/4)
I hope that helps.

how to use ifft function in MATLAB with experimental data

I am trying to use the ifft function in MATLAB on some experimental data, but I don't get the expected results.
I have frequency data of a logarithmic sine sweep excitation, therefore I know the amplitude [g's], the frequency [Hz] and the phase (which is 0 since the point is a piloting point).
I tried to feed it directly to the ifft function, but I get a complex number as a result (and I expected a real result since it is a time signal). I thought the problem could be that the signal is not symmetric, therefore I computed the symmetric part in this way (in a 'for' loop)
x(i) = conj(x(mod(N-i+1,N)+1))
and I added it at the end of the amplitude vector.
new_amp = [amplitude x];
In this way the new amplitude vector is symmetric, but now I also doubled the dimension of that vector and this means I have to double the dimension of the frequency vector also.
Anyway, I fed the new amplitude vector to the ifft but still I don't get the logarithmic sine sweep, although this time the output is real as expected.
To compute the time [s] for the plot I used the following formula:
t = 60*3.33*log10(f/f(1))/(sweep rate)
What am I doing wrong?
Thank you in advance
If you want to create identical time domain signal from specified frequency values you should take into account lots of details. It seems to me very complicated problem and I think it need very strength background on the mathematics behind it.
But I think you may work on some details to get more acceptable result:
1- Time vector should be equally spaced based on sampling from frequency steps and maximum.
t = 0:1/fs:N/fs;
where: *N* is the length of signal in frequency domain, and *fs* is twice the
highest frequency in frequency domain.
2- You should have some sort of logarithmic phases on the frequency bins I think.
3- Your signal in frequency domain must be even to have real signal in time domain.
I hope this could help, even for someone to improve it.

DTMF, DFT window length

We've got an assignment in school to create a DTMF decoder, but are having trouble understanding what needs to be done, and how. First of all we need to calculate the energy of the signal using convolution. We do it by making use of the window length and the absolute value of the input signal:
SmoothEnergyOfInputSignal = conv(abs(X), ones(1,winlen)/winlen); %moving average
Now, we don't know how to get the proper window length. The smoothed energy is used to segment the signal, and later to determine the different frequencies in the signal making use of basis vectors(?)
The dtmf-pulses are at least 40ms separated by at least 40ms of silence.
The sampling frequency is at 8kHz and our signal is about 17601 samples long.
We thought that by doing fs*0.04 we'd get the window length. 0.04=40ms, but now the smoothed energy signal is shifted so the segments go beyond the maximum samples of the input signal.
[Sound, fs] = audioread('dtmf_all.wav');
winlen = fs*0.04
E = conv(abs(Sound),ones(1, winlen)/winlen)
Long story short: How do we calculate the "correct" window length?
Thanks in advance.
EDIT: The instructions were updated, and we're not supposed to use convolution. We're supposed to use filter()

How to test if a time series is a white noise in Matlab?

How to test if a time series x(t) (t=1,2...n) is a white noise in Matlab?
x(t) does not have to be Gaussian. kstest() will not work. autocorr(X) only test auto-correlation; it does not show the mean at each t is zero.
Thanks
For white noise, the condition is not mean=0 at each t, it is the overall mean for the sequence. The values at each t need to be independent and the overall mean needs to be zero.
In a given sequence of x(t) for different t, it does not make sense to talk about mean at each t (because there is only one value at each t)
You can use autocorr() to find out if the signal is white noise or not.
The autocorrelation of a continuous white noise signal has a strong peak (Dirac delta function) at t=0, and is 0 for all t unequal 0.
Given the assumption that you have a discrete signal I presume that the result of this finite, discrete series will look more like a Gaussian, but with increased signal length the autocorr() will resemble the dirac impulse more closely.
The other condition you referred to, the zero mean can be tested, but not infinitely precise since you only have a finite number of elements... but if Matlab gives you a mean fairly close to zero it is a strong indicator that you got a noise signal.
Also: http://en.wikipedia.org/wiki/Autocorrelation

Help me understand FFT function (Matlab)

1) Besides the negative frequencies, which is the minimum frequency provided by the FFT function? Is it zero?
2) If it is zero how do we plot zero on a logarithmic scale?
3) The result is always symmetrical? Or it just appears to be symmetrical?
4) If I use abs(fft(y)) to compare 2 signals, may I lose some accuracy?
1) Besides the negative frequencies, which is the minimum frequency provided by the FFT function? Is it zero?
fft(y) returns a vector with the 0-th to (N-1)-th samples of the DFT of y, where y(t) should be thought of as defined on 0 ... N-1 (hence, the 'periodic repetition' of y(t) can be thought of as a periodic signal defined over Z).
The first sample of fft(y) corresponds to the frequency 0.
The Fourier transform of real, discrete-time, periodic signals has also discrete domain, and it is periodic and Hermitian (see below). Hence, the transform for negative frequencies is the conjugate of the corresponding samples for positive frequencies.
For example, if you interpret (the periodic repetition of) y as a periodic real signal defined over Z (sampling period == 1), then the domain of fft(y) should be interpreted as N equispaced points 0, 2π/N ... 2π(N-1)/N. The samples of the transform at the negative frequencies -π ... -π/N are the conjugates of the samples at frequencies π ... π/N, and are equal to the samples at frequencies
π ... 2π(N-1)/N.
2) If it is zero how do we plot zero on a logarithmic scale?
If you want to draw some sort of Bode plot you may plot the transform only for positive frequencies, ignoring the samples corresponding to the lowest frequencies (in particular 0).
3) The result is always symmetrical? Or it just appears to be symmetrical?
It has Hermitian symmetry if y is real: Its real part is symmetric, its imaginary part is anti-symmetric. Stated another way, its amplitude is symmetric and its phase anti-symmetric.
4) If I use abs(fft(y)) to compare 2 signals, may I lose some accuracy?
If you mean abs(fft(x - y)), this is OK and you can use it to get an idea of the frequency distribution of the difference (or error, if x is an estimate of y). If you mean abs(fft(x)) - abs(fft(y)) (???) you lose at least phase information.
Well, if you want to understand the Fast Fourier Transform, you want to go back to the basics and understand the DFT itself. But, that's not what you asked, so I'll just suggest you do that in your own time :)
But, in answer to your questions:
Yes, (excepting negatives, as you said) it is zero. The range is 0 to (N-1) for an N-point input.
In MATLAB? I'm not sure I understand your question - plot zero values as you would any other value... Though, as rightly pointed out by duffymo, there is no natural log of zero.
It's essentially similar to a sinc (sine cardinal) function. It won't necessarily be symmetrical, though.
You won't lose any accuracy, you'll just have the magnitude response (but I guess you knew that already).
Consulting "Numerical Recipes in C", Chapter 12 on "Fast Fourier Transform" says:
The frequency ranges from negative fc to positive fc, where fc is the Nyquist critical frequency, which is equal to 1/(2*delta), where delta is the sampling interval. So frequencies can certainly be negative.
You can't plot something that doesn't exist. There is no natural log of zero. You'll either plot frequency as the x-axis or choose a range that doesn't include zero for your semi-log axis.
The presence or lack of symmetry in the frequency range depends on the nature of the function in the time domain. You can have a plot in the frequency domain that is not symmetric about the y-axis.
I don't think that taking the absolute value like that is a good idea. You'll want to read a great deal more about convolution, correction, and signal processing to compare two signals.
result of fft can be 0. already answered by other people.
to plot 0 frequency, the trick is to set it to a very small positive number (I use exp(-15) for that purpose).
already answered by other people.
if you are only interested in the magnitude, yes you can do that. this is applicable, say, in many image processing problems.
Half your question:
3) The results of the FFT operation depend on the nature of the signal; hence there's nothing requiring that it be symmetrical, although if it is you may get some more information about the properties of the signal
4) That will compare the magnitudes of a pair of signals, but those being equal do no guarantee that the FFTs are identical (don't forget about phase). It may, however, be enough for your purposes, but you should be sure of that.