1. Overview

Explain the modifications on code w.r.t d-nested effect on gamFactory.

2. Added/Modified Function

Added

trans_linear_nexpsm in trans_xxx

smooth.construct.si_nexpsm.smooth.spec

eff_si_nexp

deriv_si_nexp

I.predict.matrix.si_nexpsm

DHessDrho_si_nexpsm

pre_all_times

pre_si_nexp_chicago

time_gap

Modified

build_family_nl

Predict.matrix.nested

postproc_gam_nl

I_DhDr

I_build_effects

.get_eff_eval_si_nexp

I_get.jacobian.nested

RcppExports

gam_nl


3. smooth.construct.si_nexpsm.smooth.spec

This function processes design matrices, penalty matrices, and inner coefficient alpha.

Phase 0 & 1: Data Partitioning and Centering

Code Logic:

  • Split Xall to X_si and X_nexp.

  • For messy(flatten) data, time-series covariates are unrolled row by row, dropping invalid instances (NA/Inf).

  • (optionally) X_si is mean-centered without scaling, the default is FALSE.

Mathematical Formulation:

Let \(x_{si, t} \in \mathbb{R}^{d_{si}}\) and \(x_{nexp, t} \in \mathbb{R}^{d_{nexp}}\) denote the partitioned covariate vectors at time \(t\).

\[ \begin{aligned} X_{all} &= [ X_{si} \mid X_{nexp} ] \\ X_{si}^{(c)} &= X_{si} - \mathbf{1}\bar{x}_{si}^T \end{aligned} \]

Phase 2: Single-Index: Initialization

Code Logic:

  • Diagonalise \(S_{si}\) by .diagPen (3 cases), transform \(X_{si}\).

  • Initialise \(\alpha_{si}\) and \(\alpha_{center}\) -> Reparametrise by B

Mathematical Formulation:

  1. Orthogonal Reparameterization: We find an orthogonal transformation matrix \(B_{si}\) such that \(B_{si}^T S_{si} B_{si} = \Lambda_{si}\) (a diagonal matrix). The design matrix and parameters are transformed to decouple the penalized space:

\[\tilde{X}_{si} = X_{si} B_{si}, \quad \tilde{\alpha}_{si} = B_{si}^{-1} \alpha_{si}\]

Phase 3: Exponential Smoothing: Initialization

Code Logic:

  • Diagonalise \(S_{nexp}\) by .diagPen (2 cases), transform \(X_{nexp}\).

  • Initialise \(\alpha_{nexp}\) -> Reparametrise by B

  • Calculate g by deriv_si_nexp

Mathematical Formulation:

With the reparameterized \(\tilde{X}_{nexp} = X_{nexp} B_{nexp}\) and \(\tilde{\alpha}_{nexp} = B_{nexp}^{-1} \alpha_{nexp}\), the dynamic smoothing weight \(\omega_t \in (0,1)\) is computed as:

\[\omega_t = \frac{1}{1 + \exp(-{\tilde{X}}^T_{nexp, t} \tilde{\alpha}_{nexp})}\]

The trajectory \(g_t\) is recursively generated:

\[z = X_{si} * (\alpha_{si} + \alpha_{center})\]

\[g_t = \omega_t g_{t-1} + (1 - \omega_t) z_t\]

Phase 4: Global: Standardization

Code Logic:

  • Imposed variance of s to 1(by sd(g))

  • center and scale s

Mathematical Formulation:

\[\tilde{\alpha}_{si} \leftarrow \frac{\tilde{\alpha}_{si}}{\sigma_g}, \quad \alpha_{center} \leftarrow \frac{\alpha_{center}}{\sigma_g}\]

\[s_t = \frac{g_t - \mu_g}{\sigma_g}\]

(Note: If a positive constraint positive_si is active, the absorption is performed in the logarithmic space).

Phase 5 & 6: Outer B-Spline Construction and Global Penalty Assembly

Code Logic:

Build outer B-spline basis by .build_nested_bspline_basis

Assemble out$S

Mathematical Formulation:

The outer layer expands \(s_t\) over \(K\) spline bases:

\[f(s_t) = \sum_{k=1}^K \beta_k B_k(s_t)\]

The global penalty matrices corresponding to the parameter vector \(\theta = [\tilde{\alpha}_{nexp}^T, \tilde{\alpha}_{si}^T, \beta^T]^T\) are constructed as:

\[ \begin{aligned} S_1 = S_{global}^{(\beta)} &= \begin{bmatrix} \mathbf{0}_{nexp} & \mathbf{0} & \mathbf{0} \\ \mathbf{0} & \mathbf{0}_{si} & \mathbf{0} \\ \mathbf{0} & \mathbf{0} & S_{\beta} \end{bmatrix}\\ S_3 = S_{global}^{(nexp)} &= \begin{bmatrix} \Lambda_{nexp} & \mathbf{0} & \mathbf{0} \\ \mathbf{0} & \mathbf{0}_{si} & \mathbf{0} \\ \mathbf{0} & \mathbf{0} & \mathbf{0}_{\beta} \end{bmatrix} \\ S_2 = S_{global}^{(si)} &= \begin{bmatrix} \mathbf{0}_{nexp} & \mathbf{0} & \mathbf{0} \\ \mathbf{0} & \Lambda_{si} & \mathbf{0} \\ \mathbf{0} & \mathbf{0} & \mathbf{0}_{\beta} \end{bmatrix} \end{aligned} \]

4. I.predict.matrix.si_nexpsm

Phase 0 & 1: Data Partitioning and Centering

Code Logic:

  • Split Xall to X_si and X_nexp.
  • For messy(flatten) data, time-series covariates are unrolled row by row, dropping invalid instances (NA/Inf).
  • (optionally) X_si is mean-centered without scaling, the default is FALSE.

Phase 2: Linear transformation, exp smooth and global center

Code Logic:

  • transform \(X_{si}\) and \(X_{nexp}\).
  • calculate s by linear transformation and exp smooth.
  • center with xm["nexp"].

Phase 3: Jacobian or Spline Design Matrix Construction

Code Logic:

  • Jacobian (get.xa = TRUE): return \(s\), \(\frac{\partial s}{\partial \boldsymbol{\alpha_{nexp}}}\), \(\frac{\partial s}{\partial \boldsymbol{\alpha_{si}}}\).
  • Spline Design Matrix (get.xa = FALSE): use 0 to fill the position of \(\alpha\), return with s.

Mathematical Formulation:

\[X_{spline, t} = \text{Basis}(s^*_t)\]

Given the global parameter vector \(\theta = [\alpha_{nexp}^\top, \alpha_{si}^\top, \beta^\top]^\top\), the final row vector for observation \(t\) in the total design matrix \(X_{tot}\) is zero-padded to ignore the \(\alpha\) parameters during the linear predictor step \(X_{tot}\theta\):

\[X_{tot, t} = \big[ \mathbf{0}_{1 \times (d_{nexp} + d_{si})}, \; X_{spline, t} \big]\]

5. postproc_gam_nl

In the si_nexpsm type, the mean of s(after exp smooth) is appended to xm. This means: \(xm = [0\_{n_{si}}, 0\_{n_{nexp}}]\).

6. build_family_nl

Added some code to handle mgcv column dropping in Gradient/Hessian calculations. Simply pad the dropped columns with zeros.

7. pre_all_times

Used for forecasting when the model processes data with time-series anomalies.

8. time_gap

Compute adjacent time gaps and fill the first gap with the mode. Called by pre_si_nexp_chicago.