Fix SegmentsIterator for more than one initial NaN.

This commit is contained in:
yha 2019-06-13 16:44:05 +03:00
parent 3509648553
commit 589643d591
2 changed files with 36 additions and 27 deletions

View File

@ -214,36 +214,19 @@ end
# helpers to figure out if there are NaN values in a list of array types # helpers to figure out if there are NaN values in a list of array types
anynan(i::Int, args::Tuple) = any(a -> try isnan(_cycle(a,i)) catch MethodError false end, args) anynan(i::Int, args::Tuple) = any(a -> try isnan(_cycle(a,i)) catch MethodError false end, args)
anynan(istart::Int, iend::Int, args::Tuple) = any(i -> anynan(i, args), istart:iend) anynan(args::Tuple) = i -> anynan(i,args)
allnan(istart::Int, iend::Int, args::Tuple) = all(i -> anynan(i, args), istart:iend) anynan(istart::Int, iend::Int, args::Tuple) = any(anynan(args), istart:iend)
allnan(istart::Int, iend::Int, args::Tuple) = all(anynan(args), istart:iend)
function Base.iterate(itr::SegmentsIterator, nextidx::Int = 1) function Base.iterate(itr::SegmentsIterator, nextidx::Int = 1)
nextidx > itr.n && return nothing i = findfirst(!anynan(itr.args), nextidx:itr.n)
if nextidx == 1 && !any(isempty,itr.args) && anynan(1, itr.args) i === nothing && return nothing
nextidx = 2 nextval = nextidx + i - 1
end
i = istart = iend = nextidx j = findfirst(anynan(itr.args), nextval:itr.n)
nextnan = j === nothing ? itr.n + 1 : nextval + j - 1
# find the next NaN, and iend is the one before nextval:nextnan-1, nextnan
while i <= itr.n + 1
if i > itr.n || anynan(i, itr.args)
# done... array end or found NaN
iend = i-1
break
end
i += 1
end
# find the next non-NaN, and set nextidx
while i <= itr.n
if !anynan(i, itr.args)
break
end
i += 1
end
istart:iend, i
end end
# Find minimal type that can contain NaN and x # Find minimal type that can contain NaN and x

View File

@ -51,5 +51,31 @@ end
end end
@testset "NoFail" begin @testset "NoFail" begin
histogram([1, 0, 0, 0, 0, 0]) plots = [histogram([1, 0, 0, 0, 0, 0]),
plot([missing]),
plot([missing; 1:4]),
plot([fill(missing,10); 1:4])]
for plt in plots
display(plt)
end
end
@testset "Segments" begin
function segments(args...)
segs = UnitRange{Int}[]
for seg in iter_segments(args...)
push!(segs,seg)
end
segs
end
nan10 = fill(NaN,10)
@test segments(11:20) == [1:10]
@test segments([NaN]) == []
@test segments(nan10) == []
@test segments([nan10; 1:5]) == [11:15]
@test segments([1:5;nan10]) == [1:5]
@test segments([nan10; 1:5; nan10; 1:5; nan10]) == [11:15, 26:30]
@test segments([NaN; 1], 1:10) == [2:2, 4:4, 6:6, 8:8, 10:10]
@test segments([nan10; 1:15], [1:15; nan10]) == [11:15]
end end