# Find all minima of a list of points

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]


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!

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}}
*)

• Thank you, I didn't know SequenceCases. I'm still wondering why Cases only returns one minima... Nov 30, 2020 at 7:27

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

• Thanks for this tricky solution. Nov 30, 2020 at 7:43
SeedRandom[0];

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


Using PeakDetect

Rest @ Pick[xy, PeakDetect[-Last /@ xy], 1]


{{4.90706, -0.981112}, {11.0208, -0.999682}, {17.2382, -0.999178}}

SeedRandom[0];

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


Using ReplaceList:

pts = ReplaceList[xy, {___, {_, a_}, p : {_, b_}, {_, c_}, ___} /; a > b && c > b :> p]

ListLinePlot[xy, PlotStyle -> Blue, Epilog -> {PointSize[0.015], Red, Point[pts]}]

(*{{4.90706, -0.981112}, {11.0208, -0.999682}, {17.2382, -0.999178}}*)


ReplaceList is faster compared to SequenceCases.