Skip to content

Commit

Permalink
Do not extended Statistics.cor/Statistics.cov (#148)
Browse files Browse the repository at this point in the history
Using the same functions as the `Statistics` ones is a pun, but the functions do
different things, in particular they return scalar values, while the method
defined here return matrices and make it impossible to do the same thing as the
`Statistics` methods.

Also, adding the `Statistics` package as dependency with the sole purpose of
extending methods of functions, which could have been done with an extension,
increases loading time by a factor of 40.
  • Loading branch information
giordano committed May 28, 2023
1 parent ba8305f commit c12fb10
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 24 deletions.
1 change: 0 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[weakdeps]
Juno = "e5e0dc1b-0480-54bc-9374-aad01c23163d"
Expand Down
3 changes: 1 addition & 2 deletions docs/src/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,7 @@ Calculating the Covariance and Correlation Matrices
---------------------------------------------------

Calculate the covariance and correlation matrices of multiple `Measurement`s
with the functions [`cov(::AbstractVector{<:Measurement})`](@ref) and
[`cor(::AbstractVector{<:Measurement})`](@ref):
with the functions [`Measurements.cov`](@ref) and [`Measurements.cor`](@ref):

```@repl
using Measurements
Expand Down
4 changes: 2 additions & 2 deletions docs/src/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ Calculating the Covariance and Correlation Matrices
---------------------------------------------------

```@docs
Measurements.Statistics.cov(::AbstractVector{<:Measurement})
Measurements.Statistics.cor(::AbstractVector{<:Measurement})
Measurements.cov
Measurements.cor
```

The [covariance matrix](https://en.wikipedia.org/wiki/Covariance_matrix) of
Expand Down
5 changes: 0 additions & 5 deletions src/Measurements.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,9 @@ module Measurements

# Calculus is used to calculate numerical derivatives in "@uncertain" macro.
using Calculus
using Statistics

import Statistics: cor, cov

# Functions provided by this package and exposed to users
export Measurement, measurement, ±
# Re-export from Statistics
export cor, cov

# Define the "Derivatives" type, used inside "Measurement" type. This should be
# a lightweight and immutable dictionary.
Expand Down
8 changes: 4 additions & 4 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,11 @@ function uncertainty_components(x::Measurement{T}) where {T<:AbstractFloat}
end

"""
cov(x::AbstractVector{<:Measurement})
Measurements.cov(x::AbstractVector{<:Measurement})
Returns the covariance matrix of a vector of correlated `Measurement`s.
"""
function Statistics.cov(x::AbstractVector{Measurement{T}}) where T
function cov(x::AbstractVector{Measurement{T}}) where T
S = length(x)
covariance_matrix = zeros(T, (S, S))

Expand All @@ -126,11 +126,11 @@ function Statistics.cov(x::AbstractVector{Measurement{T}}) where T
end

"""
cor(x::AbstractVector{<:Measurement})
Measurements.cor(x::AbstractVector{<:Measurement})
Returns the correlation matrix of a vector of correlated `Measurement`s.
"""
function Statistics.cor(x::AbstractVector{<:Measurement})
function cor(x::AbstractVector{<:Measurement})
covariance_matrix = cov(x)
standard_deviations = sqrt.(diag(covariance_matrix))
return covariance_matrix ./ standard_deviations ./ standard_deviations'
Expand Down
20 changes: 10 additions & 10 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,30 +103,30 @@ end
x = measurement(1.0, 0.1)
y = -2x + 10
z = -3x
@test @inferred(cov([x, y, z])) [0.01 -0.02 -0.03; -0.02 0.04 0.06; -0.03 0.06 0.09]
@test @inferred(Measurements.cov([x, y, z])) [0.01 -0.02 -0.03; -0.02 0.04 0.06; -0.03 0.06 0.09]

u = measurement(1, 0.05)
v = measurement(10, 0.1)
w = u + 2v
@test @inferred(cov([u, v, w])) [0.0025 0.0 0.0025; 0.0 0.01 0.02; 0.0025 0.02 0.0425]
@test @inferred(Measurements.cov([u, v, w])) [0.0025 0.0 0.0025; 0.0 0.01 0.02; 0.0025 0.02 0.0425]
end

@testset "Correlation matrix" begin
x = measurement(1.0, 0.1)
y = -2x + 10
z = -3x
@test @inferred(cor([x, y, z])) [1.0 -1.0 -1.0; -1.0 1.0 1.0; -1.0 1.0 1.0]
@test @inferred(Measurements.cor([x, y, z])) [1.0 -1.0 -1.0; -1.0 1.0 1.0; -1.0 1.0 1.0]

u = measurement(1, 0.05)
v = measurement(10, 0.1)
w = u + 2v
@test @inferred(cor([u, v, w])) [1.0 0.0 0.24253562503633297; 0.0 1.0 0.9701425001453319; 0.24253562503633297 0.9701425001453319 1.0] atol=1e-15
@test @inferred(Measurements.cor([u, v, w])) [1.0 0.0 0.24253562503633297; 0.0 1.0 0.9701425001453319; 0.24253562503633297 0.9701425001453319 1.0] atol=1e-15
end

@testset "Correlated values" begin
@testset "Simple" begin
u_in = measurement(1, 0.1)
cov_matrix = @inferred cov([u_in])
cov_matrix = @inferred Measurements.cov([u_in])

u_out, = @inferred Measurements.correlated_values([1], cov_matrix)
@test 2u_in 2u_out
Expand All @@ -139,7 +139,7 @@ end

xyz_in = [x_in, y_in, z_in]

cov_matrix = cov([x_in, y_in, z_in])
cov_matrix = Measurements.cov([x_in, y_in, z_in])

@test Measurements.uncertainty.([x_in, y_in, z_in]) .^ 2 diag(cov_matrix)

Expand All @@ -155,7 +155,7 @@ end
v_in = measurement(10, 0.1)
w_in = u_in + 2v_in

cov_matrix = cov([u_in, v_in, w_in])
cov_matrix = Measurements.cov([u_in, v_in, w_in])

(u_out, v_out, w_out) = Measurements.correlated_values(Measurements.value.([u_in, v_in, w_in]), cov_matrix)

Expand All @@ -165,7 +165,7 @@ end
@test w_out u_out + 2v_out
@test 0 ± 0 u_out + 2v_out - w_out atol=2e-8

corr_matrix = cor([u_out, v_out, w_out])
corr_matrix = Measurements.cor([u_out, v_out, w_out])
@test corr_matrix[1,1] 1
@test corr_matrix[2,3] 2Measurements.uncertainty(v_out)/Measurements.uncertainty(w_out)
end
Expand All @@ -183,7 +183,7 @@ end
x_in = measurement(1, 0)
y_in = measurement(2, 0)
z_in = measurement(3, 5)
cov_matrix = cov([x_in, y_in, z_in])
cov_matrix = Measurements.cov([x_in, y_in, z_in])
nom_values = Measurements.value.([x_in, y_in, z_in])
variables = Measurements.correlated_values(nom_values, cov_matrix)

Expand All @@ -194,7 +194,7 @@ end
@test Measurements.uncertainty(variable)^2 variance
end

@test cov_matrix cov(variables)
@test cov_matrix Measurements.cov(variables)
@test [x_in, y_in, z_in] variables
end
end
Expand Down

0 comments on commit c12fb10

Please sign in to comment.