Message Boards Message Boards

1
|
15187 Views
|
9 Replies
|
8 Total Likes
View groups...
Share
Share this post:

Finding peaks and valleys in data

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}

POSTED BY: Henrick Jeanty
9 Replies

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/1107009464

Nancy Blachman's book is quite good too but it is 13 years old and Mathematica had grown very considerably since then.

POSTED BY: David Reiss

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

POSTED BY: Henrick Jeanty

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 BY: Henrick Jeanty

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 BY: Vitaliy Kaurov

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 BY: David Reiss

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]}]

enter image description here

POSTED BY: Vitaliy Kaurov
POSTED BY: Henrick Jeanty

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 BY: David Reiss

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 BY: Henrick Jeanty
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract