cov¶
- array_api_extra.cov(m, /, *, axis=-1, correction=1, fweights=None, aweights=None, xp=None)¶
Estimate a covariance matrix (or a stack of covariance matrices).
Covariance indicates the level to which two variables vary together. If we examine N-dimensional samples, \(X = [x_1, x_2, ... x_N]^T\), each with M observations, then element \(C_{ij}\) of the \(N \times N\) covariance matrix is the covariance of \(x_i\) and \(x_j\). The element \(C_{ii}\) is the variance of \(x_i\).
Extends
numpy.cov()with support for batch input. Naming follows the array API conventions used elsewhere in this library (axis,correction) rather than the NumPy spellings (rowvar,bias,ddof); see Notes for the mapping.- Parameters:
m (
object) – An array of shape(..., N, M)whose innermost two dimensions contain M observations of N variables by default. The axis of observations is controlled by axis.axis (
int) – Axis of m containing the observations. Default:-1(the last axis), matching the array API convention. Useaxis=-2(or0for 2-D input) to treat each column as a variable, which corresponds torowvar=Falseinnumpy.cov().correction (
float) – Degrees of freedom correction: normalization divides byN - correction(for unweighted input). Default:1, which gives the unbiased estimate (matchesnumpy.cov()default ofbias=False). Set to0for the biased estimate (Nnormalization). Corresponds toddofinnumpy.cov()and tocorrectioninnumpy.var()/numpy.std()andtorch.cov(). Non-integer values are allowed for advanced use cases: the unbiased correction for weighted observations depends on the sum and dispersion of the weights and is generally not an integer, and autocorrelated data may also require a fractional correction. Non-integercorrectionroutes through the generic implementation becausenumpy.cov()’sddofandtorch.cov()’scorrectionboth require integers.fweights (
object|None) – 1-D array of integer frequency weights: the number of times each observation is repeated. Same asfweightsinnumpy.cov()/torch.cov().aweights (
object|None) – 1-D array of observation-vector weights (analytic weights). Larger values mark more important observations. Same asaweightsinnumpy.cov()/torch.cov().xp (
ModuleType|None) – The standard-compatible namespace for m. Default: infer.
- Returns:
An array having shape
(..., N, N)whose innermost two dimensions represent the covariance matrix of the variables.- Return type:
Notes
Mapping from
numpy.cov()to this function:numpy.cov(m, rowvar=True) -> cov(m, axis=-1) # default numpy.cov(m, rowvar=False) -> cov(m, axis=-2) numpy.cov(m, bias=True) -> cov(m, correction=0) numpy.cov(m, ddof=k) -> cov(m, correction=k) numpy.cov(m, fweights=f) -> cov(m, fweights=f) numpy.cov(m, aweights=a) -> cov(m, aweights=a)
A
RuntimeWarningis emitted for non-positive effective degrees of freedom when the effective normalizer can be checked without materializing a lazy array. When the normalizer itself is lazy (e.g. for weighted Dask inputs), this check is skipped; choosecorrectionand weights such that it is positive.Examples
>>> import array_api_strict as xp >>> import array_api_extra as xpx
Consider two variables, \(x_0\) and \(x_1\), which correlate perfectly, but in opposite directions:
>>> x = xp.asarray([[0, 2], [1, 1], [2, 0]]).T >>> x Array([[0, 1, 2], [2, 1, 0]], dtype=array_api_strict.int64)
Note how \(x_0\) increases while \(x_1\) decreases. The covariance matrix shows this clearly:
>>> xpx.cov(x, xp=xp) Array([[ 1., -1.], [-1., 1.]], dtype=array_api_strict.float64)
Note that element \(C_{0,1}\), which shows the correlation between \(x_0\) and \(x_1\), is negative.
Further, note how x and y are combined:
>>> x = xp.asarray([-2.1, -1, 4.3]) >>> y = xp.asarray([3, 1.1, 0.12]) >>> X = xp.stack((x, y), axis=0) >>> xpx.cov(X, xp=xp) Array([[11.71 , -4.286 ], [-4.286 , 2.14413333]], dtype=array_api_strict.float64)
>>> xpx.cov(x, xp=xp) Array(11.71, dtype=array_api_strict.float64)
>>> xpx.cov(y, xp=xp) Array(2.14413333, dtype=array_api_strict.float64)
Input with more than two dimensions is treated as a stack of two-dimensional input.
>>> stack = xp.stack((X, 2*X)) >>> xpx.cov(stack) Array([[[ 11.71 , -4.286 ], [ -4.286 , 2.14413333]], [[ 46.84 , -17.144 ], [-17.144 , 8.57653333]]], dtype=array_api_strict.float64)
The normalization can be adjusted with correction, and observations can be weighted with integer frequencies fweights or importance weights aweights:
>>> x = xp.asarray([0., 1., 2., 3., 4.]) >>> xpx.cov(x, xp=xp) # unbiased variance: divide by N - 1 Array(2.5, dtype=array_api_strict.float64) >>> xpx.cov(x, correction=0, xp=xp) # biased variance: divide by N Array(2., dtype=array_api_strict.float64)
Giving the two extreme observations frequency 2 via fweights is equivalent to repeating them in x:
>>> xpx.cov(x, fweights=xp.asarray([2, 1, 1, 1, 2]), xp=xp) Array(3., dtype=array_api_strict.float64) >>> xpx.cov(xp.asarray([0., 0., 1., 2., 3., 4., 4.]), xp=xp) Array(3., dtype=array_api_strict.float64)
aweights instead adjusts the relative importance of observations, here down-weighting the two extremes:
>>> xpx.cov(x, aweights=xp.asarray([0.5, 1., 1., 1., 0.5]), xp=xp) Array(1.92, dtype=array_api_strict.float64)