1
$\begingroup$

Given a list of points {x[i],y[i]} I would like to find all the local minima of y

Example:

xy = Table[{x, Sin[x]}, {x, RandomReal[{0, 2 Pi 3}, 200] // Sort}];
ListPlot[xy]

enter image description here

I tried to solve this task using Cases ,

 Cases[xy, {___, {_, a_ }, p : {_, b_ }, {_, c_ }, ___} /;a > b && c > b :> p, All] 
 (*{{4.71476, -0.999997}}*)

but Mathematica only returns 1 minimum .

What's wrong with my code? Perhaps alternative solutions exist?

Thanks!

$\endgroup$
3
$\begingroup$

Use SequenceCases instead of Cases:

SequenceCases[xy, {{_, a_}, p : {_, b_}, {_, c_}} /; a > b && b < c :> p]

(* Out:
{{4.75359, -0.999151}, {10.8845, -0.993834}, {17.2955, -0.99986}}
*)
$\endgroup$
1
  • $\begingroup$ Thank you, I didn't know SequenceCases. I'm still wondering why Cases only returns one minima... $\endgroup$ Nov 30 '20 at 7:27
1
$\begingroup$

Simple: use FindPeaks on -xy. To avoid finding a minimum at the first or the last point, use

valleys = 
 xy[[Cases[First /@ FindPeaks[-Last /@ xy], 
    Except[1 | Length[xy], _]]]]

ListPlot[xy, Epilog -> {PointSize[Medium], Red, Point[valleys]}]
$\endgroup$
1
  • $\begingroup$ Thanks for this tricky solution. $\endgroup$ Nov 30 '20 at 7:43

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.