1
- # ##### Weight vector #####
1
+ # #### Weight vector #####
2
2
abstract type AbstractWeights{S<: Real , T<: Real , V<: AbstractVector{T} } <: AbstractVector{T} end
3
3
4
4
"""
@@ -18,12 +18,24 @@ macro weights(name)
18
18
end
19
19
20
20
length (wv:: AbstractWeights ) = length (wv. values)
21
- values (wv:: AbstractWeights ) = wv. values
22
21
sum (wv:: AbstractWeights ) = wv. sum
23
22
isempty (wv:: AbstractWeights ) = isempty (wv. values)
24
23
size (wv:: AbstractWeights ) = size (wv. values)
25
24
26
- Base. getindex (wv:: AbstractWeights , i) = getindex (wv. values, i)
25
+ Base. convert (:: Type{Vector} , wv:: AbstractWeights ) = convert (Vector, wv. values)
26
+
27
+ @propagate_inbounds function Base. getindex (wv:: AbstractWeights , i:: Integer )
28
+ @boundscheck checkbounds (wv, i)
29
+ @inbounds wv. values[i]
30
+ end
31
+
32
+ @propagate_inbounds function Base. getindex (wv:: W , i:: AbstractArray ) where W <: AbstractWeights
33
+ @boundscheck checkbounds (wv, i)
34
+ @inbounds v = wv. values[i]
35
+ W (v, sum (v))
36
+ end
37
+
38
+ Base. getindex (wv:: W , :: Colon ) where {W <: AbstractWeights } = W (copy (wv. values), sum (wv))
27
39
28
40
@propagate_inbounds function Base. setindex! (wv:: AbstractWeights , v:: Real , i:: Int )
29
41
s = v - wv[i]
@@ -247,7 +259,7 @@ eweights(n::Integer, λ::Real) = eweights(1:n, λ)
247
259
eweights (t:: AbstractVector , r:: AbstractRange , λ:: Real ) =
248
260
eweights (something .(indexin (t, r)), λ)
249
261
250
- # NOTE: No variance correction is implemented for exponential weights
262
+ # NOTE: no variance correction is implemented for exponential weights
251
263
252
264
struct UnitWeights{T<: Real } <: AbstractWeights{Int, T, V where V<:Vector{T}}
253
265
len:: Int
@@ -260,23 +272,24 @@ Construct a `UnitWeights` vector with length `s` and weight elements of type `T`
260
272
All weight elements are identically one.
261
273
""" UnitWeights
262
274
263
- values (wv:: UnitWeights{T} ) where T = fill (one (T), length (wv))
264
275
sum (wv:: UnitWeights{T} ) where T = convert (T, length (wv))
265
276
isempty (wv:: UnitWeights ) = iszero (wv. len)
266
277
length (wv:: UnitWeights ) = wv. len
267
278
size (wv:: UnitWeights ) = Tuple (length (wv))
268
279
280
+ Base. convert (:: Type{Vector} , wv:: UnitWeights{T} ) where {T} = ones (T, length (wv))
281
+
269
282
@propagate_inbounds function Base. getindex (wv:: UnitWeights{T} , i:: Integer ) where T
270
283
@boundscheck checkbounds (wv, i)
271
284
one (T)
272
285
end
273
286
274
287
@propagate_inbounds function Base. getindex (wv:: UnitWeights{T} , i:: AbstractArray{<:Int} ) where T
275
288
@boundscheck checkbounds (wv, i)
276
- fill ( one (T), size (i))
289
+ UnitWeights {T} ( length (i))
277
290
end
278
291
279
- Base. getindex (wv:: UnitWeights{T} , :: Colon ) where T = fill ( one (T), length (wv) )
292
+ Base. getindex (wv:: UnitWeights{T} , :: Colon ) where {T} = UnitWeights {T} (wv. len )
280
293
281
294
"""
282
295
uweights(s::Integer)
@@ -315,7 +328,7 @@ This definition is equivalent to the correction applied to unweighted data.
315
328
corrected ? (1 / (w. len - 1 )) : (1 / w. len)
316
329
end
317
330
318
- # #### Equality tests #####
331
+ # ### Equality tests #####
319
332
320
333
for w in (AnalyticWeights, FrequencyWeights, ProbabilityWeights, Weights)
321
334
@eval begin
@@ -341,22 +354,7 @@ Compute the weighted sum of an array `v` with weights `w`, optionally over the d
341
354
"""
342
355
wsum (v:: AbstractVector , w:: AbstractVector ) = dot (v, w)
343
356
wsum (v:: AbstractArray , w:: AbstractVector ) = dot (vec (v), w)
344
-
345
- # Note: the methods for BitArray and SparseMatrixCSC are to avoid ambiguities
346
- Base. sum (v:: BitArray , w:: AbstractWeights ) = wsum (v, values (w))
347
- Base. sum (v:: SparseArrays.SparseMatrixCSC , w:: AbstractWeights ) = wsum (v, values (w))
348
- Base. sum (v:: AbstractArray , w:: AbstractWeights ) = dot (v, values (w))
349
-
350
- for v in (AbstractArray{<: Number }, BitArray, SparseArrays. SparseMatrixCSC, AbstractArray)
351
- @eval begin
352
- function Base. sum (v:: $v , w:: UnitWeights )
353
- if length (v) != length (w)
354
- throw (DimensionMismatch (" Inconsistent array dimension." ))
355
- end
356
- return sum (v)
357
- end
358
- end
359
- end
357
+ wsum (v:: AbstractArray , w:: AbstractVector , dims:: Colon ) = wsum (v, w)
360
358
361
359
# # wsum along dimension
362
360
#
392
390
# (d) A is a general dense array with eltype <: BlasReal:
393
391
# dim <= 2: delegate to (a) and (b)
394
392
# otherwise, decompose A into multiple pages
395
- #
396
393
397
394
function _wsum1! (R:: AbstractArray , A:: AbstractVector , w:: AbstractVector , init:: Bool )
398
395
r = wsum (A, w)
@@ -455,7 +452,8 @@ function _wsumN!(R::StridedArray{T}, A::DenseArray{T,N}, w::StridedVector{T}, di
455
452
return R
456
453
end
457
454
458
- # General Cartesian-based weighted sum across dimensions
455
+ # # general Cartesian-based weighted sum across dimensions
456
+
459
457
@generated function _wsum_general! (R:: AbstractArray{RT} , f:: supertype (typeof (abs)),
460
458
A:: AbstractArray{T,N} , w:: AbstractVector{WT} , dim:: Int , init:: Bool ) where {T,RT,WT,N}
461
459
quote
512
510
end
513
511
end
514
512
515
-
516
513
# N = 1
517
514
_wsum! (R:: StridedArray{T} , A:: DenseArray{T,1} , w:: StridedVector{T} , dim:: Int , init:: Bool ) where {T<: BlasReal } =
518
515
_wsum1! (R, A, w, init)
@@ -533,7 +530,6 @@ _wsum!(R::AbstractArray, A::AbstractArray, w::AbstractVector, dim::Int, init::Bo
533
530
wsumtype (:: Type{T} , :: Type{W} ) where {T,W} = typeof (zero (T) * zero (W) + zero (T) * zero (W))
534
531
wsumtype (:: Type{T} , :: Type{T} ) where {T<: BlasReal } = T
535
532
536
-
537
533
"""
538
534
wsum!(R, A, w, dim; init=true)
539
535
@@ -559,19 +555,21 @@ function wsum(A::AbstractArray{<:Number}, w::UnitWeights, dim::Int)
559
555
return sum (A, dims= dim)
560
556
end
561
557
562
- # extended sum! and wsum
558
+ # # extended sum! and wsum
563
559
564
560
Base. sum! (R:: AbstractArray , A:: AbstractArray , w:: AbstractWeights{<:Real} , dim:: Int ; init:: Bool = true ) =
565
- wsum! (R, A, values (w) , dim; init= init)
561
+ wsum! (R, A, w , dim; init= init)
566
562
567
- Base. sum (A:: AbstractArray{<:Number} , w:: AbstractWeights{<:Real} , dim:: Int ) = wsum (A, values (w), dim)
563
+ Base. sum (A:: AbstractArray , w:: AbstractWeights{<:Real} ; dims:: Union{Colon,Int} = :) =
564
+ wsum (A, w, dims)
568
565
569
- function Base. sum (A:: AbstractArray{<:Number} , w:: UnitWeights , dim:: Int )
570
- size (A, dim) != length (w) && throw (DimensionMismatch (" Inconsistent array dimension." ))
571
- return sum (A, dims= dim)
566
+ function Base. sum (A:: AbstractArray , w:: UnitWeights ; dims:: Union{Colon,Int} = :)
567
+ a = (dims === :) ? length (A) : size (A, dims)
568
+ a != length (w) && throw (DimensionMismatch (" Inconsistent array dimension." ))
569
+ return sum (A, dims= dims)
572
570
end
573
571
574
- # ##### Weighted means #####
572
+ # #### Weighted means #####
575
573
576
574
"""
577
575
wmean(v, w::AbstractVector)
589
587
Compute the weighted mean of array `A` with weight vector `w`
590
588
(of type `AbstractWeights`) along dimension `dims`, and write results to `R`.
591
589
"""
592
- mean! (R:: AbstractArray , A:: AbstractArray , w:: AbstractWeights ;
593
- dims:: Union{Nothing,Int} = nothing ) = _mean! (R, A, w, dims)
594
- _mean! (R:: AbstractArray , A:: AbstractArray , w:: AbstractWeights , dims:: Nothing ) = throw (ArgumentError (" dims argument must be provided" ))
590
+ mean! (R:: AbstractArray , A:: AbstractArray , w:: AbstractWeights ; dims:: Union{Nothing,Int} = nothing ) =
591
+ _mean! (R, A, w, dims)
592
+ _mean! (R:: AbstractArray , A:: AbstractArray , w:: AbstractWeights , dims:: Nothing ) =
593
+ throw (ArgumentError (" dims argument must be provided" ))
595
594
_mean! (R:: AbstractArray , A:: AbstractArray , w:: AbstractWeights , dims:: Int ) =
596
595
rmul! (Base. sum! (R, A, w, dims), inv (sum (w)))
597
596
@@ -611,24 +610,21 @@ w = rand(n)
611
610
mean(x, weights(w))
612
611
```
613
612
"""
614
- mean (A:: AbstractArray , w:: AbstractWeights ; dims:: Union{Nothing ,Int} = nothing ) =
613
+ mean (A:: AbstractArray , w:: AbstractWeights ; dims:: Union{Colon ,Int} = : ) =
615
614
_mean (A, w, dims)
616
- _mean (A:: AbstractArray , w:: AbstractWeights , dims:: Nothing ) =
615
+ _mean (A:: AbstractArray , w:: AbstractWeights , dims:: Colon ) =
617
616
sum (A, w) / sum (w)
618
617
_mean (A:: AbstractArray{T} , w:: AbstractWeights{W} , dims:: Int ) where {T,W} =
619
618
_mean! (similar (A, wmeantype (T, W), Base. reduced_indices (axes (A), dims)), A, w, dims)
620
619
621
- function _mean (A:: AbstractArray , w:: UnitWeights , dims:: Nothing )
622
- length (A) != length (w) && throw (DimensionMismatch (" Inconsistent array dimension." ))
623
- return mean (A)
624
- end
625
-
626
- function _mean (A:: AbstractArray , w:: UnitWeights , dims:: Int )
627
- size (A, dims) != length (w) && throw (DimensionMismatch (" Inconsistent array dimension." ))
620
+ function mean (A:: AbstractArray , w:: UnitWeights ; dims:: Union{Colon,Int} = :)
621
+ a = (dims === :) ? length (A) : size (A, dims)
622
+ a != length (w) && throw (DimensionMismatch (" Inconsistent array dimension." ))
628
623
return mean (A, dims= dims)
629
624
end
630
625
631
- # ##### Weighted quantile #####
626
+ # #### Weighted quantile #####
627
+
632
628
"""
633
629
quantile(v, w::AbstractWeights, p)
634
630
723
719
724
720
quantile (v:: RealVector , w:: AbstractWeights{<:Real} , p:: Number ) = quantile (v, w, [p])[1 ]
725
721
722
+ # #### Weighted median #####
726
723
727
-
728
- # ##### Weighted median #####
729
724
"""
730
725
median(v::RealVector, w::AbstractWeights)
731
726
0 commit comments