Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare standalone package, step 2 #128

Merged
merged 5 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
keywords = ["statistics"]
license = "MIT"
desc = "Basic statistics for Julia."
version = "1.9.0"
version = "1.11.0"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
2 changes: 0 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ var
varm
cor
cov
mean!
mean
median!
median
middle
Expand Down
318 changes: 160 additions & 158 deletions src/Statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,189 +16,189 @@ export cor, cov, std, stdm, var, varm, mean!, mean,

##### mean #####

"""
mean(itr)

Compute the mean of all elements in a collection.

!!! note
If `itr` contains `NaN` or [`missing`](@ref) values, the result is also
`NaN` or `missing` (`missing` takes precedence if array contains both).
Use the [`skipmissing`](@ref) function to omit `missing` entries and compute the
mean of non-missing values.

# Examples
```jldoctest
julia> using Statistics

julia> mean(1:20)
10.5

julia> mean([1, missing, 3])
missing

julia> mean(skipmissing([1, missing, 3]))
2.0
```
"""
mean(itr) = mean(identity, itr)

"""
mean(f, itr)

Apply the function `f` to each element of collection `itr` and take the mean.

```jldoctest
julia> using Statistics

julia> mean(√, [1, 2, 3])
1.3820881233139908

julia> mean([√1, √2, √3])
1.3820881233139908
```
"""
function mean(f, itr)
y = iterate(itr)
if y === nothing
return Base.mapreduce_empty_iter(f, +, itr,
Base.IteratorEltype(itr)) / 0
end
count = 1
value, state = y
f_value = f(value)/1
total = Base.reduce_first(+, f_value)
y = iterate(itr, state)
while y !== nothing
if !isdefined(Base, :mean)
"""
mean(itr)

Compute the mean of all elements in a collection.

!!! note
If `itr` contains `NaN` or [`missing`](@ref) values, the result is also
`NaN` or `missing` (`missing` takes precedence if array contains both).
Use the [`skipmissing`](@ref) function to omit `missing` entries and compute the
mean of non-missing values.

# Examples
```jldoctest
julia> using Statistics

julia> mean(1:20)
10.5

julia> mean([1, missing, 3])
missing

julia> mean(skipmissing([1, missing, 3]))
2.0
```
"""
mean(itr) = mean(identity, itr)

"""
mean(f, itr)

Apply the function `f` to each element of collection `itr` and take the mean.

```jldoctest
julia> using Statistics

julia> mean(√, [1, 2, 3])
1.3820881233139908

julia> mean([√1, √2, √3])
1.3820881233139908
```
"""
function mean(f, itr)
y = iterate(itr)
if y === nothing
return Base.mapreduce_empty_iter(f, +, itr,
Base.IteratorEltype(itr)) / 0
end
count = 1
value, state = y
total += _mean_promote(total, f(value))
count += 1
f_value = f(value)/1
total = Base.reduce_first(+, f_value)
y = iterate(itr, state)
while y !== nothing
value, state = y
total += _mean_promote(total, f(value))
count += 1
y = iterate(itr, state)
end
return total/count
end
return total/count
end

"""
mean(f, A::AbstractArray; dims)

Apply the function `f` to each element of array `A` and take the mean over dimensions `dims`.

!!! compat "Julia 1.3"
This method requires at least Julia 1.3.
"""
mean(f, A::AbstractArray; dims)

```jldoctest
julia> using Statistics
Apply the function `f` to each element of array `A` and take the mean over dimensions `dims`.

julia> mean(√, [1, 2, 3])
1.3820881233139908
!!! compat "Julia 1.3"
This method requires at least Julia 1.3.

julia> mean([√1, √2, √3])
1.3820881233139908
```jldoctest
julia> using Statistics

julia> mean(√, [1 2 3; 4 5 6], dims=2)
2×1 Matrix{Float64}:
1.3820881233139908
2.2285192400943226
```
"""
mean(f, A::AbstractArray; dims=:) = _mean(f, A, dims)

function mean(f::Number, itr::Number)
f_value = try
f(itr)
catch MethodError
rethrow(ArgumentError("""mean(f, itr) requires a function and an iterable.
Perhaps you meant middle(x, y)?""",))
end
Base.reduce_first(+, f_value)/1
end
julia> mean(√, [1, 2, 3])
1.3820881233139908

"""
mean!(r, v)

Compute the mean of `v` over the singleton dimensions of `r`, and write results to `r`.
julia> mean([√1, √2, √3])
1.3820881233139908

# Examples
```jldoctest
julia> using Statistics
julia> mean(√, [1 2 3; 4 5 6], dims=2)
2×1 Matrix{Float64}:
1.3820881233139908
2.2285192400943226
```
"""
mean(f, A::AbstractArray; dims=:) = _mean(f, A, dims)

julia> v = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4

julia> mean!([1., 1.], v)
2-element Vector{Float64}:
1.5
3.5
function mean(f::Number, itr::Number)
f_value = try
f(itr)
catch MethodError
rethrow(ArgumentError("""mean(f, itr) requires a function and an iterable.
Perhaps you meant middle(x, y)?""",))
end
Base.reduce_first(+, f_value)/1
end

julia> mean!([1. 1.], v)
1×2 Matrix{Float64}:
2.0 3.0
```
"""
function mean!(R::AbstractArray, A::AbstractArray)
sum!(R, A; init=true)
x = max(1, length(R)) // length(A)
R .= R .* x
return R
end
"""
mean!(r, v)

Compute the mean of `v` over the singleton dimensions of `r`, and write results to `r`.

# Examples
```jldoctest
julia> using Statistics

julia> v = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4

julia> mean!([1., 1.], v)
2-element Vector{Float64}:
1.5
3.5

julia> mean!([1. 1.], v)
1×2 Matrix{Float64}:
2.0 3.0
```
"""
function mean!(R::AbstractArray, A::AbstractArray)
sum!(R, A; init=true)
x = max(1, length(R)) // length(A)
R .= R .* x
return R
end

"""
mean(A::AbstractArray; dims)
"""
mean(A::AbstractArray; dims)

Compute the mean of an array over the given dimensions.
Compute the mean of an array over the given dimensions.

!!! compat "Julia 1.1"
`mean` for empty arrays requires at least Julia 1.1.
!!! compat "Julia 1.1"
`mean` for empty arrays requires at least Julia 1.1.

# Examples
```jldoctest
julia> using Statistics
# Examples
```jldoctest
julia> using Statistics

julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4

julia> mean(A, dims=1)
1×2 Matrix{Float64}:
2.0 3.0
julia> mean(A, dims=1)
1×2 Matrix{Float64}:
2.0 3.0

julia> mean(A, dims=2)
2×1 Matrix{Float64}:
1.5
3.5
```
"""
mean(A::AbstractArray; dims=:) = _mean(identity, A, dims)
julia> mean(A, dims=2)
2×1 Matrix{Float64}:
1.5
3.5
```
"""
mean(A::AbstractArray; dims=:) = _mean(identity, A, dims)

_mean_promote(x::T, y::S) where {T,S} = convert(promote_type(T, S), y)
_mean_promote(x::T, y::S) where {T,S} = convert(promote_type(T, S), y)

# ::Dims is there to force specializing on Colon (as it is a Function)
function _mean(f, A::AbstractArray, dims::Dims=:) where Dims
isempty(A) && return sum(f, A, dims=dims)/0
if dims === (:)
n = length(A)
else
n = mapreduce(i -> size(A, i), *, unique(dims); init=1)
end
x1 = f(first(A)) / 1
result = sum(x -> _mean_promote(x1, f(x)), A, dims=dims)
if dims === (:)
return result / n
else
return result ./= n
# ::Dims is there to force specializing on Colon (as it is a Function)
function _mean(f, A::AbstractArray, dims::Dims=:) where Dims
isempty(A) && return sum(f, A, dims=dims)/0
if dims === (:)
n = length(A)
else
n = mapreduce(i -> size(A, i), *, unique(dims); init=1)
end
x1 = f(first(A)) / 1
result = sum(x -> _mean_promote(x1, f(x)), A, dims=dims)
if dims === (:)
return result / n
else
return result ./= n
end
end
end

function mean(r::AbstractRange{<:Real})
isempty(r) && return oftype((first(r) + last(r)) / 2, NaN)
(first(r) + last(r)) / 2
function mean(r::AbstractRange{<:Real})
isempty(r) && return oftype((first(r) + last(r)) / 2, NaN)
(first(r) + last(r)) / 2
end
end

median(r::AbstractRange{<:Real}) = mean(r)

##### variances #####

# faster computation of real(conj(x)*y)
Expand Down Expand Up @@ -877,6 +877,8 @@ _median(v::AbstractArray, dims) = mapslices(median!, v, dims = dims)

_median(v::AbstractArray{T}, ::Colon) where {T} = median!(copyto!(Array{T,1}(undef, length(v)), v))

median(r::AbstractRange{<:Real}) = mean(r)

"""
quantile!([q::AbstractArray, ] v::AbstractVector, p; sorted=false, alpha::Real=1.0, beta::Real=alpha)

Expand Down