fips.linalg.KroneckerOperator#

class fips.linalg.KroneckerOperator(factors, std=1.0, positions=None)[source]#

Bases: LinearOperator

A covariance kept as the Kronecker product of its marginal correlations.

\[S = D \, P \, (C_1 \otimes C_2 \otimes \dots \otimes C_K) \, P^T D\]

Each factor \(C_k\) is the correlation matrix of one marginal (the times, or the grid cells), \(P\) picks the rows of the full product that the operator has, in its order (any subset of the product, in any order), and \(D\) is the diagonal of standard deviations. Entry (i, j) is std[i] * std[j] * prod_k C_k[pos_k[i], pos_k[j]].

The n x n matrix is never formed unless dense() is called. A product with p columns costs N * (N_1 + ... + N_K) per column, where N_k is the size of factor k and N their product, and holds work arrays of about N entries per column. That is less than the dense matrix as long as the rows fill most of the product.

The operator copies the factors, the standard deviations and the positions it is given, and the copies are read-only: changing the arrays afterwards leaves the operator as it was.

A Kronecker model builds one from the labels of a space, and Covariance puts it behind them.

Parameters:
  • factors (Sequence[ArrayLike]) – The marginal correlation matrices \(C_k\), square, symmetric and positive-definite (positive-definite only for solve()).

  • std (ArrayLike) – The standard deviation of each row; a scalar is the same for every row.

  • positions (Sequence[ArrayLike] | None) – For each factor, the position of each row in that factor (pos_k). If not given, the rows are the full product in order, the first factor varying slowest, as np.kron lays it out.

Raises:

ValueError – If there is no factor, a factor is not square, not finite or not symmetric (to 1e-10 of its largest entry), the positions do not match the factors (one array per factor, all the same length, each within its factor), two rows have the same positions, or a standard deviation is negative or not finite.

See also

fips.Kronecker

The correlation model whose covariance this is.

fips.Covariance

A labeled covariance, which holds a form.

Examples

>>> import numpy as np
>>> from fips.linalg import KroneckerOperator
>>> C_time = np.array([[1.0, 0.5], [0.5, 1.0]])
>>> C_space = np.array([[1.0, 0.2, 0.0], [0.2, 1.0, 0.2], [0.0, 0.2, 1.0]])
>>> S = KroneckerOperator([C_time, C_space], std=2.0)
>>> S.shape
(6, 6)
>>> np.allclose(S.dense(), 4.0 * np.kron(C_time, C_space))
True
>>> x = np.arange(6.0)
>>> np.allclose(S.solve(S @ x), x)
True

Attributes

factors

The marginal correlation matrices, one per marginal, read-only.

positions

For each factor, the position of each row in it (pos_k), read-only.

std

The standard deviation of each row, read-only.

Methods

dense()

Return the operator as a dense NumPy array.

diagonal()

Return the main diagonal, std**2 * prod_k diag(C_k)[pos_k].

logdet()

Return the log-determinant through the factors.

solve(B)

Solve self @ X = B through the factors.

sqrt()

Return a square root \(R\) with \(R R^T\) equal to the operator, through the factors.

Inherited

From LinearOperator: dot, trace