mi_cyl {cylcop}R Documentation

Estimate the Mutual Information Between a Circular and a Linear Random Variable

Description

The empirical copula is obtained from the data (theta and x), and the mutual information of the 2 components is calculated. This gives a non-negative number that can be normalized to lie between 0 and 1.

Usage

mi_cyl(theta, x, normalize = TRUE, symmetrize = FALSE)

Arguments

theta

numeric vector of angles (measurements of a circular variable).

x

numeric vector of step lengths (measurements of a linear variable).

normalize

logical value whether the mutual information should be normalized to lie within [0,1][0,1].

symmetrize

logical value whether it should be assumed that right and left turns are equivalent. If theta can take values in [π,π)[-\pi, \pi), this means that positive and negative angles are equivalent.

Details

First, the two components of the empirical copula, uu and vv are obtained. Then the mutual information is calculated via discretizing uu and vv into length(theta)^(1/3) bins. The mutual information can be normalized to lie between 0 and 1 by dividing by the product of the entropies of u and v. This is done using functions from the 'infotheo' package.

Even if u and v are perfectly correlated (i.e. cor_cyl goes to 1 with large sample sizes), the normalized mutual information will not be 1 if the underlying copula is periodic and symmetric. E.g. while normalCopula(1) has a correlation of 1 and a density that looks like a line going from (0,0)(0,0) to (1,1)(1,1), cyl_rect_combine(normalCopula(1)) has a density that looks like "<". The mutual information will be 1 in the first case, but not in the second. Therefore, we can set symmetrize = TRUE to first convert (if necessary) theta to lie in [π,π)[-\pi, \pi) and then multiply all angles larger than 0 with -1. The empirical copula is then calculated and the mutual information is obtained from those values. It is exactly 1 in the case of perfect correlation as captured by e.g. cyl_rect_combine(normalCopula(1)).

Note also that the mutual information is independent of the marginal distributions. However, symmetrize=TRUE only works with angles, not with pseudo-observations. When x and theta are pseudo-observations, information is lost due to the ranking, and symmetrization will fail.

Value

A numeric value, the mutual information between theta and x in nats.

References

Ma J, Sun Z (2011). “Mutual Information Is Copula Entropy.” Tsinghua Science and Technology, 16(1), 51-54. ISSN 1007-0214, doi:10.1016/S1007-0214(11)70008-6, https://www.sciencedirect.com/science/article/pii/S1007021411700086/.

Calsaverini RS, Vicente R, Systems C, Artes ED (2009). “An information-theoretic approach to statistical dependence: Copula information.” Europhysics Letters, 88(6), 1–6. doi:10.1209/0295-5075/88/68003, https://iopscience.iop.org/article/10.1209/0295-5075/88/68003/.

Hodel FH, Fieberg JR (2021). “Cylcop: An R Package for Circular-Linear Copulae with Angular Symmetry.” bioRxiv. doi:10.1101/2021.07.14.452253, https://www.biorxiv.org/content/10.1101/2021.07.14.452253v3/.

See Also

cor_cyl(), fit_cylcop_cor().

Examples

set.seed(123)

cop <- cyl_quadsec(0.1)
marg1 <- list(name="vonmises",coef=list(0,4))
marg2 <- list(name="lnorm",coef=list(2,3))

#draw samples and calculate the mutual information.
sample <- rjoint(100,cop,marg1,marg2)
mi_cyl(theta = sample[,1],
  x = sample[,2],
  normalize = TRUE,
  symmetrize = FALSE
)

#the correlation coefficient is independent of the marginal distribution.
 sample <- traj_sim(100,
  cop,
  marginal_circ = list(name = "vonmises", coef  = list(0, 1)),
  marginal_lin = list(name = "weibull", coef = list(shape = 2))
)

mi_cyl(theta = sample$angle,
  x = sample$steplength,
  normalize = TRUE,
  symmetrize = FALSE)
mi_cyl(theta = sample$cop_u,
  x = sample$cop_v,
  normalize = TRUE,
  symmetrize = FALSE)

# Estimate correlation of samples drawn from circular-linear copulas
# with perfect correlation.
cop <- cyl_rect_combine(copula::normalCopula(1))
sample <- rjoint(100,cop,marg1,marg2)
# without normalization
mi_cyl(theta = sample[,1],
  x = sample[,2],
  normalize = FALSE,
  symmetrize = FALSE
)
#with normalization
mi_cyl(theta = sample[,1],
  x = sample[,2],
  normalize = TRUE,
  symmetrize = FALSE
)
#only with normalization and symmetrization do we get a value of 1
mi_cyl(theta = sample[,1],
  x = sample[,2],
  normalize = TRUE,
  symmetrize = TRUE
)


[Package cylcop version 0.2.0 Index]