# predict_matrix()


Build the prediction design matrix for new data.


Usage

``` python
predict_matrix(
    model,
    new_data,
)
```


Predicting from a fitted GAM requires evaluating each term at new covariate values in *exactly* the same numeric representation used during fitting. For a linear term this is trivial (just read off the new column), but for a smooth term it is not: simply re-fitting a fresh basis on the new data would choose different knots, degrees of freedom, and identifiability constraints, producing a matrix whose columns don't line up with the fitted coefficients `beta` at all. [predict_matrix](predict_matrix.md#whittaker.predict_matrix) avoids this by reusing the exact [SmoothBasis](SmoothBasis.md#whittaker.SmoothBasis) objects stored on `model.smooths[i].basis` -- the same knots and constraints the model was fitted with -- and simply evaluating `basis.basis_matrix()` at the new covariate values, so the resulting columns are directly compatible with the training-time coefficients.

Because a [ModelMatrix](ModelMatrix.md#whittaker.ModelMatrix) does not retain the original `~whittaker.formula.terms.Formula` object (only its numeric consequences), [predict_matrix](predict_matrix.md#whittaker.predict_matrix) first calls `_reconstruct_formula` to rebuild an equivalent [Formula](Formula.md#whittaker.Formula) from `model.column_names` and `model.smooths`, then walks that formula's terms in order -- extracting linear/interaction columns directly from `new_data` and re-evaluating each smooth's stored basis -- to assemble a new design matrix with the same column layout as `model.X`.


## Parameters


`model: ModelMatrix`  
A [ModelMatrix](ModelMatrix.md#whittaker.ModelMatrix) previously returned by [build_model_matrix()](build_model_matrix.md#whittaker.build_model_matrix).

`new_data: dict[str, numpy.ndarray]`  
Column-oriented new data. Must contain every covariate column referenced by the original formula (the response column is not needed).


## Returns


`numpy.ndarray`  
Design matrix of shape `(n_new, p)` with the same column layout as `model.X`.


## Notes

`_reconstruct_formula` infers term boundaries purely from `column_names` and the stored [SmoothInfo](SmoothInfo.md#whittaker.SmoothInfo) objects, not from any record of the literal original formula string. In practice this reconstruction always agrees with the training matrix's column layout, since it is derived from the very structures that layout was built from -- but the reconstructed [Formula](Formula.md#whittaker.Formula)'s term order and string labels are *inferred*, and should not be treated as a faithful reproduction of the original formula object passed to [build_model_matrix](build_model_matrix.md#whittaker.build_model_matrix) (for example, `full=True` interactions are not reconstructed exactly as originally specified).


## Examples

Continuing from the [build_model_matrix](build_model_matrix.md#whittaker.build_model_matrix) example above, predict at new values of `x` using the same fitted basis:


``` python
import numpy as np
from whittaker.formula.parser import parse
from whittaker.model_matrix import build_model_matrix, predict_matrix

rng = np.random.default_rng(0)
x = np.sort(rng.uniform(0, 1, 50))
y = np.sin(2 * np.pi * x) + rng.normal(scale=0.2, size=50)

model_matrix = build_model_matrix(parse("y ~ s(x)"), {"x": x, "y": y})

new_x = np.linspace(0, 1, 5)
X_new = predict_matrix(model_matrix, {"x": new_x})
X_new.shape
```


    (5, 10)
