Skip to content

Commit a8b8074

Browse files
authored
Add varfinite (#15)
Compute the variance using only finite values
1 parent 9264ea2 commit a8b8074

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

src/ImageBase.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export
1414
minfinite,
1515
maxfinite,
1616
maxabsfinite,
17-
meanfinite
17+
meanfinite,
18+
varfinite
1819

1920

2021
using Reexport

src/statistics.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,29 @@ else
6464
return s./n
6565
end
6666
end
67+
68+
"""
69+
varfinite(A; kwargs...)
70+
71+
Compute the variance of `A`, ignoring any non-finite values.
72+
73+
The supported `kwargs` are those of `sum(f, A; kwargs...)`.
74+
"""
75+
function varfinite end
76+
77+
if Base.VERSION >= v"1.1"
78+
function varfinite(A; kwargs...)
79+
m = meanfinite(A; kwargs...)
80+
n = sum(Map12(isfinite, x->true, x->false), A; kwargs...) # TODO: replace with `Returns`
81+
s = sum(Map12(isfinite, identity, zero), (A .- m).^2; kwargs...)
82+
return s ./ max.(0, (n .- 1))
83+
end
84+
else
85+
function varfinite(A; kwargs...)
86+
m = meanfinite(A; kwargs...)
87+
n = sum(Map12(isfinite, x->true, x->false).(A); kwargs...)
88+
s = sum(Map12(isfinite, identity, zero).((A .- m).^2); kwargs...)
89+
return s ./ max.(0, (n .- 1))
90+
end
91+
end
92+

test/statistics.jl

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,31 @@ using Test
99
img = colorview(RGB, PermutedDimsArray(A, (3,1,2)))
1010
s12 = sum(img, dims=(1,2))
1111
@test eltype(s12) <: RGB
12+
1213
A = [NaN, 1, 2, 3]
13-
@test meanfinite(A, 1) [2]
14+
@test meanfinite(A, dims=1) [2]
15+
@test varfinite(A, dims=1) [1]
16+
17+
A = [NaN NaN 1;
18+
1 2 3]
19+
vf = varfinite(A, dims=2)
20+
@test isnan(vf[1])
21+
1422
A = [NaN 1 2 3;
1523
NaN 6 5 4]
16-
mf = meanfinite(A, 1)
24+
mf = meanfinite(A, dims=1)
25+
vf = varfinite(A, dims=1)
1726
@test isnan(mf[1])
18-
@test mf[1,2:end] [3.5,3.5,3.5]
19-
@test meanfinite(A, 2) reshape([2, 5], 2, 1)
20-
@test meanfinite(A, (1,2)) [3.5]
27+
@test mf[2:end] [3.5,3.5,3.5]
28+
@test isnan(vf[1])
29+
@test vf[2:end] [12.5,4.5,0.5]
30+
31+
@test meanfinite(A, dims=2) reshape([2, 5], 2, 1)
32+
@test varfinite(A, dims=2) reshape([1, 1], 2, 1)
33+
34+
@test meanfinite(A, dims=(1,2)) [3.5]
35+
@test varfinite(A, dims=(1,2)) [3.5]
36+
2137
@test minfinite(A) == 1
2238
@test maxfinite(A) == 6
2339
@test maxabsfinite(A) == 6
@@ -29,7 +45,7 @@ using Test
2945
@test maxfinite(A) == maximum(A)
3046
A = rand(Float32,3,5,5)
3147
img = colorview(RGB, A)
32-
dc = meanfinite(img, 1)-reshape(reinterpretc(RGB{Float32}, mean(A, dims=2)), (1,5))
48+
dc = meanfinite(img, dims=1)-reshape(reinterpretc(RGB{Float32}, mean(A, dims=2)), (1,5))
3349
@test maximum(map(_abs, dc)) < 1e-6
3450
dc = minfinite(img)-RGB{Float32}(minimum(A, dims=(2,3))...)
3551
@test _abs(dc) < 1e-6

0 commit comments

Comments
 (0)