Skip to content

Commit 13a68a0

Browse files
nalimilantkelman
authored andcommitted
Fix findmax and findmin with iterables
The state is not guaranteed to be equivalent to the index of the element. (cherry picked from commit bbaaf54) ref #14086
1 parent 06c9fe3 commit 13a68a0

File tree

4 files changed

+28
-23
lines changed

4 files changed

+28
-23
lines changed

base/abstractarray.jl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,9 +408,6 @@ start(A::AbstractArray) = (@_inline_meta(); itr = eachindex(A); (itr, start(itr)
408408
next(A::AbstractArray,i) = (@_inline_meta(); (idx, s) = next(i[1], i[2]); (A[idx], (i[1], s)))
409409
done(A::AbstractArray,i) = done(i[1], i[2])
410410

411-
iterstate(i) = i
412-
iterstate(i::Tuple{UnitRange{Int},Int}) = i[2]
413-
414411
# eachindex iterates over all indices. LinearSlow definitions are later.
415412
eachindex(A::AbstractArray) = (@_inline_meta(); eachindex(linearindexing(A), A))
416413

base/array.jl

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -830,36 +830,36 @@ function findmax(a)
830830
if isempty(a)
831831
throw(ArgumentError("collection must be non-empty"))
832832
end
833-
i = start(a)
834-
mi = i
835-
m, i = next(a, i)
836-
while !done(a, i)
837-
iold = i
838-
ai, i = next(a, i)
833+
s = start(a)
834+
mi = i = 1
835+
m, s = next(a, s)
836+
while !done(a, s)
837+
ai, s = next(a, s)
838+
i += 1
839839
if ai > m || m!=m
840840
m = ai
841-
mi = iold
841+
mi = i
842842
end
843843
end
844-
return (m, iterstate(mi))
844+
return (m, mi)
845845
end
846846

847847
function findmin(a)
848848
if isempty(a)
849849
throw(ArgumentError("collection must be non-empty"))
850850
end
851-
i = start(a)
852-
mi = i
853-
m, i = next(a, i)
854-
while !done(a, i)
855-
iold = i
856-
ai, i = next(a, i)
851+
s = start(a)
852+
mi = i = 1
853+
m, s = next(a, s)
854+
while !done(a, s)
855+
ai, s = next(a, s)
856+
i += 1
857857
if ai < m || m!=m
858858
m = ai
859-
mi = iold
859+
mi = i
860860
end
861861
end
862-
return (m, iterstate(mi))
862+
return (m, mi)
863863
end
864864

865865
indmax(a) = findmax(a)[2]

base/multidimensional.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
### Multidimensional iterators
44
module IteratorsMD
55

6-
import Base: eltype, length, start, done, next, last, getindex, setindex!, linearindexing, min, max, eachindex, ndims, iterstate
6+
import Base: eltype, length, start, done, next, last, getindex, setindex!, linearindexing, min, max, eachindex, ndims
77
importall ..Base.Operators
88
import Base: simd_outer_range, simd_inner_length, simd_index, @generated
99
import Base: @nref, @ncall, @nif, @nexprs, LinearFast, LinearSlow, to_index
@@ -59,8 +59,6 @@ immutable CartesianRange{I<:CartesianIndex}
5959
stop::I
6060
end
6161

62-
iterstate{CR<:CartesianRange,CI<:CartesianIndex}(i::Tuple{CR,CI}) = Base._sub2ind(i[1].stop.I, i[2].I)
63-
6462
@generated function CartesianRange{N}(I::CartesianIndex{N})
6563
startargs = fill(1, N)
6664
:(CartesianRange($I($(startargs...)), I))

test/arrayops.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ for i = 1:3
306306
end
307307
@test isequal(a,findn(z))
308308

309-
#argmin argmax
309+
#findmin findmax indmin indmax
310310
@test indmax([10,12,9,11]) == 2
311311
@test indmin([10,12,9,11]) == 3
312312
@test findmin([NaN,3.2,1.8]) == (1.8,3)
@@ -316,6 +316,16 @@ end
316316
@test findmin([3.2,1.8,NaN,2.0]) == (1.8,2)
317317
@test findmax([3.2,1.8,NaN,2.0]) == (3.2,1)
318318

319+
# #14085
320+
@test findmax(4:9) == (9,6)
321+
@test indmax(4:9) == 6
322+
@test findmin(4:9) == (4,1)
323+
@test indmin(4:9) == 1
324+
@test findmax(5:-2:1) == (5,1)
325+
@test indmax(5:-2:1) == 1
326+
@test findmin(5:-2:1) == (1,3)
327+
@test indmin(5:-2:1) == 3
328+
319329
## permutedims ##
320330

321331
#keeps the num of dim

0 commit comments

Comments
 (0)