What's Changed
[823](https://github.com/MilesCranmer/PySR/pull/823) adds support for _parameters in template expressions_, allowing you to learn expressions under a template, that have custom coefficients which can be optimized.
Along with this, the `TemplateExpressionSpec` API has changed. (The old API will continue to function, but will not have parametric expressions available).
python
spec = TemplateExpressionSpec(
"fx = f(x); p[1] + p[2] * fx + p[3] * fx^2",
expressions=["f"],
variable_names=["x"],
parameters={"p": 3},
)
This would learn three parameters, for the expression $y = p_1 + p_2 f(x) + p_3 f(x)^2.$
You can have multiple parameter vectors, and these parameter vectors can also be indexed by categorical features. For example:
python
Learn different parameters for each class:
spec = TemplateExpressionSpec(
"p1[category] * f(x1, x2) + p2[1] * g(x1^2)",
expressions=["f", "g"],
variable_names=["x1", "x2", "category"],
parameters={"p1": 3, "p2": 1},
)
This will learn an equation of the form:
$$y = \alpha_c\,f(x_1,x_2) + \beta g(x_1 ^2)$$
where $c$ is the category, $\alpha_c$ is a learned parameter specific to each category, and $\beta$ is a normal scalar category. Note that **unlike ParametricExpressionSpec**, this feature of TemplateExpressionSpec would have you pass the `category` variable _in_ `X` rather than as a category keyword (floating point versions of the categories). This difference means that in a TemplateExpressionSpec, you can actually have _multiple_ categories!
* Added support for expression-level loss functions via `loss_function_expression`, which allows you to specify custom loss functions that operate on the full expression object rather than just its evaluated output. This is particularly useful when working with template expressions.
* Note that the old template expression syntax using function-style definitions is deprecated. Use the new, cleaner syntax instead:
python
Old:
spec = TemplateExpressionSpec(
function_symbols=["f", "g"],
combine="((; f, g), (x1, x2, x3)) -> sin(f(x1, x2)) + g(x3)"
)
New:
spec = TemplateExpressionSpec(
"sin(f(x1, x2)) + g(x3)"
expressions=["f", "g"],
variable_names=["x1", "x2", "x3"],
)
**Full Changelog:** [v1.3.1...v1.4.0](https://github.com/MilesCranmer/PySR/compare/v1.3.1...v1.4.0)