Skip to content

Commit 86b3d99

Browse files
committed
Recover original min/max init
This commit just Recover the initialization of `minimum/maximum` on master
1 parent 975a0c8 commit 86b3d99

File tree

1 file changed

+34
-25
lines changed

1 file changed

+34
-25
lines changed

base/reducedim.jl

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -124,36 +124,45 @@ function _reducedim_init(f, op, fv, fop, A, region)
124124
end
125125

126126
# initialization when computing minima and maxima requires a little care
127-
function reducedim_init(f::F, ::Union{typeof(min),typeof(max)}, A::AbstractArray, region) where {F}
128-
# First compute the reduce indices. This will throw an ArgumentError
129-
# if any region is invalid
130-
ri = reduced_indices(A, region)
127+
for (f1, f2, initval, typeextreme) in ((:min, :max, :Inf, :typemax), (:max, :min, :(-Inf), :typemin))
128+
@eval function reducedim_init(f, op::typeof($f1), A::AbstractArray, region)
129+
# First compute the reduce indices. This will throw an ArgumentError
130+
# if any region is invalid
131+
ri = reduced_indices(A, region)
131132

132-
# Next, throw if reduction is over a region with length zero
133-
any(i -> isempty(axes(A, i)), region) && _empty_reduce_error()
133+
# Next, throw if reduction is over a region with length zero
134+
any(i -> isempty(axes(A, i)), region) && _empty_reduce_error()
134135

135-
# Make a view of the first slice of the region
136-
A1 = view(A, ri...)
136+
# Make a view of the first slice of the region
137+
A1 = view(A, ri...)
137138

138-
# calculate the output type
139-
T = promote_typejoin_union(_return_type(f, Tuple{eltype(A)}))
140-
141-
map!(f, reducedim_initarray(A,region,_InitialValue(),T), A1)
142-
end
139+
if isempty(A1)
140+
# If the slice is empty just return non-view version as the initial array
141+
return copy(A1)
142+
else
143+
# otherwise use the min/max of the first slice as initial value
144+
v0 = mapreduce(f, $f2, A1)
145+
146+
T = _realtype(f, promote_union(eltype(A)))
147+
Tr = v0 isa T ? T : typeof(v0)
148+
149+
# but NaNs and missing need to be avoided as initial values
150+
if (v0 == v0) === false
151+
# v0 is NaN
152+
v0 = $initval
153+
elseif isunordered(v0)
154+
# v0 is missing or a third-party unordered value
155+
Tnm = nonmissingtype(Tr)
156+
# TODO: Some types, like BigInt, don't support typemin/typemax.
157+
# So a Matrix{Union{BigInt, Missing}} can still error here.
158+
v0 = $typeextreme(Tnm)
159+
end
160+
# v0 may have changed type.
161+
Tr = v0 isa T ? T : typeof(v0)
143162

144-
function reducedim_init(f::ExtremaMap, ::typeof(_extrema_rf), A::AbstractArray, region)
145-
ri = reduced_indices(A, region)
146-
any(i -> isempty(axes(A, i)), region) && _empty_reduce_error()
147-
A1 = view(A, ri...)
148-
IT = eltype(A)
149-
if missing isa IT
150-
RT = promote_typejoin_union(_return_type(f.f, Tuple{nonmissingtype(IT)}))
151-
T = Union{Tuple{RT,RT},Tuple{Missing,Missing}}
152-
else
153-
RT = promote_typejoin_union(_return_type(f.f, Tuple{IT}))
154-
T = Union{Tuple{RT,RT}}
163+
return reducedim_initarray(A, region, v0, Tr)
164+
end
155165
end
156-
map!(f, reducedim_initarray(A,region,_InitialValue(),T), A1)
157166
end
158167

159168
reducedim_init(f::Union{typeof(abs),typeof(abs2)}, op::typeof(max), A::AbstractArray{T}, region) where {T} =

0 commit comments

Comments
 (0)