Skip to content

BREAK: make parametrized functions pure - #579

Open
grayson-helmholz wants to merge 11 commits into
mainfrom
BREAK/pure-parametrized-function
Open

BREAK: make parametrized functions pure#579
grayson-helmholz wants to merge 11 commits into
mainfrom
BREAK/pure-parametrized-function

Conversation

@grayson-helmholz

@grayson-helmholz grayson-helmholz commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Closes #568

⚠️ Interface changes

ParametrizedFunction is now pure: parameter values are passed to the evaluation itself instead of being stored on the function beforehand. A call can no longer affect a later call, which makes function objects thread-safe and safe to trace with JIT compilers such as jax.jit.

ParametrizedFunction.__call__ is now declared on the interface itself (it was previously only implemented on subclasses) and takes parameter values as an optional second positional argument. Values given at the call are merged with the defaults in parameters for that evaluation only.

There is no deprecation period: update_parameters() is removed in the same release that introduces the pure API.

Old name New name
ParametrizedFunction.update_parameters(new_parameters) removed — pass values to __call__, or use with_parameters() for a new function with different defaults
ParametrizedFunction.__call__(data) ParametrizedFunction.__call__(data, parameters=None)
ParametrizedFunction.with_parameters(parameters) (new)

❗ Behavioral changes

  • ChiSquared and UnbinnedNLL no longer mutate the function they wrap. Calling an estimator, or running optimize() over it, leaves the wrapped function's parameters untouched, so a function can now be reused after a fit instead of silently carrying the optimizer's last trial values.

📝 Documentation

  • The notebooks now state once, on the usage/basics page, that a ParametrizedFunction is immutable and that there are two ways of using non-default parameter values: pass them to __call__ for a single evaluation, or create a new function with with_parameters(). Both are cheap, because the lambdified backend function is shared between the two.
  • Fit fractions and sub-intensity distributions on the amplitude-analysis page are now computed with the optimized parameter values. They were computed with the model defaults before, because nothing ever wrote the fit result back into intensity_func. The rendered plot and the reported percentages change accordingly.

🖱️ Developer experience

  • Notebooks set the figure format with set_matplotlib_formats() from matplotlib_inline instead of the %config InlineBackend.figure_formats magic, so the cells remain valid Python and can be formatted and linted like any other source file.

Squash commit messages

* BEHAVIOR: compute fit fractions with optimized parameters
* BREAK: add `parameters` argument to `__call__()`
* BREAK: replace `update_parameters()` with `with_parameters()`
* DOC: explain immutable function interface in notebooks
* DX: replace inline backend magic with `set_matplotlib_formats()`

@grayson-helmholz grayson-helmholz linked an issue Aug 7, 2026 that may be closed by this pull request
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@redeboer redeboer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'TensorWaves benchmark results'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: b818ba1 Previous: dadc908 Ratio
benchmarks/expression.py::test_fit[1000-ScipyMinimizer-numpy] 7.067198373578674 iter/sec (stddev: 0.0006566206798525118) 15.653084369591935 iter/sec (stddev: 0.0008327728665216672) 2.21
benchmarks/expression.py::test_fit[1000-ScipyMinimizer-numba] 6.950944860503677 iter/sec (stddev: 0.0007231228780639494) 15.57675266668666 iter/sec (stddev: 0.00019544090300604612) 2.24
benchmarks/expression.py::test_fit[1000-ScipyMinimizer-tf] 0.6204018518144632 iter/sec (stddev: 0.0031506456032551738) 1.4336772024447277 iter/sec (stddev: 0.002264740294580996) 2.31
benchmarks/unbinned_nll.py::test_unbinned_nll_normalization_formula[original-numpy] 29.237973075993775 iter/sec (stddev: 0.00029802421855302494) 82.89554185733245 iter/sec (stddev: 0.00047803677168886747) 2.84
benchmarks/unbinned_nll.py::test_unbinned_nll_normalization_formula[optimized-numpy] 37.661080405219295 iter/sec (stddev: 0.00022621010787575476) 128.51191203721672 iter/sec (stddev: 0.00026220735978772406) 3.41
benchmarks/unbinned_nll.py::test_unbinned_nll_estimator[numpy] 124.35434985283246 iter/sec (stddev: 0.00009557364942604139) 345.5347754466312 iter/sec (stddev: 0.00009775185162269724) 2.78
benchmarks/unbinned_nll.py::test_unbinned_nll_estimator[numba] 97.18704899505222 iter/sec (stddev: 0.0003010207023603398) 547.3808519863164 iter/sec (stddev: 0.00008040495616927644) 5.63

This comment was automatically generated by workflow using github-action-benchmark.

@redeboer
redeboer force-pushed the BREAK/pure-parametrized-function branch from b818ba1 to d1955d7 Compare September 1, 2026 08:58
@redeboer redeboer added the ⚠️ Interface Breaking changes to the API label Sep 1, 2026
@redeboer redeboer changed the title Break/pure parametrized function BREAK: make parametrized functions pure Sep 1, 2026
@redeboer redeboer added this to the 0.5.0 milestone Sep 1, 2026
@redeboer redeboer added the 📝 Docs Improvements or additions to documentation label Sep 1, 2026
@redeboer
redeboer force-pushed the BREAK/pure-parametrized-function branch from 65e86f0 to 8481a7f Compare September 1, 2026 14:10
@redeboer redeboer added ❗ Behavior Changes that may affect the framework output 🖱️ DX Improvements to the Developer Experience labels Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

❗ Behavior Changes that may affect the framework output 📝 Docs Improvements or additions to documentation 🖱️ DX Improvements to the Developer Experience ⚠️ Interface Breaking changes to the API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pure, immutable ParametrizedFunction

3 participants