Searching for specific maxima
Mostrar comentarios más antiguos
Hello Everyone,
I have a specific question. Let us say I have some random data set that looks like this:
1 2 1 2 3 2 3 4 122 3 4 5 3 51 4 2
I am expecting two "maxima" or peaks (not necessarily 122 or 51). I want to be able to autonomously detect the two largest maxima, save the two maxima values and the index where they occur. Is there an easy way to do this?
Thanks for your help.
1 comentario
Walter Roberson
el 17 de En. de 2012
What if more than one location has the same maximum (or second highest) value?
Respuestas (5)
the cyclist
el 18 de En. de 2012
x = [1 2 1 2 3 2 3 4 122 3 4 5 3 51 4 2];
[sorted_x indexToSortedValues] = sort(x,'descend');
This will sort the values from high-to-low, and tell you the indices of the sorted values. Be wary of the potential uncertainty that Walter mentions in his comment.
5 comentarios
Sarah
el 18 de En. de 2012
Walter Roberson
el 18 de En. de 2012
There are a number of peak-picking routines in the MATLAB File Exchange; they should work better than looking at the maxima.
Image Analyst
el 18 de En. de 2012
I agree with Walter. The cyclist's code will do what he says but it won't necessarily find peaks or help you locate them, unless your second peak is the second highest value. For example if you still have two peaks but your data looks like x = [1 2 1 2 3 2 3 4 122 120 4 5 3 51 4 2] your second value will be 120, which was part of the first peak, and your second peak is now located as the third value of the sorted array - probably not where you expected to find it. (This is a different watchout than Walter's warning of multiple elements with the same value.)
the cyclist
el 18 de En. de 2012
I have to admit I totally missed the fact that you seem to be looking for localized peaks, as opposed to just the two largest values (i.e. maxima). There was an FEX "Pick of the Week" for finding local extrema, as discussed here: http://blogs.mathworks.com/pick/2008/05/09/finding-local-extrema/
Sarah
el 18 de En. de 2012
Andrei Bobrov
el 18 de En. de 2012
A = [1 2 1 2 3 2 3 4 122 120 3 4 5 3 51 4 2]
[pks,locs] = findpeaks(A)
[ix,ix] = sort(pks,'descend')
outpks = pks(ix(1:2))
outidx = locs(ix(1:2))
3 comentarios
the cyclist
el 18 de En. de 2012
Note that the findpeaks() function is part of the Signal Processing Toolbox, so you may not have access to it.
Sarah
el 18 de En. de 2012
Andrei Bobrov
el 18 de En. de 2012
Hi cyclist! Variant without 'findpeaks'.
i1 = diff(A(:).')>0;
ix = strfind(i1,[1 0]);
[c i2] = sort(A(ix),'descend')
outpks = c(1:2)
outidx = ix(i2(1:2))
Dr. Seis
el 18 de En. de 2012
Similar to andrei:
A = [1 2 1 2 3 2 3 4 122 120 3 4 5 3 51 4 2]
[pks,locs] = findpeaks(A)
maxpks = max(pks);
threshold = 0.4; % 40% threshold
outpks = pks(pks>threshold*maxpks);
outidx = locs(pks>threshold*maxpks);
Set the threshold so that it will only pick up either: 1) the biggest two picks or 2) one peak
3 comentarios
Sarah
el 18 de En. de 2012
Dr. Seis
el 18 de En. de 2012
The threshold value is data dependent. It was just a random value that I picked that would yield the largest of the two peaks and would yield only one peak should those two transition together (since if they joined together there would be no other individual peak greater than 40% of 122+51). If, in reality, the peaks are going to be a lot closer in amplitude than the difference between 122 and 51, then you can make that threshold larger (like 80%). However, if you are expecting a larger range of differences between the largest peak and the second largest peak (before they transition into one peak) then you will need to set that threshold lower (like 20-30%).
Sarah
el 22 de En. de 2012
Sarah
el 22 de En. de 2012
0 votos
12 comentarios
Dr. Seis
el 22 de En. de 2012
You don't happen to have a short example (like the size you posted before) where the threshold method breaks down? Is it that in certain circumstances the second peak falls way below the defined threshold... or does findpeaks not actually see a double peak when those two peaks begin to merge?
Sarah
el 22 de En. de 2012
Image Analyst
el 22 de En. de 2012
It looks like you're plotting only the markers and maybe they oscillate on an element by element basis giving the appearance of two separate plots. Can you set xlim([9.475 9.525]) and plot with lines, like plot(data, 'bo-') so we can see what's going on?
Sarah
el 22 de En. de 2012
Sarah
el 22 de En. de 2012
Dr. Seis
el 22 de En. de 2012
Sorry, one more plot. Can you plot <http://i.imgur.com/RzcOW.jpg> using the same limits as <http://i.imgur.com/8K2ZZ.jpg> (i.e., [9.475 9.525])? So, just to be sure, in the earlier picture where there are two peaks, the robust peak finder should in fact return two peaks?
Sarah
el 22 de En. de 2012
Sarah
el 22 de En. de 2012
Dr. Seis
el 22 de En. de 2012
So... I think I see the problem. There are going to be cases where you might need a threshold of 10% so that (as in the case immediately above) it will detect both the primary and the secondary peak. But (maybe) in other cases a threshold of 10% will return peaks that it should not have.
Dr. Seis
el 22 de En. de 2012
Is there, perhaps, a window of indices around the main peak that it should check? For example, it should only check for extra peaks +/- 500 indices from the main peak?
Sarah
el 22 de En. de 2012
Dr. Seis
el 22 de En. de 2012
Try a range of 1.1 times the number of indices associated with the width of your pulse.
Dr. Seis
el 22 de En. de 2012
Next idea, instead of envelope of Freq we replace any negative (or really small) frequencies with linear interpolation of positive ones:
tempFreq = Freq(1,:);
maxFreq = max(tempFreq);
for i = 2 : length(tempFreq)-1
if tempFreq(i) <= 0.01*maxFreq
tempFreq(i) = mean(tempFreq([i-1,i+1]));
end
end
[Peaks,Index] = findpeaks(tempFreq);
[MaxPeak,IndPeak] = max(Peaks);
IndRange = abs(Index(IndPeak)-Index);
IndThres = 500; % Set this value to the number of indices
% associated with your pulse width * 1.1
OutPks = Peaks( IndRange <= IndThres );
OutPks = Index( IndRange <= IndThres );
[OutRow,OutColumn] = size(OutPks);
You will still need to define IndThres to be the about 1.1 times your pulse width above.
Categorías
Más información sobre Descriptive Statistics en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!