@@ -43,18 +43,6 @@ julia> mean(skipmissing([1, missing, 3]))
43
43
"""
44
44
mean (itr) = mean (identity, itr)
45
45
46
- struct Counter{F} <: Function
47
- f:: F
48
- n:: Base.RefValue{Int}
49
- end
50
- Counter (f:: F ) where {F} = Counter {F} (f, Ref (0 ))
51
- (f:: Counter )(x) = (f. n[] += 1 ; f. f (x))
52
-
53
- struct DivOne{F} <: Function
54
- f:: F
55
- end
56
- (f:: DivOne )(x) = f. f (x)/ 1
57
-
58
46
"""
59
47
mean(f, itr)
60
48
@@ -71,13 +59,23 @@ julia> mean([√1, √2, √3])
71
59
```
72
60
"""
73
61
function mean (f, itr)
74
- if Base. IteratorSize (itr) === Base. SizeUnknown ()
75
- g = Counter (DivOne (f))
76
- result = mapfoldl (g, add_mean, itr)
77
- return result/ g. n[]
78
- else
79
- return mapfoldl (DivOne (f), add_mean, itr)/ length (itr)
62
+ y = iterate (itr)
63
+ if y === nothing
64
+ return Base. mapreduce_empty_iter (f, + , itr,
65
+ Base. IteratorEltype (itr)) / 0
80
66
end
67
+ count = 1
68
+ value, state = y
69
+ f_value = f (value)/ 1
70
+ total = Base. reduce_first (+ , f_value)
71
+ y = iterate (itr, state)
72
+ while y != = nothing
73
+ value, state = y
74
+ total += _mean_promote (total, f (value))
75
+ count += 1
76
+ y = iterate (itr, state)
77
+ end
78
+ return total/ count
81
79
end
82
80
83
81
"""
@@ -182,24 +180,20 @@ mean(A::AbstractArray; dims=:) = _mean(identity, A, dims)
182
180
183
181
_mean_promote (x:: T , y:: S ) where {T,S} = convert (promote_type (T, S), y)
184
182
185
- add_mean (x, y) = Base. add_sum (x, _mean_promote (x, y))
186
-
187
- Base. reduce_empty (:: typeof (add_mean), T) = Base. reduce_empty (Base. add_sum, T)
188
- Base. mapreduce_empty (g:: DivOne , :: typeof (add_mean), T) = Base. mapreduce_empty (g. f, Base. add_sum, T)/ 1
189
- Base. mapreduce_empty (g:: Counter{<:DivOne} , :: typeof (add_mean), T) = Base. mapreduce_empty (g. f. f, Base. add_sum, T)/ 1
190
-
191
-
192
183
# ::Dims is there to force specializing on Colon (as it is a Function)
193
184
function _mean (f, A:: AbstractArray , dims:: Dims = :) where Dims
185
+ isempty (A) && return sum (f, A, dims= dims)/ 0
194
186
if dims === (:)
195
- result = mapreduce (DivOne (f), add_mean, A, dims= dims)
196
187
n = length (A)
188
+ else
189
+ n = mapreduce (i -> size (A, i), * , unique (dims); init= 1 )
190
+ end
191
+ x1 = f (first (A)) / 1
192
+ result = sum (x -> _mean_promote (x1, f (x)), A, dims= dims)
193
+ if dims === (:)
197
194
return result / n
198
195
else
199
- result = mapreduce (DivOne (f), add_mean, A, dims= dims)
200
- n = prod (i -> size (A, i), unique (dims); init= 1 )
201
- result ./= n
202
- return result
196
+ return result ./= n
203
197
end
204
198
end
205
199
0 commit comments