11module StaticArraysStatisticsExt
22
3- import Statistics: mean
3+ import Statistics: mean, median
4+
5+ using Base. Order: Forward, ord
6+ using Statistics: median!, middle
47
58using StaticArrays
6- using StaticArrays: _InitialValue, _reduce, _mapreduce
9+ using StaticArrays: BitonicSort, _InitialValue, _reduce, _mapreduce, _bitonic_sort_limit, _sort
710
811_mean_denom (a, :: Colon ) = length (a)
912_mean_denom (a, dims:: Int ) = size (a, dims)
@@ -12,4 +15,37 @@ _mean_denom(a, ::Val{D}) where {D} = size(a, D)
1215@inline mean (a:: StaticArray ; dims= :) = _reduce (+ , a, dims) / _mean_denom (a, dims)
1316@inline mean (f:: Function , a:: StaticArray ; dims= :) = _mapreduce (f, + , dims, _InitialValue (), Size (a), a) / _mean_denom (a, dims)
1417
18+ @inline function median (a:: StaticArray ; dims = :)
19+ if dims == Colon ()
20+ median (vec (a))
21+ else
22+ # FIXME : Implement `mapslices` correctly on `StaticArray` to remove
23+ # this fallback.
24+ median (Array (a); dims)
25+ end
26+ end
27+
28+ @inline function median (a:: StaticVector )
29+ (isimmutable (a) && length (a) <= _bitonic_sort_limit) ||
30+ return median! (Base. copymutable (a))
31+
32+ # following Statistics.median
33+ isempty (a) &&
34+ throw (ArgumentError (" median of empty vector is undefined, $(repr (a)) " ))
35+ eltype (a) >: Missing && any (ismissing, a) &&
36+ return missing
37+ nanix = findfirst (x -> x isa Number && isnan (x), a)
38+ isnothing (nanix) ||
39+ return a[nanix]
40+
41+ order = ord (isless, identity, nothing , Forward)
42+ sa = _sort (Tuple (a), BitonicSort, order)
43+
44+ n = length (a)
45+ # sa is 1-indexed
46+ return isodd (n) ?
47+ middle (sa[n ÷ 2 + 1 ]) :
48+ middle (sa[n ÷ 2 ], sa[n ÷ 2 + 1 ])
49+ end
50+
1551end # module
0 commit comments