diff --git a/src/minmax.jl b/src/minmax.jl index e482948..cf48349 100644 --- a/src/minmax.jl +++ b/src/minmax.jl @@ -18,7 +18,7 @@ function findnextextrema(cmp, x::AbstractVector, i::Int, w::Int, strict::Bool) peak &= false i = j > i ? j : i + 1 break # No reason to continue checking if the rest of the elements qualify - elseif xi === xj # plateau + elseif xi === xj # potential plateau k = findnext(p -> xi !== p, x, j+1) # @show k i j if strict @@ -26,7 +26,13 @@ function findnextextrema(cmp, x::AbstractVector, i::Int, w::Int, strict::Bool) xi1 = x[i-1] xk = x[k] # @show xi1 xi xk i j k - if !ismissing(xi1) && !isnan(xi1) && cmp(xi1, xi) && + if k < i + # elements of equal value are allowed within x[i-w:i+w] when + # `strict == true` (as long as the immediately previous + # element is less than `x[i]`, etc as tested on the next + # line) + continue + elseif !ismissing(xi1) && !isnan(xi1) && cmp(xi1, xi) && !ismissing(xk) && !isnan(xk) && cmp(xk, xi) # plateau begins and ends with elements less than the current return i @@ -44,7 +50,7 @@ function findnextextrema(cmp, x::AbstractVector, i::Int, w::Int, strict::Bool) else xk = isnothing(k) ? NaN : x[k] xi1 = i-1 ≥ firstindex(x) ? x[i-1] : NaN - if something(k, lastindex(x)+1) ≥ i+w && + if i+w ≤ something(k, lastindex(x)+1) && (ismissing(xi1) || isnan(xi1) || cmp(xi1, xi)) && (ismissing(xk) || isnan(xk) || cmp(xk, xi)) return i diff --git a/test/minmax.jl b/test/minmax.jl index 5947050..abc78ec 100644 --- a/test/minmax.jl +++ b/test/minmax.jl @@ -83,6 +83,10 @@ x1 = a*sin.(2*pi*f1*T*t)+b*sin.(2*pi*f2*T*t)+c*sin.(2*pi*f3*T*t); # issue #4 @test isempty(argmaxima(zeros(10))) @test argmaxima(zeros(10), 1; strict=false) == [1] + + # issue #30 + y = [12.452637, 12.389122, 12.452637, 12.512817, 48.756142, 48.410103, 45.00222] + @test findnextmaxima(y, 3, 2) === 5 end # A missing or NaN should not occur within the `w` of the peak