Skip to content

Commit 16b13d2

Browse files
committed
Merge remote-tracking branch 'origin/teh/reduce_init' into sum-init
2 parents a9fd8b8 + ed1cfc9 commit 16b13d2

File tree

4 files changed

+63
-25
lines changed

4 files changed

+63
-25
lines changed

base/reduce.jl

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ function mapfoldl_impl(f::F, op::OP, nt, itr) where {F,OP}
4545
end
4646

4747
function foldl_impl(op::OP, nt, itr) where {OP}
48-
v = _foldl_impl(op, get(nt, :init, _InitialValue()), itr)
48+
v = _foldl_impl(op, nt, itr)
4949
v isa _InitialValue && return reduce_empty_iter(op, itr)
5050
return v
5151
end
@@ -157,7 +157,7 @@ Like [`mapreduce`](@ref), but with guaranteed left associativity, as in [`foldl`
157157
If provided, the keyword argument `init` will be used exactly once. In general, it will be
158158
necessary to provide `init` to work with empty collections.
159159
"""
160-
mapfoldl(f, op, itr; kw...) = mapfoldl_impl(f, op, kw.data, itr)
160+
mapfoldl(f, op, itr; init=_InitialValue()) = mapfoldl_impl(f, op, init, itr)
161161

162162
"""
163163
foldl(op, itr; [init])
@@ -200,7 +200,7 @@ Like [`mapreduce`](@ref), but with guaranteed right associativity, as in [`foldr
200200
provided, the keyword argument `init` will be used exactly once. In general, it will be
201201
necessary to provide `init` to work with empty collections.
202202
"""
203-
mapfoldr(f, op, itr; kw...) = mapfoldr_impl(f, op, kw.data, itr)
203+
mapfoldr(f, op, itr; init=_InitialValue()) = mapfoldr_impl(f, op, init, itr)
204204

205205

206206
"""
@@ -640,35 +640,47 @@ function mapreduce_impl(f, op::Union{typeof(max), typeof(min)},
640640
end
641641

642642
"""
643-
maximum(f, itr)
643+
maximum(f, itr; [init])
644644
645645
Returns the largest result of calling function `f` on each element of `itr`.
646+
If provided, `init` must be a neutral element for `max` that will be returned
647+
for empty collections.
646648
647649
# Examples
648650
```jldoctest
649651
julia> maximum(length, ["Julion", "Julia", "Jule"])
650652
6
653+
654+
julia> maximum(length, []; init=-1)
655+
-1
651656
```
652657
"""
653-
maximum(f, a) = mapreduce(f, max, a)
658+
maximum(f, a; kw...) = mapreduce(f, max, a; kw...)
654659

655660
"""
656-
minimum(f, itr)
661+
minimum(f, itr; [init])
657662
658663
Returns the smallest result of calling function `f` on each element of `itr`.
664+
If provided, `init` must be a neutral element for `min` that will be returned
665+
for empty collections.
659666
660667
# Examples
661668
```jldoctest
662669
julia> minimum(length, ["Julion", "Julia", "Jule"])
663670
4
671+
672+
julia> minimum(length, []; init=-1)
673+
-1
664674
```
665675
"""
666-
minimum(f, a) = mapreduce(f, min, a)
676+
minimum(f, a; kw...) = mapreduce(f, min, a; kw...)
667677

668678
"""
669-
maximum(itr)
679+
maximum(itr; [init])
670680
671681
Returns the largest element in a collection.
682+
If provided, `init` must be a neutral element for `max` that will be returned
683+
for empty collections.
672684
673685
# Examples
674686
```jldoctest
@@ -677,14 +689,24 @@ julia> maximum(-20.5:10)
677689
678690
julia> maximum([1,2,3])
679691
3
692+
693+
julia> maximum(())
694+
ERROR: ArgumentError: reducing over an empty collection is not allowed
695+
Stacktrace:
696+
[...]
697+
698+
julia> maximum((); init=-1)
699+
-1
680700
```
681701
"""
682-
maximum(a) = mapreduce(identity, max, a)
702+
maximum(a; kw...) = mapreduce(identity, max, a; kw...)
683703

684704
"""
685-
minimum(itr)
705+
minimum(itr; [init])
686706
687707
Returns the smallest element in a collection.
708+
If provided, `init` must be a neutral element for `min` that will be returned
709+
for empty collections.
688710
689711
# Examples
690712
```jldoctest
@@ -693,9 +715,17 @@ julia> minimum(-20.5:10)
693715
694716
julia> minimum([1,2,3])
695717
1
718+
719+
julia> minimum([])
720+
ERROR: ArgumentError: reducing over an empty collection is not allowed
721+
Stacktrace:
722+
[...]
723+
724+
julia> minimum([]; init=-1)
725+
-1
696726
```
697727
"""
698-
minimum(a) = mapreduce(identity, min, a)
728+
minimum(a; kw...) = mapreduce(identity, min, a; kw...)
699729

700730
## all & any
701731

base/reducedim.jl

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -307,21 +307,21 @@ julia> mapreduce(isodd, |, a, dims=1)
307307
1 1 1 1
308308
```
309309
"""
310-
mapreduce(f, op, A::AbstractArrayOrBroadcasted; dims=:, kw...) =
311-
_mapreduce_dim(f, op, kw.data, A, dims)
310+
mapreduce(f, op, A::AbstractArrayOrBroadcasted; dims=:, init=_InitialValue()) =
311+
_mapreduce_dim(f, op, init, A, dims)
312312
mapreduce(f, op, A::AbstractArrayOrBroadcasted...; kw...) =
313313
reduce(op, map(f, A...); kw...)
314314

315-
_mapreduce_dim(f, op, nt::NamedTuple{(:init,)}, A::AbstractArrayOrBroadcasted, ::Colon) =
316-
mapfoldl(f, op, A; nt...)
315+
_mapreduce_dim(f, op, nt, A::AbstractArrayOrBroadcasted, ::Colon) =
316+
mapfoldl_impl(f, op, nt, A)
317317

318-
_mapreduce_dim(f, op, ::NamedTuple{()}, A::AbstractArrayOrBroadcasted, ::Colon) =
318+
_mapreduce_dim(f, op, ::_InitialValue, A::AbstractArrayOrBroadcasted, ::Colon) =
319319
_mapreduce(f, op, IndexStyle(A), A)
320320

321-
_mapreduce_dim(f, op, nt::NamedTuple{(:init,)}, A::AbstractArrayOrBroadcasted, dims) =
322-
mapreducedim!(f, op, reducedim_initarray(A, dims, nt.init), A)
321+
_mapreduce_dim(f, op, nt, A::AbstractArrayOrBroadcasted, dims) =
322+
mapreducedim!(f, op, reducedim_initarray(A, dims, nt), A)
323323

324-
_mapreduce_dim(f, op, ::NamedTuple{()}, A::AbstractArrayOrBroadcasted, dims) =
324+
_mapreduce_dim(f, op, ::_InitialValue, A::AbstractArrayOrBroadcasted, dims) =
325325
mapreducedim!(f, op, reducedim_init(f, op, A, dims), A)
326326

327327
"""
@@ -717,12 +717,12 @@ for (fname, _fname, op) in [(:sum, :_sum, :add_sum), (:prod, :_prod,
717717
(:maximum, :_maximum, :max), (:minimum, :_minimum, :min)]
718718
@eval begin
719719
# User-facing methods with keyword arguments
720-
@inline ($fname)(a::AbstractArray; dims=:) = ($_fname)(a, dims)
721-
@inline ($fname)(f, a::AbstractArray; dims=:) = ($_fname)(f, a, dims)
720+
@inline ($fname)(a::AbstractArray; dims=:, kw...) = ($_fname)(a, dims; kw...)
721+
@inline ($fname)(f, a::AbstractArray; dims=:, kw...) = ($_fname)(f, a, dims; kw...)
722722

723723
# Underlying implementations using dispatch
724-
($_fname)(a, ::Colon) = ($_fname)(identity, a, :)
725-
($_fname)(f, a, ::Colon) = mapreduce(f, $op, a)
724+
($_fname)(a, ::Colon; kw...) = ($_fname)(identity, a, :; kw...)
725+
($_fname)(f, a, ::Colon; kw...) = mapreduce(f, $op, a; kw...)
726726
end
727727
end
728728

@@ -743,8 +743,8 @@ for (fname, op) in [(:sum, :add_sum), (:prod, :mul_prod),
743743
mapreducedim!(f, $(op), initarray!(r, $(op), init, A), A)
744744
$(fname!)(r::AbstractArray, A::AbstractArray; init::Bool=true) = $(fname!)(identity, r, A; init=init)
745745

746-
$(_fname)(A, dims) = $(_fname)(identity, A, dims)
747-
$(_fname)(f, A, dims) = mapreduce(f, $(op), A, dims=dims)
746+
$(_fname)(A, dims; kw...) = $(_fname)(identity, A, dims; kw...)
747+
$(_fname)(f, A, dims; kw...) = mapreduce(f, $(op), A; dims=dims, kw...)
748748
end
749749
end
750750

test/reduce.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ prod2(itr) = invoke(prod, Tuple{Any}, itr)
211211
@test_throws ArgumentError maximum(Int[])
212212
@test_throws ArgumentError minimum(Int[])
213213

214+
@test maximum(Int[]; init=-1) == -1
215+
@test minimum(Int[]; init=-1) == -1
216+
214217
@test maximum(5) == 5
215218
@test minimum(5) == 5
216219
@test extrema(5) == (5, 5)

test/reducedim.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ safe_minabs(A::Array{T}, region) where {T} = safe_mapslices(minimum, abs.(A), re
7575
@test @inferred(count(!, Breduc, dims=region)) safe_count(.!Breduc, region)
7676
end
7777

78+
# Combining dims and init
79+
A = Array{Int}(undef, 0, 3)
80+
@test_throws ArgumentError maximum(A; dims=1)
81+
@test maximum(A; dims=1, init=-1) == reshape([-1,-1,-1], 1, 3)
82+
7883
# Test reduction along first dimension; this is special-cased for
7984
# size(A, 1) >= 16
8085
Breduc = rand(64, 3)

0 commit comments

Comments
 (0)