What's the fastest way to find the local maxima of a 2D list? E.g.
nx = ny = 100;
dat = Table[Sin[2. \[Pi] x/nx] (0.1 + Cos[2. \[Pi] y/ny]), {y, 0, ny}, {x, 0, nx}];
ListPlot3D[dat]
This (updated) function has three local maxima of different heights:
Position[MaxDetect[dat], 1]
(* {{1, 26}, {51, 76}, {101, 26}} *)
dat[[1, 26]]
dat[[51, 76]]
dat[[101, 26]]
(* 1.1, 0.9, 1.1 *)
My original attempt was super-slow:
RepeatedTiming[MaxDetect[Chop@dat];][[1]]
(* 1.55 *)
Turns out using Chop
is a very bad idea. Without it is 100X faster:
RepeatedTiming[MaxDetect[dat];][[1]]
(* 0.016 *)
Along the way I discovered another version that is 2X faster yet:
RepeatedTiming[MaxDetect[Image[dat]];][[1]]
(* 0.0067 *)
Questions
- Why is
MaxDetect
so much slower whenChop
is applied? (I should add that my actual non-example problem has lots of small values that needed toChop
-ping) - Why does converting to an
Image
speed it up further? - Is there any faster way available?
UnitStep[dat - Max[dat]]
? $\endgroup$Chop[dat, Max@dat]
$\endgroup$