Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

KroneckerSum vs SumKronecker — two operators, one confusing name

Two of the most useful structured operators in gaussx have nearly identical names — and very different jobs. Sorting them out is worth a notebook of its own.

OperatorDefinitionWhere it appears
KroneckerSum A⊕BA\oplus BA⊗Ib+Ia⊗BA\otimes I_b + I_a\otimes Bseparable PDEs, spacetime GMRF priors, additive Gaussian fields
SumKroneckerA1⊗B1+A2⊗B2A_1\otimes B_1 + A_2\otimes B_2multi-output GPs with correlated tasks, signal + iid noise on a grid

Both produce nanb×nanbn_a n_b \times n_a n_b matrices. Both look like “a sum of Kroneckers”. But the structure is wildly different: KroneckerSum is the additive separation of two operators acting on independent axes — eigendecomposable in closed form via the eigendecomposition of each factor alone. SumKronecker is the superposition of two unrelated Kronecker products — generally not jointly diagonalizable, and requiring an O((nanb)3)O((n_a n_b)^3) inner solve.

What you will see by the end:

  • The vec-form identity that makes KroneckerSum matvec cost O(nanb(na+nb))O(n_a n_b(n_a + n_b)).
  • The eigendecomposition λiA+λjB\lambda^A_i + \lambda^B_j (sum of spectra), and the resulting O(na3+nb3)O(n_a^3 + n_b^3) solve / logdet — same scaling as a single Kronecker.
  • Why SumKronecker has no analogous closed form, and the joint-eigenbasis trick gaussx uses to handle it.
  • A side-by-side cost table showing the gap: cheap factor-wise vs dense-after-a-rotation.
  • The “which one do I want” decision rule.

By the end you should be able to spot which of the two is hiding inside any spacetime / multi-output covariance you encounter.

0. Where these structures show up in geoscience

These two operators are the workhorses of spacetime and multi-variable covariances — exactly the setting where geoscience problems live.

  • KroneckerSum   A⊕B=A⊗I+I⊗B\;A\oplus B = A\otimes I + I\otimes B: the additive separation. Used whenever a process is governed by independent action along two axes that add rather than multiply:

    • 2-D Laplacian for elliptic PDE inversion (gravity, electromagnetics): L2D=Lx⊕LyL_{2D} = L_x \oplus L_y, the separable second-difference.
    • Spacetime Gaussian Markov random fields (GMRFs): a precision Λt⊕Λs\Lambda_t \oplus \Lambda_s encodes “AR(1) in time and CAR in space, independently”. Common in INLA-style spatial epidemiology, air-quality monitoring, climate-station analysis.
    • Advection-diffusion priors where the diffusion operator splits across axes.
    • Any separable covariance that is parameterized additively (e.g. squared-exponential length scales added in the precision form for stability).
  • SumKronecker   A1⊗B1+A2⊗B2\;A_1\otimes B_1 + A_2\otimes B_2: the superposition of two Kronecker layers. The shape behind every multi-output / multi-fidelity geoscience workflow:

    • Multi-output spacetime fields: Kvar⊗Kspace-time+σ2I⊗IK_{\mathrm{var}}\otimes K_{\mathrm{space}\text{-}\mathrm{time}} + \sigma^2 I\otimes I — joint emulation of (temperature, salinity, velocity) on a gridded ocean reanalysis.
    • Coregionalized geostatistics (LMC, ICM): a low-rank correlation matrix BB between outputs combined with a spatial kernel KXK_X, plus iid noise. Land-cover, mineral-resource, and soil-property mapping all live here.
    • Multi-fidelity emulation: low-fidelity covariance K1⊗B1K_1\otimes B_1 (cheap simulator) plus a discrepancy K2⊗B2K_2\otimes B_2 (correction term).
    • Hierarchical Bayesian downscaling: a coarse-grid GP plus a fine-grid GP, each with its own Kronecker factorization.

The mental shortcut: KroneckerSum is for single-quantity processes that decouple across axes; SumKronecker is for multi-quantity / multi-fidelity processes superposed on the same grid. Spacetime climate emulators routinely contain both — a SumKronecker outer layer (signal + noise) wrapping a KroneckerSum inner layer (spacetime separable precision).

1. KroneckerSum — additive separation

The Kronecker sum (note: not a sum of Kroneckers) is

A⊕B  =  A⊗Ib  +  Ia⊗B  ∈  Rnanb×nanbA \oplus B \;=\; A \otimes I_b \;+\; I_a \otimes B \;\in\; \mathbb{R}^{n_a n_b \times n_a n_b}

Picture it as a 2-D tensor-product grid where one axis is governed by AA and the other by BB, and the two contributions add. The classic example is the 2-D Laplacian: a 1-D second-difference LxL_x acting on xx plus a 1-D second-difference LyL_y acting on yy becomes Lx⊕LyL_x \oplus L_y on the joint grid.

Because the action splits across axes, the matvec admits a vec-form analogous to Roth’s lemma for A⊗BA\otimes B:

(A⊕B) vec(X)  =  vec(BX+XA⊤),X∈Rnb×na(A \oplus B)\,\mathrm{vec}(X) \;=\; \mathrm{vec}(B X + X A^\top), \qquad X \in \mathbb{R}^{n_b\times n_a}

Two matrix multiplies of size nb×nan_b\times n_a — total cost O(nanb(na+nb))O(n_a n_b (n_a + n_b)), identical scaling to a Kronecker product matvec. (gaussx implements exactly this with einops.rearrange and jax.vmap.)

matvec error : 2.26e-15
shape        : 12 x 12  (= 4 * 3)

2. The eigendecomposition: sum-of-spectra

The headline result. If A=QAΛAQA⊤A = Q_A \Lambda_A Q_A^\top and B=QBΛBQB⊤B = Q_B \Lambda_B Q_B^\top are symmetric eigendecompositions, then A⊕BA\oplus B has eigenvectors QA⊗QBQ_A\otimes Q_B and eigenvalues λiA+λjB\lambda^A_i + \lambda^B_j:

A⊕B  =  (QA⊗QB) diag ⁣{λiA+λjB}i,j (QA⊗QB)⊤A\oplus B \;=\; (Q_A\otimes Q_B)\,\mathrm{diag}\!\left\{\lambda^A_i + \lambda^B_j\right\}_{i,j}\,(Q_A\otimes Q_B)^\top

The proof is one line: A⊗I+I⊗B=(QA⊗QB)(ΛA⊗I+I⊗ΛB)(QA⊗QB)⊤A\otimes I + I\otimes B = (Q_A\otimes Q_B)(\Lambda_A\otimes I + I\otimes \Lambda_B)(Q_A\otimes Q_B)^\top, and ΛA⊗I+I⊗ΛB\Lambda_A\otimes I + I\otimes\Lambda_B is diagonal with the entries λiA+λjB\lambda^A_i + \lambda^B_j.

Practically: solve and logdet need only the per-factor eigendecompositions (O(na3+nb3)O(n_a^3 + n_b^3)), not a joint (nanb)3(n_a n_b)^3 pass:

(A⊕B)−1b  =  (QA⊗QB) diag ⁣(1λiA+λjB) (QA⊗QB)⊤b,log⁡∣A⊕B∣  =  ∑i,jlog⁡(λiA+λjB)(A\oplus B)^{-1}b \;=\; (Q_A\otimes Q_B)\,\mathrm{diag}\!\left(\frac{1}{\lambda^A_i + \lambda^B_j}\right)\,(Q_A\otimes Q_B)^\top b, \qquad \log|A\oplus B| \;=\; \sum_{i,j}\log(\lambda^A_i + \lambda^B_j)

The next cell verifies eq. ((3)) numerically.

max eigenvalue mismatch : 1.07e-14
first 6 sum-eigs        : [0.42669084 1.56075562 1.58988744 2.72395222 5.91979167 7.05385645]
first 6 direct eigs     : [0.42669084 1.56075562 1.58988744 2.72395222 5.91979167 7.05385645]
<Figure size 660x440 with 2 Axes>

3. KroneckerSum solve in O(na3+nb3)O(n_a^3 + n_b^3)

Per eq. ((4)), the solve is three steps:

  1. Project bb into the joint eigenbasis: b~=(QA⊗QB)⊤b\tilde b = (Q_A\otimes Q_B)^\top b.
  2. Element-wise divide by λiA+λjB\lambda^A_i + \lambda^B_j.
  3. Project back: x=(QA⊗QB) x~x = (Q_A\otimes Q_B)\,\tilde x.

Steps 1 and 3 are Kronecker-matvecs at O(nanb(na+nb))O(n_a n_b(n_a+n_b)). Step 2 is element-wise. The dominant cost is the two factor eigh calls.

This is the same scaling as a Kronecker product solve — additive separation costs no more than multiplicative.

solve error : 8.99e-15
logdet error: 7.11e-15

4. SumKronecker — superposition of two Kronecker products

A different beast. Now we have two Kronecker products and we add them:

M=A1⊗B1  +  A2⊗B2M = A_1\otimes B_1 \;+\; A_2\otimes B_2

The canonical case is multi-output GPs with correlated tasks: Ktask⊗Kspatial+σ2Itask⊗IspatialK_{\mathrm{task}}\otimes K_{\mathrm{spatial}} + \sigma^2 I_{\mathrm{task}}\otimes I_{\mathrm{spatial}}. Or signal-plus-noise on a tensor grid. Or any covariance where two distinct Kronecker layers superpose.

Matvec is the obvious sum of Kronecker matvecs — cost 2⋅O(nanb(na+nb))2 \cdot O(n_a n_b (n_a+n_b)), twice that of a single Kronecker. Solve and logdet are the hard part: in general A1,A2A_1, A_2 do not share eigenvectors, so we cannot simultaneously diagonalize and the spectrum is not a tidy sum or outer-product.

matvec error : 3.02e-14
||[A1, A2]||  : 35.6242  (non-zero → no shared eigenbasis)

5. The joint-eigenbasis-of-pair-2 trick

gaussx’s SumKronecker.eigendecompose() uses a hybrid approach:

  1. Eigendecompose the second pair: A2=QCΛCQC⊤A_2 = Q_C \Lambda_C Q_C^\top, B2=QDΛDQD⊤B_2 = Q_D \Lambda_D Q_D^\top. Cost: O(na3+nb3)O(n_a^3 + n_b^3).
  2. Rotate the first pair into that basis: A~1=QC⊤A1QC\tilde A_1 = Q_C^\top A_1 Q_C, B~1=QD⊤B1QD\tilde B_1 = Q_D^\top B_1 Q_D. Cost: O(na3+nb3)O(n_a^3 + n_b^3).
  3. Form the rotated full matrix A~1⊗B~1+diag(λiCλjD)\tilde A_1 \otimes \tilde B_1 + \mathrm{diag}(\lambda^C_i \lambda^D_j) — an nanb×nanbn_a n_b\times n_a n_b matrix — and call eigh. Cost: O((nanb)3)O((n_a n_b)^3).

The third step is the bottleneck. Unlike KroneckerSum, we cannot avoid a dense pass on the full N=nanbN=n_a n_b matrix. The trick only buys us:

  • A symmetric form for eigh (the rotation makes A2⊗B2A_2\otimes B_2 purely diagonal so the second pair contributes only to the diagonal).
  • Cheaper structural inheritance (the eigendecomposition is computed once and reused for solve, logdet, and matrix square root).

SumKronecker is intended for moderate factor sizes — typical multi-output GPs with task dimension ≤10\leq 10. Past that, you need iterative Krylov solvers (1.D) or alternative parameterizations.

eigendecomp residual : 1.07e-13
logdet via eigs      : 27.528890
logdet ref           : 27.528890
solve error via eigs : 1.97e-14

6. Cost & structure comparison

Side-by-side, with N=nanbN = n_a n_b:

AspectKronecker A⊗BA\otimes BKroneckerSum A⊕BA\oplus BSumKronecker A1⊗B1+A2⊗B2A_1\otimes B_1 + A_2\otimes B_2
Storagena2+nb2n_a^2 + n_b^2na2+nb2n_a^2 + n_b^22(na2+nb2)2(n_a^2 + n_b^2)
MatvecO(N(na+nb))O(N(n_a + n_b))O(N(na+nb))O(N(n_a + n_b))2⋅O(N(na+nb))2\cdot O(N(n_a + n_b))
SpectrumλiAλjB\lambda^A_i \lambda^B_jλiA+λjB\lambda^A_i + \lambda^B_jno closed form
Solve / logdetO(na3+nb3)O(n_a^3 + n_b^3)O(na3+nb3)O(n_a^3 + n_b^3)O(N3)O(N^3) via eigh on A~1⊗B~1+diag\tilde A_1\otimes\tilde B_1 + \mathrm{diag}
ConstructorKronecker(A, B)KroneckerSum(A, B)SumKronecker(Kronecker(A1,B1), Kronecker(A2,B2))

The two takeaways:

  1. KroneckerSum is essentially free — same asymptotic cost as a single Kronecker product, including a clean closed-form spectrum.
  2. SumKronecker is moderate-only — the cubic-in-NN inner eigh is the price of not having a shared eigenbasis. Use it when N≲N \lesssim a few thousand (multi-output GP with small task dimension); reach for iterative methods otherwise.

7. Solve cost: KroneckerSum vs SumKronecker

Theoretical FLOP curves for the eigendecomposition-based solve, sweeping N=n2N = n^2 (square layout na=nb=nn_a = n_b = n). KroneckerSum scales as O(n3)=O(N3/2)O(n^3) = O(N^{3/2}); SumKronecker as O(N3)O(N^3). Plot is log–log so the slopes are exactly the asymptotic exponents.

<Figure size 770x550 with 1 Axes>

8. Which one do I want?

A simple decision rule when you build a covariance with Kronecker-shaped pieces:

Pattern in your covarianceReach for
“AA acts on rows, BB acts on columns, contributions add” (separable PDE / GMRF)KroneckerSum(A, B)
“Kernel on a tensor grid times a coregionalization matrix”Kronecker(K_task, K_space)
“Kernel times correlation plus iid noise on a tensor grid”SumKronecker(Kronecker(K_task, K_space), σ²·Kronecker(I, I))
“Two independent Kronecker layers superposed” (multi-output, multi-fidelity)SumKronecker(...)
“Three or more Kronecker layers”iterative methods — see 1.E (SLQ logdet, BBMM)

The naming is admittedly cruel — “Kronecker sum” means A⊗I+I⊗BA\otimes I + I\otimes B in linear-algebra texts, but a “sum of Kroneckers” reads like the same thing in plain English. In gaussx, the operator names track the linear-algebra convention: KroneckerSum = A⊕BA\oplus B, SumKronecker = ∑kAk⊗Bk\sum_k A_k\otimes B_k. When in doubt, check the eigendecomposition: if the spectrum is a tidy outer-sum of two factor spectra, you have a KroneckerSum. If not, you have a SumKronecker.

The rest of Part 1 fills in the remaining structured leaves (Toeplitz, BlockTriDiag, MaskedOperator) and then 1.7 explains how the kronecker_sum_tag attached on construction lets gaussx’s primitives dispatch through any of these forms automatically.