TensorProductBasisT2

Tensor product basis with full penalty decomposition (t2()-style interaction smooth).

Usage

Source

TensorProductBasisT2(marginals)

TensorProductBasisT2 builds exactly the same basis matrix as TensorProductBasis (te()) — the row-wise Kronecker product of the marginal bases — but replaces te()’s d per-direction penalties with a richer decomposition that has one penalty for every non-empty subset of the marginal directions, following the “type 2” tensor product construction of Wood, Scheipl and Faraway (2013). Because it uses ordinary quadratic penalties throughout (rather than the null-space/range-space projections used internally by te()), the resulting penalties are positive semi-definite by construction and combine cleanly with random-effects representations of the smooth, and it never has negative smoothing-parameter degeneracies that can occasionally affect te(). Prefer TensorProductBasisT2 over plain TensorProductBasis when a strictly additive quadratic-penalty structure is needed (e.g. for mixed-model / REML-based fitting), or when the interaction component of the surface is believed to need noticeably different smoothing from any single marginal direction on its own and a dedicated smoothing parameter for that pure-interaction subset is wanted.

Notes

For d marginals with penalties S_1, \ldots, S_d and basis dimensions k_1, \ldots, k_d, every non-empty subset \sigma \subseteq \{1, \ldots, d\} of marginal directions gets its own penalty

\mathbf{S}_\sigma = \mathbf{M}_1 \otimes \mathbf{M}_2 \otimes \cdots \otimes \mathbf{M}_d, \qquad \mathbf{M}_j = \begin{cases} \mathbf{S}_j & j \in \sigma \\ \mathbf{I}_{k_j} & j \notin \sigma \end{cases},

giving 2^d - 1 penalties in total (compared to the d penalties of TensorProductBasis). For two marginals with penalties S_1, S_2, this is

\{\, \mathbf{S}_1 \otimes \mathbf{I},\ \ \mathbf{I} \otimes \mathbf{S}_2,\ \ \mathbf{S}_1 \otimes \mathbf{S}_2 \,\},

the usual two te()-style main-effect-direction penalties plus one additional penalty, S_1 ⊗ S_2, that penalizes roughness jointly in both directions at once — this extra term is what lets the pure two-way-interaction component of the surface have its own smoothing parameter, separate from either marginal direction’s smoothness. As the number of marginals d grows, the number of penalties grows exponentially (2^d - 1), so this construction is practical mainly for d = 2 or d = 3; null_space_dimension() and identifiability_constraints() are inherited unchanged from TensorProductBasis, since the basis matrix itself does not change — only the penalty is decomposed further.

Examples

import numpy as np
from whittaker.smooths.tensor import TensorProductBasisT2
from whittaker.smooths.tprs import TPRS

rng = np.random.default_rng(0)
x = rng.uniform(0, 1, (100, 2))

basis = TensorProductBasisT2([TPRS(k=6), TPRS(k=5)]).fit(x)
B = basis.basis_matrix(x)
penalties = basis.penalty_matrices()
B.shape, len(penalties)  # 3 penalties for 2 marginals (2^2 - 1)
((100, 30), 3)

Methods

Name Description
penalty_matrices() Return one penalty per non-empty subset of marginal directions.

penalty_matrices()

Return one penalty per non-empty subset of marginal directions.

Usage

Source

penalty_matrices()

Returns

list[NDArray]
List of 2^d - 1 matrices, each of shape (k, k) where d is the number of marginals and k is the total basis dimension. Ordered by increasing subset bitmask (single-direction penalties first, higher-order interaction penalties last).