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,39 +268,42 @@ 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)
297
-
298
-
306
+ mapreduce_single (f, op, x) = f (reduce_single (op, x))
299
307
300
308
_mapreduce (f, op, A:: AbstractArray ) = _mapreduce (f, op, IndexStyle (A), A)
301
309
325
333
_mapreduce (f, op, :: IndexCartesian , A:: AbstractArray ) = mapfoldl (f, op, A)
326
334
327
335
mapreduce (f, op, A:: AbstractArray ) = _mapreduce (f, op, IndexStyle (A), A)
328
- mapreduce (f, op, a:: Number ) = f ( a)
336
+ mapreduce (f, op, a:: Number ) = mapreduce_single (f, op, a)
329
337
330
338
"""
331
339
reduce(op, v0, itr)
@@ -403,7 +411,7 @@ In the former case, the integers are widened to system word size and therefore
403
411
the result is 128. In the latter case, no such widening happens and integer
404
412
overflow results in -128.
405
413
"""
406
- sum (f:: Callable , a) = mapreduce (promote_sys_size_add ∘ f, + , a)
414
+ sum (f, a) = mapreduce (f, add_tosys , a)
407
415
408
416
"""
409
417
sum(itr)
@@ -419,7 +427,7 @@ julia> sum(1:20)
419
427
210
420
428
```
421
429
"""
422
- sum (a) = mapreduce (promote_sys_size_add, + , a)
430
+ sum (a) = sum (identity , a)
423
431
sum (a:: AbstractArray{Bool} ) = count (a)
424
432
425
433
# # prod
@@ -437,7 +445,7 @@ julia> prod(abs2, [2; 3; 4])
437
445
576
438
446
```
439
447
"""
440
- prod (f:: Callable , a) = mapreduce (promote_sys_size_mul ∘ f, * , a)
448
+ prod (f:: Callable , a) = mapreduce (f, mul_tosys , a)
441
449
442
450
"""
443
451
prod(itr)
@@ -453,7 +461,7 @@ julia> prod(1:20)
453
461
2432902008176640000
454
462
```
455
463
"""
456
- prod (a) = mapreduce (promote_sys_size_mul, * , a)
464
+ prod (a) = mapreduce (identity, mul_tosys , a)
457
465
458
466
# # maximum & minimum
459
467
0 commit comments