braintools.analysis.spectral.pli

Contents

braintools.analysis.spectral.pli#

braintools.analysis.spectral.pli(x, y, dt=None, band=None)#

Compute the phase-lag index between two continuous signals.

With \(S(t) = z_x(t)\,\overline{z_y(t)}\) the cross-spectrum of the analytic signals, the phase-lag index [1] is

\[\mathrm{PLI} = \left| \frac{1}{T} \sum_t \operatorname{sign} \left(\operatorname{Im} S(t)\right) \right| = \left| \langle \operatorname{sign}(\sin(\phi_x - \phi_y)) \rangle \right|.\]

It ignores zero-lag (and \(\pi\)-lag) coupling, which volume conduction produces, so identical signals have PLI = 0.

Parameters:
  • x (Array | ndarray | bool | number | bool | int | float | complex | Quantity) – Real signals of identical shape (T, ...); time is axis 0.

  • y (Array | ndarray | bool | number | bool | int | float | complex | Quantity) – Real signals of identical shape (T, ...); time is axis 0.

  • dt (float | Quantity | None) – Sampling interval (seconds if a plain number). Required with band.

  • band (Tuple[float, float] | None) – If given, both signals are first filtered with bandpass().

Returns:

pli – Values in [0, 1] of shape x.shape[1:].

Return type:

Array

Raises:

ValueError – If the shapes differ, band is given without dt, or band is invalid.

See also

plv

Phase-locking value.

wpli

Weighted phase-lag index.

Notes

Jittable and vmappable. Not differentiable: the sign makes it piecewise constant, so its gradient is zero almost everywhere.

References

Examples

>>> import jax.numpy as jnp
>>> from braintools.analysis.spectral import pli
>>> t = jnp.arange(1000) * 1e-3
>>> x = jnp.cos(2 * jnp.pi * 10 * t)
>>> float(pli(x, x))
0.0
>>> float(pli(x, jnp.cos(2 * jnp.pi * 10 * t - jnp.pi / 4)))
1.0