Metastability and Eye Movements: A Dynamical‑Systems Interpretation

  1. Why metastability is a natural language for gaze behavior The idea that perception, attention, and neural activity evolve through transiently stable states has deep roots in cognitive science and neuroscience. Concepts such as attractors , basins , noise‑induced transitions , and escape times appear in work on perceptual switching, decision‑making, and neural population dynamics (Kelso, 1995; Rabinovich et al., 2008; Deco & Jirsa, 2012). Eye movements, especially the alternation between fixations and saccades ,   fit remarkably well into this metastable picture. The Freidlin–Wentzell theory of rare events (Freidlin & Wentzell, 2012) provides a rigorous mathematical language for these intuitions. 2. Fixations as metastable states  Consider the gaze position X t as the state of a stochastic dynamical system. During a fixation the  gaze remains confined to a small region, microsaccades and noise generate small fluctuations, and the gaze tends to return...

R function Kullback_Leibler

The Kullback_Leibler() function calculates the  Kullback-Leibler divergence between two probability distributions p and q. The function takes two arguments p and q, which can be either discrete or continuous probability distributions. The type of distribution is specified using the type argument.

The function first checks the type of distributions and their lengths. If the distributions are discrete, it checks that they have non-negative values and sum to one. If the distributions are continuous, it checks that they have positive values.

The Kullback-Leibler divergence is then calculated using the formula sum(p * log(p / q)). The function also calculates a normalized version of the divergence by dividing it by the entropy of p. The asymmetry of the divergence is checked by swapping p and q.

Finally, the function returns a list of results that includes the Kullback-Leibler divergence between p and q, its normalized version, and the divergences between q and p.



Kullback_Leibler <- function(p, q, type = c("discrete", "continuous")) {

  # p, q: two distributions of the same size to be compared

  

# Check the type of distributions

  type <- match.arg(type)

  # Check the length of distributions

  if (length(p) != length(q)) {

    stop("The distributions must have the same length")

  }

  # Check the validity of distributions

  if (type == "discrete") {

    if (any(p < 0) || any(q < 0)) {

      stop("The discrete distributions must have non-negative values")

    }

    if (abs(sum(p) - 1) > 1e-6 || abs(sum(q) - 1) > 1e-6) {

      stop("The discrete distributions must sum to one")

    }

  } else {

    if (any(p <= 0) || any(q <= 0)) {

      stop("The continuous distributions must have positive values")

    }

  }

  # Calculate the Kullback-Leibler divergence

  kl <- sum(p * log(p / q))

  # Normalize the divergence by dividing by the entropy of p

  kl_norm <- kl / (-sum(p * log(p)))

  # Check the asymmetry of the divergence by swapping p and q

  kl_swap <- sum(q * log(q / p))

  kl_swap_norm <- kl_swap / (-sum(q * log(q)))

  # Return a list of results

  Return(list(kld.pq = kl, kld.pq.norm = kl_norm, kld.qp = kl_swap, kld.qp.norm = kl_swap_norm))

}


#EXAMPLE 1: discrete distributions

# Discrete distributions

p <- c(0.1, 0.2, 0.3, 0.4)

q <- c(0.2, 0.3, 0.2, 0.3)

Kullback_Leibler(p,q,type="discrete")

 

#EXAMPLE 2: continuous distributions

# Continuous distributions

x <- seq(-5, 5, length.out = 100)

p <- dnorm(x, mean = -1, sd = 1)

q <- dnorm(x, mean = 1, sd = 1)

Kullback_Leibler(p,q,type="continuous")



In EXAMPLE 1, we have two discrete distributions p and q with probabilities 0.10.20.3, and 0.4 and 0.20.30.2, and 0.3, respectively.

When we call the Kullback_Leibler() function with these distributions and the argument type="discrete", we get the following results:

$kld.pq
[1] 0.04575749

$kld.pq.norm
[1] 0.064078

$kld.qp
[1] 0.05129329

$kld.qp.norm
[1] 0.0719366
The first result $kld.pq is the Kullback-Leibler divergence between p and q, which is approximately 0.04575749. The second result $kld.pq.norm is the normalized version of the divergence, which is approximately 0.064078.
The third result $kld.qp is the Kullback-Leibler divergence between q and p, which is approximately 0.05129329. The fourth result $kld.qp.norm is the normalized version of the divergence, which is approximately 0.0719366.


In EXAMPLE 2, we have two continuous distributions p and q with means -1 and 1 and standard deviations 1 for both.

When we call the Kullback_Leibler() function with these distributions and the argument type="continuous", we get the following results:

$kld.pq
[1] 1.386294

$kld.pq.norm
[1] 0.5

$kld.qp
[1] 1.386294

$kld.qp.norm
[1] 0.5

The first result $kld.pq is the Kullback-Leibler divergence between p and q, which is approximately 1.386294. The second result $kld.pq.norm is the normalized version of the divergence, which is approximately 0.5.

The third result $kld.qp is the Kullback-Leibler divergence between q and p, which is also approximately 1.386294. The fourth result $kld.qp.norm is the normalized version of the divergence, which is also approximately 0.5.

Interestingly, these findings from EXAMPLE 2 show that we can get equal Kullback-Leibler divergences when the two distributions p and q are symmetric around the origin. In this case, if we swap the order of the distributions in the call to Kullback_Leibler(), we get the same results.



Comments

Popular posts from this blog

Understanding Anaerobic Threshold (VT2) and VO2 Max in Endurance Training

Diagnosing Singular Fits in Linear Mixed Models: Practical Examples, Code, and Alternatives

Owen's Function: A Simple Solution to Complex Problems