Skip to content

Commit 93362bf

Browse files
authored
Multidimensional probabilities (#241)
* Increase allowed lower deviation for some DiffEntEsts with negative bias * Probabilities subtype AbstractArray instead of AbstractVector * `fasthist` only works on vectors, so adjust docstring * Update changelog * Set package version to 2.1
1 parent 6f1f0ff commit 93362bf

File tree

8 files changed

+30
-27
lines changed

8 files changed

+30
-27
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Changelog is kept with respect to version 0.11 of Entropies.jl. From version v2.
66

77
- Added `Gao` estimator for differential Shannon entropy.
88
- Added `Lord` estimator for differential Shannon entropy.
9+
- `Probabilities` now wraps `AbstractArray{T, N}` instead of `AbstractVector{T}`, so that it can also represent multidimensional probability mass functions. For vectors, it behaves as before.
910

1011
## 2.0
1112

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "ComplexityMeasures"
22
uuid = "ab4b797d-85ee-42ba-b621-05d793b346a2"
33
authors = "Kristian Agasøster Haaga <kahaaga@gmail.com>, George Datseries <datseris.george@gmail.com>"
44
repo = "https://github.com/juliadynamics/ComplexityMeasures.jl.git"
5-
version = "2.0.0"
5+
version = "2.1.0"
66

77
[deps]
88
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"

src/probabilities.jl

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,36 @@ export outcome_space
99
# Types
1010
###########################################################################################
1111
"""
12-
Probabilities <: AbstractVector
12+
Probabilities <: AbstractArray
1313
Probabilities(x) → p
1414
15-
`Probabilities` is a simple wrapper around `x::AbstractVector{<:Real}` that ensures its
16-
values sum to 1, so that `p` can be interpreted as probability mass function.
15+
`Probabilities` is a simple wrapper around `x::AbstractArray{<:Real, N}` that ensures its
16+
values sum to 1, so that `p` can be interpreted as `N`-dimensional probability mass
17+
function. In most use cases, `p` will be a vector.
1718
"""
18-
struct Probabilities{T} <: AbstractVector{T}
19-
p::Vector{T}
20-
function Probabilities(x::AbstractVector{T}, normed = false) where T <: Real
19+
struct Probabilities{T, N} <: AbstractArray{T, N}
20+
p::Array{T, N}
21+
function Probabilities(x::AbstractArray{T, N}, normed = false) where {T <: Real, N}
2122
if !normed # `normed` is an internal argument that skips checking the sum.
22-
s = sum(x)
23+
s = sum(x, dims = 1:N)
2324
if s 1
2425
x = x ./ s
2526
end
2627
end
27-
return new{T}(x)
28+
return new{T, N}(x)
2829
end
2930
end
30-
function Probabilities(x::AbstractVector{<:Integer})
31+
function Probabilities(x::AbstractArray{<:Integer, N}) where N
3132
s = sum(x)
3233
return Probabilities(x ./ s, true)
3334
end
3435

35-
# extend base Vector interface:
36+
# extend base Array interface:
3637
for f in (:length, :size, :eachindex, :eltype, :parent,
3738
:lastindex, :firstindex, :vec, :getindex, :iterate)
3839
@eval Base.$(f)(d::Probabilities, args...) = $(f)(d.p, args...)
3940
end
41+
4042
Base.IteratorSize(::Probabilities) = Base.HasLength()
4143
# Special extension due to the rules of the API
4244
@inline Base.sum(::Probabilities{T}) where T = one(T)
@@ -96,7 +98,7 @@ contain `0`s as entries or not depends on the estimator.
9698
E.g., in [`ValueHistogram`](@ref) `0`s are skipped, while in
9799
[`SymbolicPermutation`](@ref) `0` are not, because we get them for free.
98100
99-
probabilities(x::Array_or_Dataset) → p::Probabilities
101+
probabilities(x::Vector_or_Dataset) → p::Probabilities
100102
101103
Estimate probabilities by directly counting the elements of `x`, assuming that
102104
`Ω = sort(unique(x))`, i.e. that the outcome space is the unique elements of `x`.

test/entropies/estimators/alizadeharghami.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ ea = entropy(Shannon(), AlizadehArghami(m = 100), rand(npts))
1313
ea_n = entropy(Shannon(; base = ℯ), AlizadehArghami(m = 100), randn(npts))
1414
ea_n3 = entropy(Shannon(; base = 3), AlizadehArghami(m = 100), randn(npts))
1515

16-
@test U - max(0.01, U*0.03) ea U + max(0.01, U*0.03)
17-
@test N * 0.98 ea_n N * 1.02
18-
@test N_base3 * 0.98 ea_n3 N_base3 * 1.02
16+
@test U - max(0.02, U*0.03) ea U + max(0.01, U*0.03)
17+
@test N * 0.96 ea_n N * 1.02
18+
@test N_base3 * 0.96 ea_n3 N_base3 * 1.02
1919

2020
x = rand(1000)
2121
@test_throws ArgumentError entropy(Renyi(q = 2), AlizadehArghami(), x)

test/entropies/estimators/correa.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ ea = entropy(Shannon(), Correa(m = 100), rand(npts))
1313
ea_n = entropy(Shannon(; base = ℯ), Correa(m = 100), randn(npts))
1414
ea_n3 = entropy(Shannon(; base = 3), Correa(m = 100), randn(npts))
1515

16-
@test U - max(0.01, U*0.03) ea U + max(0.01, U*0.03)
17-
@test N * 0.98 ea_n N * 1.02
18-
@test N_base3 * 0.98 ea_n3 N_base3 * 1.02
16+
@test U - max(0.02, U*0.03) ea U + max(0.01, U*0.03)
17+
@test N * 0.96 ea_n N * 1.02
18+
@test N_base3 * 0.96 ea_n3 N_base3 * 1.02
1919

2020
x = rand(1000)
2121
@test_throws ArgumentError entropy(Renyi(q = 2), Correa(), x)

test/entropies/estimators/ebrahimi.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ ea = entropy(Shannon(), Ebrahimi(m = 100), rand(npts))
1313
ea_n = entropy(Shannon(; base = ℯ), Ebrahimi(m = 100), randn(npts))
1414
ea_n3 = entropy(Shannon(; base = 3), Ebrahimi(m = 100), randn(npts))
1515

16-
@test U - max(0.01, U*0.03) ea U + max(0.01, U*0.03)
17-
@test N * 0.98 ea_n N * 1.02
18-
@test N_base3 * 0.98 ea_n3 N_base3 * 1.02
16+
@test U - max(0.02, U*0.03) ea U + max(0.01, U*0.03)
17+
@test N * 0.96 ea_n N * 1.02
18+
@test N_base3 * 0.96 ea_n3 N_base3 * 1.02
1919

2020
x = rand(1000)
2121
@test_throws ArgumentError entropy(Renyi(q = 2), Ebrahimi(), x)

test/entropies/estimators/lord.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ ea = entropy(Shannon(), Lord(k = 20), rand(npts))
1313
ea_n = entropy(Shannon(; base = ℯ), Lord(k = 20), randn(npts))
1414
ea_n3 = entropy(Shannon(; base = 3), Lord(k = 20), randn(npts))
1515

16-
@test U - max(0.03, U*0.03) ea U + max(0.03, U*0.03)
17-
@test N * 0.97 ea_n N * 1.03
18-
@test N_base3 * 0.98 ea_n3 N_base3 * 1.02
16+
@test U - max(0.05, U*0.03) ea U + max(0.03, U*0.03)
17+
@test N * 0.96 ea_n N * 1.03
18+
@test N_base3 * 0.96 ea_n3 N_base3 * 1.03
1919

2020
x = rand(1000)
2121
@test_throws ArgumentError entropy(Renyi(q = 2), Lord(), x)

test/entropies/estimators/vasicek.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ ea = entropy(Shannon(), Vasicek(m = 100), rand(npts))
1414
ea_n = entropy(Shannon(; base = ℯ), Vasicek(m = 100), randn(npts))
1515
ea_n3 = entropy(Shannon(; base = 3), Vasicek(m = 100), randn(npts))
1616

17-
@test U - max(0.01, U*0.03) ea U + max(0.01, U*0.03)
18-
@test N * 0.98 ea_n N * 1.02
19-
@test N_base3 * 0.98 ea_n3 N_base3 * 1.02
17+
@test U - max(0.02, U*0.03) ea U + max(0.01, U*0.03)
18+
@test N * 0.96 ea_n N * 1.02
19+
@test N_base3 * 0.96 ea_n3 N_base3 * 1.02
2020

2121
x = rand(1000)
2222
@test_throws ArgumentError entropy(Renyi(q = 2), Vasicek(), x)

0 commit comments

Comments
 (0)