15
15
# Certain reductions like sum and prod may wish to promote the items being reduced over to
16
16
# an appropriate size. Note we need x + zero(x) because some types like Bool have their sum
17
17
# lie in a larger type.
18
- promote_sys_size (T :: Type ) = T
19
- promote_sys_size ( :: Type{<: SmallSigned} ) = Int
20
- promote_sys_size ( :: Type{<: SmallUnsigned} ) = UInt
18
+ add_tosys (x,y ) = x + y
19
+ add_tosys (x :: SmallSigned ,y :: SmallSigned ) = Int (x) + Int (y)
20
+ add_tosys (x :: SmallUnsigned ,y :: SmallUnsigned ) = UInt (x) + UInt (y)
21
21
22
- promote_sys_size_add (x) = convert (promote_sys_size (typeof (x + zero (x))), x)
23
- promote_sys_size_mul (x) = convert (promote_sys_size (typeof (x * one (x))), x)
24
- const _PromoteSysSizeFunction = Union{typeof (promote_sys_size_add),
25
- typeof (promote_sys_size_mul)}
22
+ mul_tosys (x,y) = x * y
23
+ mul_tosys (x:: SmallSigned ,y:: SmallSigned ) = Int (x) * Int (y)
24
+ mul_tosys (x:: SmallUnsigned ,y:: SmallUnsigned ) = UInt (x) * UInt (y)
26
25
27
26
# # foldl && mapfoldl
28
27
@@ -253,6 +252,12 @@ reduce_empty(::typeof(*), T) = one(T)
253
252
reduce_empty (:: typeof (& ), :: Type{Bool} ) = true
254
253
reduce_empty (:: typeof (| ), :: Type{Bool} ) = false
255
254
255
+ reduce_empty (:: typeof (add_tosys), T) = zero (T)
256
+ reduce_empty (:: typeof (add_tosys), :: Type{T} ) where {T<: SmallSigned } = zero (Int)
257
+ reduce_empty (:: typeof (add_tosys), :: Type{T} ) where {T<: SmallUnsigned } = zero (UInt)
258
+ reduce_empty (:: typeof (mul_tosys), T) = one (T)
259
+ reduce_empty (:: typeof (mul_tosys), :: Type{T} ) where {T<: SmallSigned } = one (Int)
260
+ reduce_empty (:: typeof (mul_tosys), :: Type{T} ) where {T<: SmallUnsigned } = one (UInt)
256
261
257
262
"""
258
263
Base.mapreduce_empty(f, op, T)
@@ -263,37 +268,44 @@ array with element type of `T`.
263
268
If not defined, this will throw an `ArgumentError`.
264
269
"""
265
270
mapreduce_empty (f, op, T) = _empty_reduce_error ()
266
- mapreduce_empty (:: typeof (identity), op, T) = reduce_empty (op, T)
267
- mapreduce_empty (f:: _PromoteSysSizeFunction , op, T) =
268
- f (mapreduce_empty (identity, op, T))
269
- mapreduce_empty (:: typeof (abs), :: typeof (+ ), T) = abs (zero (T))
270
- mapreduce_empty (:: typeof (abs2), :: typeof (+ ), T) = abs2 (zero (T))
271
- mapreduce_empty (:: typeof (abs), :: Union{typeof(scalarmax), typeof(max)} , T) =
272
- abs (zero (T))
273
- mapreduce_empty (:: typeof (abs2), :: Union{typeof(scalarmax), typeof(max)} , T) =
274
- abs2 (zero (T))
275
-
276
- # Allow mapreduce_empty to “see through” promote_sys_size
277
- let ComposedFunction = typename (typeof (identity ∘ identity)). wrapper
278
- global mapreduce_empty (f:: ComposedFunction{<:_PromoteSysSizeFunction} , op, T) =
279
- f. f (mapreduce_empty (f. g, op, T))
280
- end
271
+ mapreduce_empty (f:: typeof (identity), op, T) = f (reduce_empty (op, T))
272
+ mapreduce_empty (f:: typeof (abs), op, T) = f (reduce_empty (op, T))
273
+ mapreduce_empty (f:: typeof (abs2), op, T) = f (reduce_empty (op, T))
274
+
275
+ mapreduce_empty (f:: typeof (abs), :: Union{typeof(scalarmax), typeof(max)} , T) = abs (zero (T))
276
+ mapreduce_empty (f:: typeof (abs2), :: Union{typeof(scalarmax), typeof(max)} , T) = abs2 (zero (T))
281
277
282
278
mapreduce_empty_iter (f, op, itr, :: HasEltype ) = mapreduce_empty (f, op, eltype (itr))
283
279
mapreduce_empty_iter (f, op:: typeof (& ), itr, :: EltypeUnknown ) = true
284
280
mapreduce_empty_iter (f, op:: typeof (| ), itr, :: EltypeUnknown ) = false
285
281
mapreduce_empty_iter (f, op, itr, :: EltypeUnknown ) = _empty_reduce_error ()
286
282
287
283
# handling of single-element iterators
284
+ """
285
+ Base.reduce_single(f, op, x)
286
+
287
+ The value to be returned when calling [`reduce`] with `op` over an iterator which contains
288
+ a single element `x`.
289
+
290
+ The default is `x`.
291
+ """
292
+ reduce_single (op, x) = x
293
+ reduce_single (:: typeof (add_tosys), x:: SmallSigned ) = Int (x)
294
+ reduce_single (:: typeof (add_tosys), x:: SmallUnsigned ) = UInt (x)
295
+ reduce_single (:: typeof (mul_tosys), x:: SmallSigned ) = Int (x)
296
+ reduce_single (:: typeof (mul_tosys), x:: SmallUnsigned ) = UInt (x)
297
+
288
298
"""
289
299
Base.mapreduce_single(f, op, x)
290
300
291
301
The value to be returned when calling [`mapreduce`] with `f` and `op` over an iterator
292
302
which contains a single element `x`.
293
303
294
- The default is `f(x )`.
304
+ The default is `f(reduce_single(op, x) )`.
295
305
"""
296
- mapreduce_single (f, op, x) = f (x)
306
+ mapreduce_single (f, op, x) = f (reduce_single (op, x))
307
+
308
+
297
309
298
310
299
311
325
337
_mapreduce (f, op, :: IndexCartesian , A:: AbstractArray ) = mapfoldl (f, op, A)
326
338
327
339
mapreduce (f, op, A:: AbstractArray ) = _mapreduce (f, op, IndexStyle (A), A)
328
- mapreduce (f, op, a:: Number ) = f ( a)
340
+ mapreduce (f, op, a:: Number ) = mapreduce_single (f, op, a)
329
341
330
342
"""
331
343
reduce(op, v0, itr)
@@ -403,7 +415,7 @@ In the former case, the integers are widened to system word size and therefore
403
415
the result is 128. In the latter case, no such widening happens and integer
404
416
overflow results in -128.
405
417
"""
406
- sum (f:: Callable , a) = mapreduce (promote_sys_size_add ∘ f, + , a)
418
+ sum (f, a) = mapreduce (f, add_tosys , a)
407
419
408
420
"""
409
421
sum(itr)
@@ -419,7 +431,7 @@ julia> sum(1:20)
419
431
210
420
432
```
421
433
"""
422
- sum (a) = mapreduce (promote_sys_size_add, + , a)
434
+ sum (a) = sum (identity , a)
423
435
sum (a:: AbstractArray{Bool} ) = count (a)
424
436
425
437
# # prod
@@ -437,7 +449,7 @@ julia> prod(abs2, [2; 3; 4])
437
449
576
438
450
```
439
451
"""
440
- prod (f:: Callable , a) = mapreduce (promote_sys_size_mul ∘ f, * , a)
452
+ prod (f:: Callable , a) = mapreduce (f, mul_tosys , a)
441
453
442
454
"""
443
455
prod(itr)
@@ -453,7 +465,7 @@ julia> prod(1:20)
453
465
2432902008176640000
454
466
```
455
467
"""
456
- prod (a) = mapreduce (promote_sys_size_mul, * , a)
468
+ prod (a) = mapreduce (identity, mul_tosys , a)
457
469
458
470
# # maximum & minimum
459
471
0 commit comments