Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add isplateau #47

Merged
merged 1 commit into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ findnextmaxima
findnextminima
ismaxima
isminima
isplateau
```

2 changes: 1 addition & 1 deletion src/Peaks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Peaks

export argmaxima, argminima, maxima, minima, findmaxima, findminima, findnextmaxima,
findnextminima, peakproms, peakproms!, peakwidths, peakwidths!, peakheights,
peakheights!, ismaxima, isminima, filterpeaks!
peakheights!, ismaxima, isminima, isplateau, filterpeaks!

include("minmax.jl")
include("utils.jl")
Expand Down
31 changes: 28 additions & 3 deletions src/minmax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ of a plateau must exist. For `strict == false`, a maxima is the maximum of all n
`NaN`, or either end of the array, `x[begin-1]` or `x[end+1]`, may be treated as the bounds
of a plateau).

See also: [`findmaxima`](@ref), [`findnextmaxima`](@ref)
See also: [`findmaxima`](@ref), [`findnextmaxima`](@ref), [`argminima`](@ref)

# Examples
```jldoctest
Expand Down Expand Up @@ -186,7 +186,7 @@ Find the values of local maxima in `x`, where each maxima `i` is either the maxi
A plateau is defined as a maxima with consecutive equal (`===`/egal) maximal values which
are bounded by lesser values immediately before and after the consecutive maximal values.

See also: [`argmaxima`](@ref), [`findnextmaxima`](@ref)
See also: [`argmaxima`](@ref), [`findnextmaxima`](@ref), [`minima`](@ref)
"""
function maxima(
x::AbstractVector{T}, w::Int=1; strict::Bool=true
Expand All @@ -208,7 +208,7 @@ the argument `x`.
A plateau is defined as a maxima with consecutive equal (`===`/egal) maximal values which
are bounded by lesser values immediately before and after the consecutive maximal values.

See also: [`argmaxima`](@ref), [`findnextmaxima`](@ref)
See also: [`argmaxima`](@ref), [`findnextmaxima`](@ref), [`findminima`](@ref)

# Examples
```jldoctest
Expand Down Expand Up @@ -252,6 +252,7 @@ julia> findnextminima([3,2,3,1,1,3], 3)
```
"""
findnextminima(x, i, w=1; strict=true) = findnextextrema(>, x, i, w, strict)

"""
isminima(i, x[, w=1; strict=true]) -> Bool

Expand Down Expand Up @@ -360,3 +361,27 @@ function findminima(x, w::Int=1; strict::Bool=true)
idxs = argminima(x, w; strict=strict)
return (;indices=idxs, heights=x[idxs], data=x)
end

"""
isplateau(i, x[, w=1; strict=true]) -> Union{Missing,Bool}

Test if `i` is a plateau in `x`, where a plateau is defined as a maxima or minima with
consecutive equal (`===`/egal) extreme values which are bounded by lesser values immediately
before and after the consecutive values. Returns `false` if `i` is the last index in `x`.

See also: [`ismaxima`](@ref), [`isminima`](@ref)
"""
function isplateau(i, x, w=1; strict=true)
if ismaxima(i, x, w; strict) || isminima(i, x, w; strict)
if i === lastindex(x)
# default unstrict assumption that first/last element can be peak means that we
# should not assume first/last element is (also) a plateau (too much assuming)
return false
else
return x[i] === x[i+1]
end
else
return false
end
end

9 changes: 8 additions & 1 deletion test/minmax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ x1 = a*sin.(2*pi*f1*T*t)+b*sin.(2*pi*f2*T*t)+c*sin.(2*pi*f3*T*t);
@test isempty(argminima(reverse(mn)))
end

@testset "is(minima|maxima)" begin
@testset "is(minima|maxima|plateau)" begin
isx = [0,0,3,1,2,0,4,4,0,5]
ispk = [0,0,1,0,1,0,1,0,0,1] # Not strict

Expand All @@ -164,6 +164,13 @@ x1 = a*sin.(2*pi*f1*T*t)+b*sin.(2*pi*f2*T*t)+c*sin.(2*pi*f3*T*t);
@test isminima(10, -isx; strict=true) == false
@test isminima(10, -isx; strict=false) == true
@test isminima.(eachindex(isx), Ref(-isx); strict=false) == ispk

@test isplateau(7, isx) == true
@test isplateau(8, isx) == false
@test isplateau(3, isx) == false

@test isplateau(10, isx; strict=true) == false
@test isplateau(10, isx; strict=false) == false
end

pks, vals = @test_nowarn findmaxima(x1)
Expand Down
Loading