1
|
13571 Views
|
9 Replies
|
8 Total Likes
View groups...
Share
GROUPS:

# Finding peaks and valleys in data

Posted 10 years ago
 This will probably be trivial to some here, but I am trying to figure a function to find the peaks and valleys in a data sequence. For instance, given the following sequence: a = 10 5 3 6 9 15 13 12 9 15 18 20 19 18 ... A peak is defined as (a[n] > a[n - 1] and a[n] > a[n + 1]) A valley is defined as (a[n] < a[n - 1] and a[n] < a[n + 1]) The peaks are 15 and 20 at indices 5 and 11 (index base 0) The valleys are 3 and 9 at indices 2 and 8 I would like the result of the function to be of the form: 0 0 3 0 0 15 0 0 9 0 0 20 0 0 ... or of the form {3 2} {15 5} {9 8} {20 11} ... {peak index} {valley index} .... Basically, an alternating list of peaks and valleys or of valleys and peaks depending on whether we start with a peak or a valley. Those values that are neither peaks nor valleys are set to 0 in the result. Or a list of pairs of the form {peak index} or {valley index}
9 Replies
Sort By:
Posted 10 years ago
 First a very quick comment: indices are referenced to 1 rather than 0 in Mathematica. That said, here is an approach to finding the indices (positions in the list of data) where the peaks or valleys are located In[1]:= testList = {10, 5, 3, 6, 9, 15, 13, 12, 9, 15, 18, 20, 19, 18}; In[2]:= peakTrippleQ[{x_, y_, z_}] := TrueQ[x < y > z] In[3]:= peakPositions[list_List] := Flatten[Position[peakTrippleQ /@ Partition[list, 3, 1], True] + 1] In[4]:= valleyTrippleQ[{x_, y_, z_}] := TrueQ[x > y < z] In[5]:= valleyPositions[list_List] := Flatten[Position[valleyTrippleQ /@ Partition[list, 3, 1], True] + 1] In[6]:= peakPositions[testList] Out[6]= {6, 12} In[7]:= valleyPositions[testList] Out[7]= {3, 9}
Posted 10 years ago
 Check out functions FindPeaks and PeakDetect. testList = {10, 5, 3, 6, 9, 15, 13, 12, 9, 15, 18, 20, 19, 18}; peaks = FindPeaks[testList]; valleys = {1, -1} # & /@ FindPeaks[-testList]; ListLinePlot[testList, Epilog -> {Red, PointSize[0.03], Point[peaks], Point[valleys]}]
Posted 10 years ago
 Thank you very much for your answer David, I would have to analyze your answer to understand what each part is doing. However, I must let you know that I received another answer by Vitaliy Kaurov, and it was exactly what I wanted and, I must say, simpler. Here it is: testList = {10, 5, 3, 6, 9, 15, 13, 12, 9, 15, 18, 20, 19, 18}; peaks = FindPeaks[testList]; valleys = {1, -1} # & /@ FindPeaks[-testList]; ListLinePlot[testList, Epilog -> {Red, PointSize[0.03], Point[peaks], Point[valleys]}]The answer is also in the format I need which is the index of that peak and the peak value. But thank you very much nonetheless. Regards, Henrick
Posted 10 years ago
Posted 10 years ago
 Hi Henrick,Dont worry. I got CC'd on both of your replies! By the way, I would have given you the answer that Vitaliy gave you but I forgot about FindPeaks as it is a new function in version 10. The Documentation Center for Mathematica is actually quite helpful. If you type "find peak" into its search bar, the second and third result that it returns are PeakDetect and FindPeaks. So searching in the documentation is one thing to often try first if you are wondering if Mathematica has a built in functionality that addresses a problem you are working on. Best regards, David
Posted 10 years ago
 Dear Henrick,David's advice is what most people including me do - search documentation for keywords. You can even search them for functional syntax such as /@ if you unsure about it.All discussions on this forum are public and everyone can read them. People participating on discussions get an email when the discussion gets any update. So do not worry about CC.Welcome to Wolfram Community!~ Vitaliy
Posted 10 years ago
 Hello David,Thank you for the clarification. Your suggestion is strangely reassuring. "Search documentation for keywords". I feel less like I am somehow being dense for not simply grasping it. Good, I shall search the documentation. I guess that I am wired more towards understanding a small set of simple commands which get combined to make a program (procedural), rather than a large set of powerful commands that can almost be whole programs in their own right.This brings interesting questions on how do we learn? Are others in this community like me? Or is it just that I have been "programmed" to be more comfortable with the procedural approach thanks to having started with Fortran, then Basic, Assembler, C, C++, C#. Are there people in this community who find Mathematica "obvious" and "natural" to use?I wonder if anyone in this community has a book to recommend. I have "Mathematica, a practical approach", 2nd Ed, by Nancy Bachman and Colin P. Williams. I will of course be looking at the ample documentation in Mathematica, but I like having a book I can hold in my hands (I guess I'm old fashioned).Well, thank you for listening to my musings, Henrick
Posted 10 years ago
 I think that Paul Wellin's recent book "Programming with Mathematica®: An Introduction" is quite good. Paul was the head of training at Wolfram Research for many years. The book is for Mathematica 9: it came out a year before version 10 came out, so the new things from version 10 are (obviously!) not discussed.http://www.amazon.com/Programming-Mathematica-Introduction-Paul-Wellin/dp/1107009464Nancy Blachman's book is quite good too but it is 13 years old and Mathematica had grown very considerably since then.
Posted 10 years ago
 Hello David, Thank you for the pointer. I checked the book out of my school's library. It is in e-book format. I will be reading and looking forward to improving my Mathematica programming knowledge and skills.Regards, Henrick