StrctTensorProdTerm#
- class liesel_gam.StrctTensorProdTerm(*marginals, common_scale=None, order=None, inference=None, names_prefix='', tx_name='tx', tf_name='tf', coef_name='\\\\beta', basis_name='B', group_terms_by_order=False, _update_on_init=True)[source]#
Bases:
UserVarAnisotropic structured additive tensor product term.
- Parameters:
*marginals (
StrctTerm|IndexingTerm|RITerm|MRFTerm) – Marginal terms.common_scale (
ScaleIG|VarIGPrior|Var|Array|ndarray|bool|number|bool|int|float|complex|None, default:None) – A single, common scale to cover all marginal dimensions, resulting in an isotropic tensor product. This means setting \(\tau^2_1 = \dots = \tau^2_M = \tau^2\) for all marginal smooths in the notation used below.order (
Sequence[int] |None, default:None) – Sequence of integers identifying the orders of interactions to be included in this term. For example, if you want to include only the bi- and trivariate interactions when supplying three marginals, passorder=(2,3). The defaultorder=Nonemeans that all orders will be included; also the main effects.names_prefix (
str, default:'') – Prefix to be added to the names of all variables created by this term. The names of the main effects (marginals) will not be changed.tx_name (
str, default:'tx') – Function component for the names of the interaction terms internally created by this term. The naming pattern is"{tx_name}(x1, x2, ...)".tf_name (
str, default:'tf') – Function component for this term’s name. The naming pattern is"{tf_name}(x1, x2, ...)".coef_name (
str, default:'\\\\beta') – Symbol component of the coefficient names created by this term. The naming pattern is"${coef_name}_{term_name}$", whereterm_nameis the name of a lower-order interaction in this term. Does not affect the names of the marginal terms’ coefficients.basis_name (
str, default:'B') – Function component for the names of interaction bases internally created by this term. The naming pattern is"{basis_name}(x1, x2, ...)".group_terms_by_order (
bool, default:False) – IfTrue, an intermediate variable object will be created for each order of interactions in this term. This can help to better organize the plotted graph of a term, but otherwise has no effect except using slightly more memory._update_on_init (
bool, default:True) – Whether to update the term upon initialization.
See also
StrctTermBasic (isotropic) structured additive term.
StrctTensorProdTermFull anisotropic tensor product term.
TermBuilderInitializes structured additive terms.
BasisBuilderInitializes structured additive term basis matrices.
BasisBasis matrix object.
StrctTerm.fAlternative, more convenient constructor.
Notes
Note
The classes
StrctInteractionTermandStrctTensorProdTermare closely related. The former loosely corresponds tomgcv::ti, and the latter loosely corresponds tomgcv::te, meaning that, when you supply centered marginals,StrctInteractionTermwill only include the highest-order interaction of the supplied marginals, whileStrctTensorProdTermwill include the highest-order interaction and all lower-order interactions, including the main effects.Assumes that the term is a tensor product of \(M\) marginal bases that can be written as
\[s(\mathbf{x}_i) = \sum_{j=1}^J B_j(\mathbf{x}_i)\beta_j = \mathbf{b}^\top \boldsymbol{\beta},\]where
\(i=1, \dots, N\) is the observation index,
\(\mathbf{x}_i^\top = [x_{i,1}, \dots, x_{i,M}]\) are covariate observations, where \(M\) denotes the number of covariates included in this term,
\(\mathbf{b}(\mathbf{x}_i)^\top = [B_1(\mathbf{x}_i), \dots, B_J(\mathbf{x}_i)]\) are a set of basis function evaluations, and
\(\boldsymbol{\beta}^\top = [\beta_1, \dots, \beta_J]\) are the corresponding coefficients.
The vector of basis function evaluations is the Kronecker product of the marginal bases:
\[\mathbf{b}(\mathbf{x}_i)^\top = \mathbf{b}_1(x_{i,1})^\top \otimes \mathbf{b}_2(x_{i,2})^\top \otimes \cdots \otimes \mathbf{b}_M(x_{i,M})^\top,\]In this notation, we assume that the marginal bases are functions of just one covariate each, which is the common case. The individual terms have (potentially different) basis dimensions \(J_1, \dots, J_M\), such that the tensor product basis dimension is \(J = \prod_{m=1}^M J_m\).
The coefficient vector is equipped with a potentially rank-deficient multivariate Gaussian prior, which, in the notation of Bach & Klein (2025), can be written as
\[p(\boldsymbol{\beta} | \boldsymbol{\tau}^2) \propto \operatorname{Det}(\mathbf{K}(\boldsymbol{\tau}^2))^{1/2} \exp \left( - \frac{1}{2} \boldsymbol{\beta}^\top \mathbf{K}(\boldsymbol{\tau}^2) \boldsymbol{\beta} \right),\]with the precision matrix constructed from marginal penalties \(\tilde{\mathbf{K}}_1, \dots, \tilde{\mathbf{K}}_M\) and variance parameters \(\tau^2_1,\dots, \tau^2_M\) as
\[\mathbf{K}(\boldsymbol{\tau}^2) = \frac{\mathbf{K}_1}{\tau^2_1} + \cdots + \frac{\mathbf{K}_M}{\tau^2_M},\]where
\[\mathbf{K}_m = \mathbf{I}_{J_1} \otimes \cdots \otimes \mathbf{I}_{J_{m-1}} \otimes \tilde{\mathbf{K}}_m \otimes \mathbf{I}_{J_{m+1}} \otimes \cdots \mathbf{I}_{J_{M}},\]and \(\mathbf{I}_{J_m}\) denotes the identity matrix of dimension \(J_m \times J_m\).
Since \(\mathbf{K}(\boldsymbol{\tau}^2)\) may be rank-deficient, \(\operatorname{Det}(\mathbf{K}(\boldsymbol{\tau}^2))\) is the pseudo-determinant, or generalized determinant.
This term exploits the clearly defined structure of the precision matrix to obtain a computationally and memory-efficient evaluation of the prior, implemented in the
MultivariateNormalPenaltyOperatordistribution class. We also implement the results obtained by Bach & Klein (2025) for efficiently computing the pseudo-determinant; a key prerequisite for making higher-dimensional tensor products feasible.References
Kneib, T., Klein, N., Lang, S., & Umlauf, N. (2019). Modular regression—A Lego system for building structured additive distributional regression models with tensor product interactions. TEST, 28(1), 1–39. https://doi.org/10.1007/s11749-019-00631-z
Bach, P., & Klein, N. (2025). Anisotropic multidimensional smoothing using Bayesian tensor product P-splines. Statistics and Computing, 35(2), 43. https://doi.org/10.1007/s11222-025-10569-y
Examples
>>> x = jnp.linspace(0.0, 1.0, 4) >>> y = jnp.linspace(1.0, 2.0, 4) >>> bx = Basis( ... jnp.column_stack([jnp.ones_like(x), x]), xname="x", penalty=jnp.eye(2) ... ) >>> by = Basis( ... jnp.column_stack([jnp.ones_like(y), y]), xname="y", penalty=jnp.eye(2) ... ) >>> sx = StrctTerm.f(bx, scale=1.0) >>> sy = StrctTerm.f(by, scale=2.0) >>> term = StrctTensorProdTerm(sx, sy) >>> len(term.terms), term.value.shape (3, (4,))
Attributes