79
79
reducedim_initarray (A:: AbstractArray , region, v0, :: Type{R} ) where {R} = fill! (similar (A,R,reduced_indices (A,region)), v0)
80
80
reducedim_initarray (A:: AbstractArray , region, v0:: T ) where {T} = reducedim_initarray (A, region, v0, T)
81
81
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
-
101
82
# TODO : better way to handle reducedim initialization
102
83
#
103
84
# 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)
124
105
return reducedim_initarray (A, region, z, Tr)
125
106
end
126
107
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
129
135
reducedim_init (f:: Union{typeof(abs),typeof(abs2)} , op:: typeof (max), A:: AbstractArray{T} , region) where {T} =
130
136
reducedim_initarray (A, region, zero (f (zero (T))))
131
137
0 commit comments