0
$\begingroup$

I am trying to extract amplitude of specific frequency in Matlab FFT. Is it possible to use the abs(mag)... But I do not know in which sample to look for mag(245) should give me amplitude for the frequency of that sample...

How to extract that amplitude-magnitude for $120$ Hz using mag?

I will add simple code:

Fs = 1000;                    % Sampling frequency
T = 1/Fs;                     % Sample time
L = 1000;                     % Length of signal
t = (0:L-1)*T;                % Time vector
% Sum of a 50 Hz sinusoid and a 120 Hz sinusoid
x = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t); 
y = x + 2*randn(size(t));     % Sinusoids plus noise
f=(0:L-1)*Fs/L;
x=fft(y);
mag=abs(x);
mag(1)=0;
plot(f(1:L/2),(2/L*mag(1:L/2)));
title('Single-Sided Amplitude Spectrum of y(t)')
xlabel('Frequency (Hz)')
ylabel('|Y(f)|')  

FFT OF THE CODE

$\endgroup$
1
$\begingroup$

The formula you are looking for is

(desired freq / Sampling Frequency) * Length of samples = sample number

you can see this works out even by verifying the units

(Hz / Hz )* sample = sample

depending on your exact frequencies, the result may or may not be an integer number. If it is not an integer, that means the exact frequency wasn't captured (due to Fs). For example if your result was 23.8 you would have to look at either sample 23 or sample 24 to get the data you required, or do some sort of interpolation.

Good luck

edit

as your comment specified, this doesn't work exactly, the reason is becasue matlab does 1 indexing, not 0 indexing. So our DC component 0Hz is at element 1, not element 0 but the above formulas are correct. However implementing in matlab is a little different

desired_freq = 120; %Hz
desired_index = (desired_freq / Fs) * L + 1; %+1 is because matlab uses 1 indexing not 0 indexing

again desired index may not be an integer number so you can't simply say mag(desired_index) one workaround would be mag(round(desired_index))

$\endgroup$
  • $\begingroup$ Thank you for helping but I can not make it work, or it not work as you wanted. If I want to extract amplitude of frequency 120 Hz from above example it would be like this: [sample number =(120/Fs)*L; % Gives result 120 % Then to calculate amplitude at 120 Hz it would be as I see like this [A120] = mag(120); % gives results much more then 1 but it should be around one...Probably I make mistake or the formula does not work, please help...thanks. $\endgroup$ – ToShare Mar 31 '15 at 22:41
  • $\begingroup$ Hello ToShare. I forgot matlab uses 1 indexing, not 0 indexing. please see my edit $\endgroup$ – andrew Mar 31 '15 at 22:50
0
$\begingroup$

The answer of andrew assumes a certain structure of the array containing the frequencies. For MATLAB in general you can also use logical filters quite easily to return specific elements of a certain array. I your case it would be something like:

mag(f == 120)

Like stated in the answer of andrew, this will return an empty array if in this case 120 would not be part of f.

$\endgroup$
  • $\begingroup$ fibonatic, you gave me and idea of using logical operator for frequency band...thank you. $\endgroup$ – ToShare Apr 1 '15 at 8:05
  • $\begingroup$ Why the downvote? $\endgroup$ – fibonatic Apr 1 '15 at 11:44
  • $\begingroup$ As I said your answer is clear and very useful. I did not "downvote" or I do not understand it correctly? $\endgroup$ – ToShare Apr 1 '15 at 16:25
  • $\begingroup$ I like this answer a lot, but I'm a bit confused as to how exactly it works. As far as I can tell there is no dependence on f in mag is this possible because we used the fft command when creating x? I'm sure I'm overlooking something simple, thanks. $\endgroup$ – andrew Apr 1 '15 at 16:28
  • 1
    $\begingroup$ @andrew It is due to the syntax of MATLAB, f==120 returns an array of the type logical which has the same size as f and contains a true at the same indices at which f is equal to 120 (every other is false). Such a logical array (I do believe it has to be the same size) can be used as "filter" in MATLAB, such that it returns an array containing only the elements of mag of the same indices for which the logical array is equal to true. $\endgroup$ – fibonatic Apr 1 '15 at 17:12
-1
$\begingroup$

EDIT

I just noticed that you have already scaled your fft output.
Mag(121) will give you what you want.
If you still want the amplitude to be scaled like your figure do, scale Mag(121) too.

Just a problem with indexing.

$\endgroup$
  • $\begingroup$ Yes, good point and elegant. This solved the problem: [A] = mag(121)*2/L; Thank you a lot...Am I good with Length of samples = 2/L = 500? I do not see the reason where I made a mistake? $\endgroup$ – ToShare Apr 1 '15 at 7:54
  • $\begingroup$ Do not mention it. Misunderstand you at first and I edited the post. You have already scaled the axis, so you do not have to calculate any index. $\endgroup$ – pakornosky Apr 1 '15 at 9:23
  • $\begingroup$ Fine...very good discussion with all of you... $\endgroup$ – ToShare Apr 1 '15 at 10:09
  • $\begingroup$ If this solve your question, please vote up and check mark on the left. Thanks. $\endgroup$ – pakornosky Apr 3 '15 at 5:11

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.