Skip to content

Sample L-comoments

Unbiased sample estimators of L-comoment matrices 1 and generalized trimmed L-comoment matrices [unpublished work by @jorenham].

L-comoment matrix estimators

lmo.l_comoment(a, r, /, trim=0, *, dtype=np.float64, rowvar=None, sort=None, cache=None)

Multivariate extension of lmo.l_moment.

Estimates the L-comoment matrix:

\[ \Lambda_{r}^{(s, t)} = \left[ \lambda_{r [ij]}^{(s, t)} \right]_{m \times m} \]

Whereas the L-moments are calculated using the order statistics of the observations, i.e. by sorting, the L-comoment sorts \(x_i\) using the order of \(x_j\). This means that in general, \(\lambda_{r [ij]}^{(s, t)} \neq \lambda_{r [ji]}^{(s, t)}\), i.e. \(\Lambda_{r}^{(s, t)}\) is not symmetric.

The \(r\)-th L-comoment \(\lambda_{r [ij]}^{(s, t)}\) reduces to the L-moment if \(i=j\), and can therefore be seen as a generalization of the (univariate) L-moments. Similar to how the diagonal of a covariance matrix contains the variances, the diagonal of the L-comoment matrix contains the L-moments.

Based on the proposed definition by Serfling & Xiao (2007) for L-comoments. Extended to allow for generalized trimming.

Parameters:

Name Type Description Default
a AnyVectorFloat | AnyMatrixFloat

1-D or 2-D array-like containing m variables and n observations. Each row of a represents a variable, and each column a single observation of all those variables. Also see rowvar below. If a is not an array, a conversion is attempted.

required
r AnyOrder | AnyOrderND

The L-moment order(s), non-negative integer or array.

required
trim AnyTrim

Left- and right-trim orders \((s, t)\), non-negative ints or floats that are bound by \(s + t < n - r\).

0
rowvar bool | None

If True, then each row (axis 0) represents a variable, with observations in the columns (axis 1). If False, the relationship is transposed: each column represents a variable, while the rows contain observations. If None (default), it is determined from the shape of a.

None
dtype _DType[_T_float]

Floating type to use in computing the L-moments. Default is numpy.float64.

float64
sort 'quick' | 'heap' | 'stable'

Sorting algorithm, see numpy.sort.

None
cache bool | None

Set to True to speed up future L-moment calculations that have the same number of observations in a, equal trim, and equal or smaller r. By default, it will cache i.f.f. the trim is integral, and \(r + s + t \le 24\). Set to False to always disable caching.

None

Returns:

Name Type Description
L Array[Any, _T_float]

Array of shape (*r.shape, m, m) with r-th L-comoments.

Examples:

Estimation of the second L-comoment (the L-coscale) from biviariate normal samples:

>>> import lmo, numpy as np
>>> rng = np.random.default_rng(12345)
>>> x = rng.multivariate_normal([0, 0], [[6, -3], [-3, 3.5]], 99)
>>> lmo.l_comoment(x, 2)
array([[ 1.2766793 , -0.83299947],
       [-0.71547941,  1.05990727]])

The diagonal contains the univariate L-moments:

>>> lmo.l_moment(x, 2, axis=0)
array([1.2766793 , 1.05990727])

The orientation (rowvar) is automatically determined, unless explicitly specified.

>>> lmo.l_comoment(x, 2).shape
(2, 2)
>>> lmo.l_comoment(x.T, 2).shape
(2, 2)
>>> lmo.l_comoment(x, 2, rowvar=False).shape
(2, 2)
>>> lmo.l_comoment(x.T, 2, rowvar=True).shape
(2, 2)
References

lmo.l_coratio(a, r, s, /, trim=0, *, dtype=np.float64, **kwds)

Estimate the generalized matrix of L-comoment ratio’s.

\[ \tilde \Lambda_{rk}^{(s, t)} = \left[ \left. \lambda_{r [ij]}^{(s, t)} \right/ \lambda_{k [ii]}^{(s, t)} \right]_{m \times m} \]
See Also

lmo.l_costats(a, /, trim=0, *, dtype=np.float64, **kwds)

Calculates the L-coscale, L-corr(elation), L-coskew(ness) and L-cokurt(osis).

Equivalent to lmo.l_coratio(a, [2, 2, 3, 4], [0, 2, 2, 2], *, **).

See Also

Shorthand aliases

lmo.l_coloc(a, /, trim=0, *, dtype=np.float64, **kwds)

L-colocation matrix of 1st L-comoment estimates, \(\Lambda^{(s, t)}_1\).

Alias for lmo.l_comoment(a, 1, *, **).

Notes

If trim = (0, 0) (default), the L-colocation for \([ij]\) is the L-location \(\lambda_1\) of \(x_i\), independent of \(x_j\).

Examples:

Without trimming, the L-colocation only provides marginal information:

>>> import lmo, numpy as np
>>> rng = np.random.default_rng(12345)
>>> x = rng.multivariate_normal([0, 0], [[6, -3], [-3, 3.5]], 99).T
>>> lmo.l_loc(x, axis=-1)
array([-0.02678225,  0.03008309])
>>> lmo.l_coloc(x)
array([[-0.02678225, -0.02678225],
       [ 0.03008309,  0.03008309]])

But the trimmed L-locations are a different story…

>>> lmo.l_loc(x, trim=(1, 1), axis=-1)
array([-0.10488868, -0.00625729])
>>> lmo.l_coloc(x, trim=(1, 1))
array([[-0.10488868, -0.03797989],
       [ 0.03325074, -0.00625729]])

What this tells us, is somewhat of a mystery: trimmed L-comoments have been only been briefly mentioned once or twice in the literature.

See Also

lmo.l_coscale(a, /, trim=0, *, dtype=np.float64, **kwds)

L-coscale matrix of 2nd L-comoment estimates, \(\Lambda^{(s, t)}_2\).

Alias for lmo.l_comoment(a, 2, *, **).

Analogous to the (auto-) variance-covariance matrix, the L-coscale matrix is positive semi-definite, and its main diagonal contains the L-scale’s. conversely, the L-coscale matrix is inherently asymmetric, thus yielding more information.

Examples:

>>> import lmo, numpy as np
>>> rng = np.random.default_rng(12345)
>>> x = rng.multivariate_normal([0, 0], [[6, -3], [-3, 3.5]], 99).T
>>> lmo.l_scale(x, trim=(1, 1), axis=-1)
array([0.66698774, 0.54440895])
>>> lmo.l_coscale(x, trim=(1, 1))
array([[ 0.66698774, -0.41025416],
       [-0.37918065,  0.54440895]])
See Also

lmo.l_corr(a, /, trim=0, *, dtype=np.float64, **kwds)

Sample L-correlation coefficient matrix \(\tilde\Lambda^{(s, t)}_2\); the ratio of the L-coscale matrix over the L-scale column-vectors.

Alias for lmo.l_coratio(a, 2, 2, *, **).

The diagonal consists of all 1’s.

Where the pearson correlation coefficient measures linearity, the (T)L-correlation coefficient measures monotonicity.

Examples:

>>> import lmo, numpy as np
>>> rng = np.random.default_rng(12345)
>>> cov = np.array([[6, -3], [-3, 3.5]])
>>> x = rng.multivariate_normal([0, 0], [[6, -3], [-3, 3.5]], 99).T
>>> lmo.l_corr(x)
array([[ 1.        , -0.65247355],
       [-0.67503962,  1.        ]])

Let’s compare this with the theoretical correlation

>>> cov[0, 1] / np.sqrt(cov[0, 0] * cov[1, 1])
-0.6546536707079772

and the (Pearson) correlation coefficient matrix:

>>> np.corrcoef(x)
array([[ 1.        , -0.66383285],
       [-0.66383285,  1.        ]])
See Also

lmo.l_coskew(a, /, trim=0, *, dtype=np.float64, **kwds)

Sample L-coskewness coefficient matrix \(\tilde\Lambda^{(s, t)}_3\).

Alias for lmo.l_coratio(a, 3, 2, *, **).

See Also

lmo.l_cokurt = l_cokurtosis module-attribute

Alias for lmo.l_cokurtosis.

lmo.l_cokurtosis(a, /, trim=0, *, dtype=np.float64, **kwds)

Sample L-cokurtosis coefficient matrix \(\tilde\Lambda^{(s, t)}_4\).

Alias for lmo.l_coratio(a, 4, 2, *, **).

See Also

References


  1. Robert Serfling and Peng Xiao. A contribution to multivariate l-moments: l-comoment matrices. Journal of Multivariate Analysis, 98(9):1765–1781, 2007.