Skip to content

Commit 686b831

Browse files
committed
Cleanup of weights to reduce diff
1 parent f6a3ef3 commit 686b831

File tree

6 files changed

+629
-508
lines changed

6 files changed

+629
-508
lines changed

src/Statistics.jl

Lines changed: 1 addition & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Standard library module for basic statistics functionality.
88
module Statistics
99

1010
using LinearAlgebra, SparseArrays
11+
using LinearAlgebra: BlasReal
1112

1213
using Base: has_offset_axes, require_one_based_indexing
1314

@@ -44,7 +45,6 @@ export std, stdm, var, varm, mean!, mean,
4445

4546
include("common.jl")
4647
include("weights.jl")
47-
include("wsum.jl")
4848
include("moments.jl")
4949
include("scalarstats.jl")
5050
include("cov.jl")
@@ -186,9 +186,6 @@ function _mean!(R::AbstractArray, A::AbstractArray, weights::Nothing)
186186
return R
187187
end
188188

189-
_mean!(R::AbstractArray, A::AbstractArray, w::AbstractArray) =
190-
rmul!(wsum!(R, A, weights=w), inv(sum(w)))
191-
192189
"""
193190
mean(A::AbstractArray; [dims], [weights::AbstractArray])
194191
@@ -257,23 +254,6 @@ function _mean(::typeof(identity), r::AbstractRange{<:Real}, dims::Colon, weight
257254
(first(r) + last(r)) / 2
258255
end
259256

260-
# Note: weighted mean currently does not use _mean_promote to avoid overflow
261-
_mean(::typeof(identity), A::AbstractArray, dims::Colon, w::AbstractArray) =
262-
wsum(A, weights=w) / sum(w)
263-
264-
_mean(::typeof(identity), A::AbstractArray, dims, w::AbstractArray) =
265-
_mean!(Base.reducedim_init(t -> (t*zero(eltype(w)))/2, Base.add_sum, A, dims), A, w)
266-
267-
function _mean(::typeof(identity), A::AbstractArray, dims, w::UnitWeights)
268-
size(A, dims) != length(w) && throw(DimensionMismatch("Inconsistent array dimension."))
269-
return mean(A, dims=dims)
270-
end
271-
272-
function _mean(::typeof(identity), A::AbstractArray, dims::Colon, w::UnitWeights)
273-
length(A) != length(w) && throw(DimensionMismatch("Inconsistent array dimension."))
274-
return mean(A)
275-
end
276-
277257
##### variances #####
278258

279259
# faster computation of real(conj(x)*y)
@@ -1072,11 +1052,6 @@ _median(A::AbstractArray, dims, w::Nothing) = mapslices(median!, A, dims = dims)
10721052
_median(A::AbstractArray{T}, dims::Colon, w::Nothing) where {T} =
10731053
median!(copyto!(Array{T,1}(undef, length(A)), A))
10741054

1075-
_median(v::AbstractArray, dims::Colon, w::AbstractArray) = quantile(v, 0.5, weights=w)
1076-
1077-
_median(A::AbstractArray, dims, w::AbstractArray) =
1078-
throw(ArgumentError("weights and dims cannot be specified at the same time"))
1079-
10801055
"""
10811056
quantile!([q::AbstractArray, ] v::AbstractVector, p; sorted=false, alpha::Real=1.0, beta::Real=alpha)
10821057
@@ -1293,95 +1268,6 @@ _quantile(itr::AbstractArray, p, sorted::Bool, weights::Nothing) =
12931268
quantile!(sorted ? itr : Base.copymutable(itr), p; sorted=sorted,
12941269
alpha=alpha, beta=beta)
12951270

1296-
function _quantile(v::AbstractArray{V}, p, sorted::Bool, alpha::Real, beta::Real,
1297-
w::AbstractArray{W}) where {V,W}
1298-
# checks
1299-
alpha == beta == 1 || throw(ArgumentError("only alpha == beta == 1 is supported " *
1300-
"when weights are provided"))
1301-
isempty(v) && throw(ArgumentError("quantile of an empty array is undefined"))
1302-
isempty(p) && throw(ArgumentError("empty quantile array"))
1303-
all(x -> 0 <= x <= 1, p) || throw(ArgumentError("input probability out of [0,1] range"))
1304-
1305-
wsum = sum(w)
1306-
wsum == 0 && throw(ArgumentError("weight vector cannot sum to zero"))
1307-
size(v) == size(w) || throw(ArgumentError("weights must have the same dimension as data " *
1308-
"(got $(size(v)) and $(size(w)))"))
1309-
for x in w
1310-
isnan(x) && throw(ArgumentError("weight vector cannot contain NaN entries"))
1311-
x < 0 && throw(ArgumentError("weight vector cannot contain negative entries"))
1312-
end
1313-
1314-
isa(w, FrequencyWeights) && !(eltype(w) <: Integer) && any(!isinteger, w) &&
1315-
throw(ArgumentError("The values of the vector of `FrequencyWeights` must be numerically" *
1316-
"equal to integers. Use `ProbabilityWeights` or `AnalyticWeights` instead."))
1317-
1318-
# remove zeros weights and sort
1319-
nz = .!iszero.(w)
1320-
vw = sort!(collect(zip(view(v, nz), view(w, nz))))
1321-
N = length(vw)
1322-
1323-
# prepare percentiles
1324-
ppermute = sortperm(p)
1325-
p = p[ppermute]
1326-
1327-
# prepare out vector
1328-
out = Vector{typeof(zero(V)/1)}(undef, length(p))
1329-
fill!(out, vw[end][1])
1330-
1331-
@inbounds for x in v
1332-
isnan(x) && return fill!(out, x)
1333-
end
1334-
1335-
# loop on quantiles
1336-
Sk, Skold = zero(W), zero(W)
1337-
vk, vkold = zero(V), zero(V)
1338-
k = 0
1339-
1340-
w1 = vw[1][2]
1341-
for i in 1:length(p)
1342-
if isa(w, FrequencyWeights)
1343-
h = p[i] * (wsum - 1) + 1
1344-
else
1345-
h = p[i] * (wsum - w1) + w1
1346-
end
1347-
while Sk <= h
1348-
k += 1
1349-
if k > N
1350-
# out was initialized with maximum v
1351-
return out
1352-
end
1353-
Skold, vkold = Sk, vk
1354-
vk, wk = vw[k]
1355-
Sk += wk
1356-
end
1357-
if isa(w, FrequencyWeights)
1358-
out[ppermute[i]] = vkold + min(h - Skold, 1) * (vk - vkold)
1359-
else
1360-
out[ppermute[i]] = vkold + (h - Skold) / (Sk - Skold) * (vk - vkold)
1361-
end
1362-
end
1363-
return out
1364-
end
1365-
1366-
function _quantile(v::AbstractArray, p, sorted::Bool,
1367-
alpha::Real, beta::Real, w::UnitWeights)
1368-
length(v) != length(w) && throw(DimensionMismatch("Inconsistent array dimension."))
1369-
return quantile(v, p)
1370-
end
1371-
1372-
function _quantile(v::AbstractArray, p::Real, sorted::Bool,
1373-
alpha::Real, beta::Real, w::UnitWeights)
1374-
length(v) != length(w) && throw(DimensionMismatch("Inconsistent array dimension."))
1375-
return quantile(v, p)
1376-
end
1377-
1378-
_quantile(v::AbstractArray, p::Real, sorted::Bool, alpha::Real, beta::Real,
1379-
w::AbstractArray) =
1380-
_quantile(v, [p], sorted, alpha, beta, w)[1]
1381-
1382-
_quantile(itr, p, sorted::Bool, alpha::Real, beta::Real, weights) =
1383-
throw(ArgumentError("weights are only supported with AbstractArrays inputs"))
1384-
13851271
"""
13861272
quantile(x, n::Integer)
13871273

0 commit comments

Comments
 (0)