7979reducedim_initarray (A:: AbstractArray , region, v0, :: Type{R} ) where {R} = fill! (similar (A,R,reduced_indices (A,region)), v0)
8080reducedim_initarray (A:: AbstractArray , region, v0:: T ) where {T} = reducedim_initarray (A, region, v0, T)
8181
82- function reducedim_initarray0 (A:: AbstractArray{T} , region, f, ops) where T
83- ri = reduced_indices0 (A, region)
84- if isempty (A)
85- if prod (length, reduced_indices (A, region)) != 0
86- reducedim_initarray0_empty (A, region, f, ops) # ops over empty slice of A
87- else
88- R = f == identity ? T : Core. Compiler. return_type (f, (T,))
89- similar (A, R, ri)
90- end
91- else
92- R = f == identity ? T : typeof (f (first (A)))
93- si = similar (A, R, ri)
94- mapfirst! (f, si, A)
95- end
96- end
97-
98- reducedim_initarray0_empty (A:: AbstractArray , region, f, ops) = mapslices (x-> ops (f .(x)), A, region)
99- reducedim_initarray0_empty (A:: AbstractArray , region,:: typeof (identity), ops) = mapslices (ops, A, region)
100-
10182# TODO : better way to handle reducedim initialization
10283#
10384# The current scheme is basically following Steven G. Johnson's original implementation
@@ -124,8 +105,33 @@ function _reducedim_init(f, op, fv, fop, A, region)
124105 return reducedim_initarray (A, region, z, Tr)
125106end
126107
127- reducedim_init (f, op:: typeof (max), A:: AbstractArray{T} , region) where {T} = reducedim_initarray0 (A, region, f, maximum)
128- reducedim_init (f, op:: typeof (min), A:: AbstractArray{T} , region) where {T} = reducedim_initarray0 (A, region, f, minimum)
108+ # initialization when computing minima and maxima requires a little care
109+ for (f1, f2, supval) in ((min, max, Inf ), (max, min, - Inf ))
110+ function reducedim_init (f, op:: typeof (f1), A:: AbstractArray , region)
111+ # First compute the reduce indices. This will throw an ArgumentError
112+ # if any region is invalid
113+ ri = Base. reduced_indices (A, region)
114+
115+ # Next, throw if reduction is over a region with length zero
116+ any (i -> iszero (size (A, i)), region) && _empty_reduce_error ()
117+
118+ # Make a view of the first slice of the region
119+ A1 = view (A, ri... )
120+
121+ if isempty (A1)
122+ # If the slice is empty just return non-view version as the initial array
123+ return copy (A1)
124+ else
125+ # otherwise use the min/max of the first slice as initial value
126+ v0 = mapreduce (f, f2, A1)
127+
128+ # but NaNs need to be avoided as intial values
129+ v0 = v0 != v0 ? typeof (v0)(supval) : v0
130+
131+ return reducedim_initarray (A, region, v0)
132+ end
133+ end
134+ end
129135reducedim_init (f:: Union{typeof(abs),typeof(abs2)} , op:: typeof (max), A:: AbstractArray{T} , region) where {T} =
130136 reducedim_initarray (A, region, zero (f (zero (T))))
131137
0 commit comments