Skip to content

Commit

Permalink
add keyword arguments to var and std
Browse files Browse the repository at this point in the history
  • Loading branch information
lindahua committed Mar 23, 2014
1 parent a9949c6 commit 8f4d9da
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 22 deletions.
77 changes: 60 additions & 17 deletions base/statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,24 @@ end
median{T<:Real}(v::AbstractArray{T}; checknan::Bool=true) =
median!(vec(copy(v)), checknan=checknan)

## variance with known mean, using pairwise summation
function varm_pairwise(A::AbstractArray, m, i1,n) # see sum_pairwise
if n < 128

## variances

function varzm_pairwise(A::AbstractArray, i1::Int, n::Int)
if n < 256
@inbounds s = abs2(A[i1])
for i=i1+1:i1+n-1
@inbounds s += abs2(A[i])
end
return s
else
n2 = div(n,2)
return varzm_pairwise(A, i1, n2) + varzm_pairwise(A, i1+n2, n-n2)
end
end

function varm_pairwise(A::AbstractArray, m::Number, i1::Int, n::Int) # see sum_pairwise
if n < 256
@inbounds s = abs2(A[i1] - m)
for i = i1+1:i1+n-1
@inbounds s += abs2(A[i] - m)
Expand All @@ -57,16 +72,36 @@ function varm_pairwise(A::AbstractArray, m, i1,n) # see sum_pairwise
return varm_pairwise(A, m, i1, n2) + varm_pairwise(A, m, i1+n2, n-n2)
end
end
function varm(v::AbstractArray, m::Number)

function varzm(v::AbstractArray; corrected::Bool=true)
n = length(v)
if n == 0 || n == 1
return NaN
n == 0 && return NaN
return varzm_pairwise(v, 1, n) / (n - int(corrected))
end

function varm(v::AbstractArray, m::Number; corrected::Bool=true)
n = length(v)
n == 0 && return NaN
return varm_pairwise(v, m, 1, n) / (n - int(corrected))
end

var(v::AbstractArray; corrected::Bool=true, zeromean::Bool=false) =
zeromean ? varzm(v; corrected=corrected) : varm(v, mean(v); corrected=corrected)

function var(v::AbstractArray, region; corrected::Bool=true, zeromean::Bool=false)
cn = regionsize(v, region) - int(corrected)
if zeromean
return sum(abs2(v), region) / cn
else
return sum(abs2(v .- mean(v, region)), region) / cn
end
return varm_pairwise(v, m, 1,n) / (n - 1)
end


## variances over ranges

varm(v::Ranges, m::Number) = var(v)

## variance
function var(v::Ranges)
s = step(v)
l = length(v)
Expand All @@ -75,20 +110,28 @@ function var(v::Ranges)
end
return abs2(s) * (l + 1) * l / 12
end
var(v::AbstractArray) = varm(v, mean(v))
function var(v::AbstractArray, region)
x = v .- mean(v, region)
return sum(abs2(x), region) / (regionsize(v,region) - 1)

## standard deviation

function sqrt!(v::AbstractArray)
for i = 1:length(v)
v[i] = sqrt(v[i])
end
v
end

## standard deviation with known mean
stdm(v, m::Number) = sqrt(varm(v, m))
stdm(v::AbstractArray, m::Number; corrected::Bool=true) =
sqrt(varm(v, m; corrected=corrected))

std(v::AbstractArray; corrected::Bool=true, zeromean::Bool=false) =
sqrt(var(v; corrected=corrected, zeromean=zeromean))

std(v::AbstractArray, region; corrected::Bool=true, zeromean::Bool=false) =
sqrt!(var(v, region; corrected=corrected, zeromean=zeromean))

## standard deviation
std(v) = sqrt(var(v))
std(v, region) = sqrt(var(v, region))

## nice-valued ranges for histograms

function histrange{T<:FloatingPoint,N}(v::AbstractArray{T,N}, n::Integer)
if length(v) == 0
return Range(0.0,1.0,1)
Expand Down
25 changes: 20 additions & 5 deletions test/statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,27 @@
@test mean([1,2,3]) == 2.
@test mean([0 1 2; 4 5 6], 1) == [2. 3. 4.]
@test mean([1 2 3; 4 5 6], 1) == [2.5 3.5 4.5]
@test var([1,2,3]) == 1.

@test var(1:8) == 6.
@test var([1 2 3 4 5; 6 7 8 9 10], 2) == [2.5 2.5]'
@test varm([1,2,3], 2) == 1.
@test std([1,2,3]) == 1.
@test stdm([1,2,3], 2) == 1.

@test_approx_eq varm([1,2,3], 2) 1.
@test_approx_eq var([1,2,3]) 1.
@test_approx_eq var([1,2,3]; corrected=false) 2.0/3
@test_approx_eq var([1,2,3]; zeromean=true) 7.
@test_approx_eq var([1,2,3]; zeromean=true, corrected=false) 14.0/3

@test_approx_eq var([1 2 3 4 5; 6 7 8 9 10], 2) [2.5 2.5]'
@test_approx_eq var([1 2 3 4 5; 6 7 8 9 10], 2; corrected=false) [2.0 2.0]'

@test_approx_eq stdm([1,2,3], 2) 1.
@test_approx_eq std([1,2,3]) 1.
@test_approx_eq std([1,2,3]; corrected=false) sqrt(2.0/3)
@test_approx_eq std([1,2,3]; zeromean=true) sqrt(7.0)
@test_approx_eq std([1,2,3]; zeromean=true, corrected=false) sqrt(14.0/3)

@test_approx_eq std([1 2 3 4 5; 6 7 8 9 10], 2) sqrt([2.5 2.5]')
@test_approx_eq std([1 2 3 4 5; 6 7 8 9 10], 2; corrected=false) sqrt([2.0 2.0]')

@test sum(hist([1,2,3])[2]) == 3
@test hist([])[2] == []
@test hist([1])[2] == [1]
Expand Down

0 comments on commit 8f4d9da

Please sign in to comment.