Tensorwaves

Latest version: v0.4.13

Safety actively analyzes 715032 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 4 of 7

0.4.0

_See all documentation for this specific version [here](https://tensorwaves.rtfd.io/en/0.4.0)._

TensorWaves [v0.4](https://tensorwaves.rtfd.io/en/0.4.x) has a more general interface than [v0.3](https://tensorwaves.rtfd.io/en/0.3.x). Major changes are the removal of the `Model` interface (#357) and generalization of the `data` module (392). This affects the way in which computational backend functions are created and the way in which hit-and-miss distributions are generated.

Some examples of syntax changes for an AmpForm `HelicityModel` (`model`):

**v0.4.x** (new)

python
create function and data transformer
from tensorwaves.function.sympy import create_parametrized_function

intensity = create_parametrized_function(
expression=model.expression.doit(),
parameters=model.parameter_defaults,
backend="jax",
)
helicity_transformer = SympyDataTransformer.from_sympy(
model.kinematic_variables, backend="numpy"
)

generate data
from tensorwaves.data import (
IntensityDistributionGenerator,
SympyDataTransformer,
TFPhaseSpaceGenerator,
TFUniformRealNumberGenerator,
)

phsp_generator = TFPhaseSpaceGenerator(
initial_state_mass=3.069,
final_state_masses={0: 0.0, 1: 0.135, 2: 0.135},
)
data_generator = IntensityDistributionGenerator(
domain_generator=phsp_generator,
function=intensity,
domain_transformer=helicity_transformer,
)
rng = TFUniformRealNumberGenerator(seed=0)
phsp = phsp_generator.generate(100_000, rng)
data = data_generator.generate(10_000, rng)


_Note that this works for general SymPy expressions: there is no AmpForm dependency._ See [this page](https://tensorwaves.readthedocs.io/en/0.4.x/usage.html).

**v0.3.x** (old)

python
from tensorwaves.model import LambdifiedFunction, SympyModel

create function and data transformer
sympy_model = SympyModel(
expression=model.expression.doit(),
parameters=model.parameter_defaults,
)
intensity = LambdifiedFunction(sympy_model, backend="jax")
helicity_transformer = HelicityTransformer(model.adapter)

generate data
from tensorwaves.data import TFUniformRealNumberGenerator, generate_data, generate_phsp
from tensorwaves.data.transform import HelicityTransformer

rng = TFUniformRealNumberGenerator(seed=0)
phsp = generate_phsp(
size=100_000,
initial_state_mass=3.069,
final_state_masses={0: 0.0, 1: 0.135, 2: 0.135},
random_generator=rng,
)
data = generate_data(
size=10_000,
initial_state_mass=3.069,
final_state_masses={0: 0.0, 1: 0.135, 2: 0.135},
data_transformer=helicity_transformer,
intensity=intensity,
random_generator=rng,
)


πŸ’‘ New features

<details>
<summary>Implemented chi-squared estimator (387)</summary>

Also includes improvements to the documentation of `estimator` module.

</details>

<details>
<summary>Implemented get_source_code function (378)</summary>

Closes 323

- Added a convenience function `tensorwaves.function.get_source_code()`
- Added read-only properties `function` and `argument_order` to `ParametrizedBackendFunction` (parallels `attrs`-decorated `PositionalArgumentFunction` class).
- `PositionalArgumentFunction` is now used internally in `ParametrizedBackendFunction` (simplifies its `__call__()` method).
- Symbols are not force-dummified anymore if `use_cse=False`

</details>

<details>
<summary>SciPy now works with TF (360)</summary>

</details>

<details>
<summary>Import optimizers directly from the tensorwaves.optimizer module (360)</summary>

It's now possible to do

python
from tensorwaves.optimizer import Minuit2


instead of

python
from tensorwaves.optimizer.minuit import Minuit2


</details>

⚠️ Interface

<details>
<summary>Adapted implementation to AmpForm v0.12.x (345)</summary>

Adapts the `data` module implementation so that it can work with [AmpForm v0.12.x](https://github.com/ComPWA/ampform/releases/tag/0.12.0). Closes https://github.com/ComPWA/ampform/issues/182.

Some major changes:

- Keys in a `DataSample` are now `str` only, not `int`. This means that momentum samples have keys `"p0"`, `"p1"`, etc. instead of `0`, `1`. This is in accordance with the `Symbol` names used in AmpForm's `HelicityModel.kinematic_variables`.
- Added a function `create_function()` that creates a `PositionalArgumentFunction`. This is a `Function` without parameters (compare `ParametrizedFunction`). The function and related class is used in the `DataTransformer` implementation, which doesn't need parameters.
- Data conversion can now be done with different back-ends.

</details>

<details>
<summary>Removed Model interface (357)</summary>

This PR removes the `Model` interface and related implementations. The interface was introduced with the idea to implement different types of expression trees later on (see [ADR-001](https://compwa-org.readthedocs.io/en/stable/adr/001.html)), but this seems to be a premature optimisation. For now, the `Function` interface suffices: `Function` instances can be created through specific functions.

Some major changes:

- The `Model` interface and its implementation `SympyModel` have been removed
- `tensorwaves.model` has been renamed to `tensorwaves.function`
- There is no way to use `performance_optimize()` (for nowβ€”see 358)

This means that the workflow becomes:

python
helicity_model: ampform.helicity.HelicityModel
function = create_parametrized_function(
expression=helicity_model.expression.doit(),
parameters=helicity_model.parameter_defaults,
backend="numpy",
)


instead of

python
model = SympyModel(
expression=helicity_model.expression.doit(),
parameters=helicity_model.parameter_defaults,
max_complexity=max_complexity,
)
function = LambdifiedFunction(model, backend="numpy")


</details>

<details>
<summary>Created ParametrizedFunction interface (353)</summary>

The existing [`Function`](https://tensorwaves.readthedocs.io/en/0.3.7/api/tensorwaves.interface.html#tensorwaves.interface.Function) interface has too many responsibilities: it (1) converts a `DataSample` to an array or tensor and (2) distinguishes parameter variables from domain variables. This worked fine so far, because `Function` was only used when optimizing, where you need to tweak those parameters. In 345 though, we need to a `Function` that only does (1), for the conversion of one `DataSample` (four-momenta) to another `DataSample` (kinematic variables) with different back-ends.

This PR creates a new [`ParametrizedFunction`](https://tensorwaves.readthedocs.io/en/latest/api/tensorwaves.interface.html#tensorwaves.interface.ParametrizeFunction) interface that does (1) and (2) and a 'bare' [`Function`](https://tensorwaves.readthedocs.io/en/latest/api/tensorwaves.interface.html#tensorwaves.interface.Function) interface that does only (1). The input and output types of the `Function` interface are generic, so that it can be used in different types of function-like interfaces.

Related changes:

- Renamed `LambdifiedFunction` to `ParametrizedBackendFunction`.
- `DataTransformer.transform()` has become a `__call__` and `DataTransformer` derives from `Function`.
- `Estimator` also derives from `Function`: it computes an estimator value for a set of parameters.

</details>

<details>
<summary>Generalized data generation interface (392)</summary>

Large refactoring of the `data` module with the aim to generalize its hit-and-miss mechanisms to general domain `DataSample` types.

Interface changes

- **Removed `generate_data()` and `generate_phsp()` façade functions.** The new way to generate phase space and hit-and-miss data samples is:

python
from tensorwaves.data import IntensityDistributionGenerator
from tensorwaves.data.phasespace import TFPhaseSpaceGenerator
from tensorwaves.data.rng import TFUniformRealNumberGenerator

intensity: Function
helicity_transformer: SympyDataTransformer
rng = TFUniformRealNumberGenerator(seed=0)
phsp_generator = TFPhaseSpaceGenerator(
initial_state_mass=3.0969,
final_state_masses={0: 0.0, 1: 0.135, 2: 0.135},
)
data_generator = IntensityDistributionGenerator(
domain_generator=phsp_generator,
domain_transformer=helicity_transformer,
function=intensity,
)
phsp = phsp_generator.generate(100_000, rng)
data = data_generator.generate(10_000, rng)


- `UniformRealNumberGenerator` -> `RealNumberGenerator`
- `PhaseSpaceGenerator` -> `DataGenerator`
- `PhaseSpaceGenerator.setup()` has been merged into the constructor (`DataGenerator.__init__()`) and removed from the interface.
- Split old `TFPhaseSpaceGenerator` into an _unweighted_ `TFPhaseSpaceGenerator` (implements `DataGenerator`) and a `TFWeightedPhaseSpaceGenerator` (implements `WeightedDataGenerator`). `TFPhaseSpaceGenerator` can be used instead of the old `generate_phsp()` function.
- Collected RNGs under a new sub-module `data.rng`

New features

- New interface: `DataGenerator`, which does not generate weights as opposed to `FourMomentumGenerator`.
- `IntensityDistributionGenerator`, which should be used instead of `generate_data()`
- `IdentityTransformer`, which is just the identity implementation of a `DataTransformer`.
- `NumpyUniformRNG`

</details>

<details>
<summary>Simplified public backend signatures (362)</summary>

Only accepts a single `str` now.

</details>

πŸ› Bug fixes

<details>
<summary>Latest function call number is now also stored in Loadable callbacks (360)</summary>

</details>

<details>
<summary>CSVSummary writes estimator value as float (360)</summary>

</details>

<details>
<summary>use_cse argument is now correctly forwarded (375)</summary>

Fix-up to 374

Additional fixes:
* Enforce specifying `use_cse` argument in hidden functions.
* Remove `**kwargs` from lambdify functions. This helps mypy/pyright identify whether functions calls miss certain arguments.

</details>

πŸ”¨ Internal maintenance

<details>
<summary>Set minimal versions for sympy and pyyaml dependencies (383)</summary>

`sympy.lambdify()` doesn't work when SymPy is too old.

</details>

πŸ“ Documentation

<details>
<summary>Added GPU installation tips (381)</summary>

Preview here: https://tensorwaves--381.org.readthedocs.build/en/381/install.html

[![image](https://user-images.githubusercontent.com/29308176/145199806-c583ab2d-cddb-4aca-aadf-c0ca1631c746.png)](https://tensorwaves--381.org.readthedocs.build/en/381/install.html)

Additional improvements:

- Check link anchors with [`linkcheck_anchors = True`](https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-linkcheck_anchors).
- Removed `typing-extensions` from requirements.

</details>

<details>
<summary>Illustrated binned and unbinned fit (388)</summary>

Follow-up to 387. Generalizes the documentation with more non-PWA examples.

</details>

<details>
<summary>Merged and isolated amplitude analysis notebooks (389)</summary>

All example notebooks for amplitude analysis have been isolated under [tensorwaves.rtfd.io/en/latest/amplitude-analysis](https://tensorwaves.rtfd.io/en/latest/amplitude-analysis). Examples under **usage** show more general expressions.

Note that resource-intensive examples like the Scipy fit on an amplitude model and the fit anination have been substituted with simpler examples, which should speed up CI on the docs.

Closes 379

</details>
<details>
<summary>Added tips for expression tree optimization (390)</summary>

The amplitude analysis notebook now shows how to optimize the expression tree with SymPy, so that the fit is much faster. This also allows showing a more complicated fit, with more free parameters and larger initial offset.

</details>

πŸ–±οΈ Developer Experience

<details>
<summary>Added fast optimize test (360)</summary>

Closes 135

Adds a test under the `tests/unit` folder that fits a small model with all back-ends and optimizers plus a unit test for `generate_data`. This also helped fishing out some bugs (see [commit history](https://github.com/ComPWA/tensorwaves/pull/360/commits)).

</details>

<details>
<summary>Implemented benchmark monitoring (368)</summary>

Closes 103

Large improvements to the testing suite:

- Added benchmark tests
- If run on the main branch, the results are pushed to the [](https://github.com/ComPWA/tensorwaves/tree/benchmark-results) branch with the [continuous-benchmark](https://github.com/marketplace/actions/continuous-benchmark) action.
- The performance results per commit are visualised on [compwa.github.io/tensorwaves](https://compwa.github.io/tensorwaves).
- If run on pull request, a warning will be commented on any commit that decreases performance. Example: https://github.com/ComPWA/tensorwaves/commit/b5c1f075eff9f9b9c82e52faf22acbb81865fdc6#commitcomment-61330128
- Integration tests have been removed so that there are only unit tests (coverage of the unit tests is sufficient since 351).
- Test folder structure has been simplified: `tests/unit` moved one folder up.

</details>

0.3.7

_See all documentation for this version [here](https://tensorwaves.rtfd.io/en/0.3.7)._

πŸ’‘ New features

<details>
<summary>Optimizer and Estimator type are now written to callback output (364)</summary>

`CSVSummary` was writing `"estimator_type"` incorrectly (it was writing the optimizer type). This PR fixes that and adds the optimizer type as an additional entry, also to `YAMLSummary`.

</details>

<details>
<summary>Lambdify with common sub-expressions (374)</summary>

See `cse` argument in [`sympy.lambdify()`](https://docs.sympy.org/latest/modules/utilities/lambdify.html#sympy.utilities.lambdify.lambdify). This fixes https://github.com/ComPWA/tensorwaves/pull/345#commitcomment-61398587.

Note that lambdified source code becomes significantly smaller in larger expressions. Finding common sub-expressions has a small hit in performance when lambdifying, but in larger expressions, this is overcome by the fact that the output source code is smaller.

</details>

⚠️ Interface

<details>
<summary>Sympy implementation is now isolated in a sub-module (344)</summary>

Extracted all SymPy functionality under `tensorwaves.model` into a separate sub-module `tensorwaves.model.sympy`.

</details>

<details>
<summary>Removed doit call from SympyModel (347)</summary>

Closes 280

This means that `doit()` has to be called on the expression first.

</details>

πŸ› Bug fixes

<details>
<summary>Correct estimator value is now written to callback output (364)</summary>

`CSVSummary` was writing `"estimator_type"` incorrectly (it was writing the optimizer type). This PR fixes that and adds the optimizer type as an additional entry, also to `YAMLSummary`.

</details>

<details>
<summary>ComplexSqrt can now lambdified to TensorFlow as well (365)</summary>

JAX and TensorFlow printing is forwarded to the NumPy printer, but with `jax.numpy` and `tensorflow.experimental.numpy` as `Printer._module` respectively.

Other improvements:

- Extended tests for `find_function` and wrote a test for lambdifying AmpForm's `ComplexSqrt`
- Allow getting `tensorflow.Tensor` with `find_function`
- Moved `_backend` module to `function`, because `function` is most related to back-ends.

</details>

πŸ”¨ Internal maintenance

<details>
<summary>Swapped optimized_lambdify() implementation (348)</summary>

Closes 322

The role of `_backend_lambdify` and `_sympy_lambdify` is now swapped:

- `_backend_lambdify` is now purely a wrapper around `sympy.lambdify`.
- `_sympy_lambdify` offers a switch between `_backend_lambdify` and `optimized_lambdify`.

These functions will change further in 292, but this is PR focuses only on the problem describe din 322.

</details>

<details>
<summary>Unit tests and integration tests are now split (349)</summary>

All tests that require AmpForm have been seperated from proper unit tests (that require no additional dependencies). The folder structure under `tests` is now:

text
tests
β”œβ”€β”€ integration
└── unit


Additional improvements:

- Fixtures for the AmpForm tests have been parametrized:
- `qrules.ReactionInfo` is parametrized with the canonica-helicity and helicity formalism.
- `SympyModel` is constructed with and without `max_complexity` argument in the constructor, so that `optimized_lambdify` is tested as well.
- Improved error message of `LambdifiedFunction.update_parameters`: over-defined parameters were computed incorrectly. In addition, the error message now prints the expected parameters.
- Callbacks can now take `pathlib.Path` (previously only `str`). This makes it possible to convert the `output_dir` fixture into a `Path` as well.

</details>

<details>
<summary>Backend handling is now isolated in a sub-module (350)</summary>

344 created a module `tensorwaves.model.backend` with the intention to collect functions that handle back-ends. This PR moves `_find_function_in_backend` (which was under `tensorwaves.estimator`) there as well, moves the module to the top, and hides it altogether, as these functions are implementation details.

</details>

<details>
<summary>Add unit tests for optimized_lambdify (351)</summary>

Additional fixes:

- The faster-lambdify notebook was failing due to the interface change introduced by 348. This was not noticed, because the `%%time` statement in the cell makes the error code of that cell return 'success'. The error has been fixed and a hidden test cell has been added to prevent such failures in the future.
- `optimized_lambdify` now directly calls `_backend_lambdify` is `max_complexity` is higher than the number of nodes in the expression.

</details>

<details>
<summary>Callback output is written to separate files in the tests (352)</summary>

Integration tests have become unstable since 349, see e.g. https://github.com/ComPWA/tensorwaves/actions/runs/1504632721, because the callback output is written to the same file when using `optimized_lambdify` / `_backend_lambdify`.

</details>

<details>
<summary>Added unit tests for fast optimize (360)</summary>

Closes 135

Adds a test under the `tests/unit` folder that fits a small model with all back-ends and optimizers plus a unit test for `generate_data`. This also helped fishing out some bugs (see [commit history](https://github.com/ComPWA/tensorwaves/pull/360/commits)).

Other improvements:

- Import optimizers directly from the `tensorwaves.optimizer` module, e.g.:
python
from tensorwaves.optimizer import Minuit2

instead of
python
from tensorwaves.optimizer.minuit import Minuit2

- CSVSummary writes estimator value as float (was complex by mistake)
- Latest function call number is also stored in `Loadable` callbacks.
- Scipy now works with TF

</details>

<details>
<summary>Importing tensorwaves is now about 8x as fast (363)</summary>

Import expensive modules inline to speed up importing `tensorwaves`. This makes `import tensorwaves` (and collecting tests) about 8x as fast. Profiling done with [tuna](https://github.com/nschloe/tuna) as follows (see [stackoverflow](https://stackoverflow.com/a/51300944)):

shell
python3 -X importtime -c "import tensorwaves" 2> tw.log && tuna tw.log


</details>

<details>
<summary>Callbacks are now not run during optimize() if unspecified (366)</summary>

Previously, if no callback was specified in the optimizer constructor, an empty CallbackList would be created and on_optimize_end etc were always called. This is (theoretically) slower.

Some other improvements:

- Use [`attrs` next-generation API](https://www.attrs.org/en/stable/api.html#next-gen) (see also https://github.com/ComPWA/compwa-org/issues/90).
- Avoid creating stream on creation of Loadable callback.
- Fail pytest on warnings (this helped fishing out the above bug)

</details>

<details>
<summary>Generalized SymPy printer implementation (371)</summary>

</details>

πŸ“ Documentation

<details>
<summary>Added API links to FitResult.specifics (356)</summary>

Added links to the 'fit result' objects in the `iminuit` and SciPy APIs.

</details>

πŸ–±οΈ Developer Experience

<details>
<summary>Pytest on GitHub Actions is now stable (355)</summary>

Fix-up to 349

Writing with a callback in a pytest fixture and then loading it back in a test led to instable CI. This PR should fix that.

</details>

<details>
<summary>Notebooks can now be run with pytest (359)</summary>

Switch from [`pytest-notebook`](https://pypi.org/project/pytest-notebook) to [`nbmake`](https://pypi.org/project/nbmake). Now it's again possible to run specific notebooks from the terminal with e.g.:

shell
pytest --nbmake docs/usage/basics.ipynb


Other small fixes:

- Avoid `fast_lambdify()` in Jupyter notebooks to speed up docs workflow.
- Cast to `tuple` in `ParametrizedBackendFunction`.

</details>

<details>
<summary>Merge test jobs on GitHub Actions (367)</summary>

Reorganise GitHub Action workflow for pytest. Extracted from 366 in order to identify potential performance issues. Notebooks slow after the changes introduced in 366, which may be caused by the changes to the callbacks.

Other changes;

- Treat warnings raised under pytest as errors.
- Renamed tox job for testing notebooks to `nb`.

</details>

<details>
<summary>Reduced dependencies in style requirements (369)</summary>

Should speed up [pre-commit job](https://github.com/ComPWA/tensorwaves/actions/workflows/ci-style.yml).

</details>

<details>
<summary>Pytest collect is now faster (370)</summary>

Import expensive modules in the tests inline so that `pytest --collect-only` is faster.

</details>

0.3.4

_See all documentation for this version [here](https://tensorwaves.rtfd.io/en/0.3.4)._

πŸ”¨ Internal maintenance

<details>
<summary>Narrowed down type hints (332)</summary>

* Improved some of the type hints
* Enforcing the use of [mypy error codes](https://mypy.readthedocs.io/en/stable/error_codes.html#silencing-errors-based-on-error-codes) (` type: ignore[error-code]`) with [flake8-type-ignore](https://gitlab.com/jonafato/flake8-type-ignore).

</details>

<details>
<summary>TF2.7 is now supported (338)</summary>


</details>


πŸ“ Documentation

<details>
<summary>Added back analytic continuation notebook (312)</summary>

</details>

<details>
<summary>Added Zenodo DOI badge (326)</summary>

[![Zenodo DOI](https://zenodo.org/badge/doi/10.5281/zenodo.5526650.svg)](https://doi.org/10.5281/zenodo.5526650)

</details>

<details>
<summary>Added Conda install instructions and Conda badge (333)</summary>

[![Anaconda-Server Badge](https://anaconda.org/conda-forge/tensorwaves/badges/version.svg)](https://anaconda.org/conda-forge/tensorwaves)

</details>

<details>
<summary>Links to Binder and Colab now point to the branch that corresponds to the version of the documentation (339)</summary>

* docs: pin more intersphinx pages
* fix: correct intersphinx links that were not previously checked
* fix: exclude version 'module' from API
* fix: move docstrings from __init__ to class definition
* refactor: get intersphinx version through function
* style: capitalize conf.py global vars that are no Sphinx options

</details>

<details>
<summary>Intersphinx pages now link to the pinned versions of dependency websites (339)</summary>

</details>


πŸ–±οΈ Developer Experience

<details>
<summary>Embeded Zenodo metadata (329)</summary>

</details>
<details>
<summary>Fixed comment syntax in .flake8 (334)</summary>

The `.flake8` config file was using not using the same comment style as described in
https://flake8.pycqa.org/en/latest/user/configuration.html#project-configuration
Consequence not all errors were identified anymore.

</details>

<details>
<summary>Removed redundant metadata from notebooks (337 and 340)</summary>

</details>

0.3.3

_See all documentation for this version [here](https://tensorwaves.rtfd.io/en/0.3.3)._

_Release for first Zenodo DOI_
[![Zenodo DOI](https://zenodo.org/badge/doi/10.5281/zenodo.5526650.svg)](https://doi.org/10.5281/zenodo.5526650)


πŸ’‘ New features

<details>
<summary>Upgraded to TensorFlow v2.6 (320)</summary>

</details>

πŸ“ Documentation

<details>
<summary>Documentation pages are wider (316)</summary>

See ComPWA/ampform104

</details>

<details>
<summary>Embeded GPLv3+ license file (318)</summary>

Some platforms like Zenodo and conda-forge require the license file to be packaged.

</details>

<details>
<summary>Extended package description in README (319)</summary>

</details>

<details>
<summary>Added package description for PyPI (324)</summary>

Closes https://github.com/ComPWA/compwa-org/issues/61

Automated changes by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action

</details>

πŸ”¨ Internal maintenance

<details>
<summary>Removed mdit-py-plugins version limit (313)</summary>

See https://github.com/ComPWA/ampform/pull/147

</details>

πŸ–±οΈ Developer Experience

<details>
<summary>Switched to pre-commit.ci where possible (321)</summary>

See ComPWA/qrules87

Note https://github.com/ComPWA/tensorwaves/pull/309#issuecomment-908152365. This comment is still relevant.

</details>

0.3.2

_See all documentation for this version [here](https://tensorwaves.rtfd.io/en/0.3.2)._

πŸ› Bug fixes

<details>
<summary>Now using syntax for setting pip version constraints (311)</summary>

Fix-up to 310

https://github.com/ComPWA/tensorwaves/blob/57f6ec0f04e0afc0cebcc955783d20cde2646be6/setup.cfg#L44

resulted in version conflicts downstream. AmpForm is now also correctly updated: 626abe1.

</details>

0.3.1

_See all documentation for this version [here](https://tensorwaves.rtfd.io/en/0.3.1)._

πŸ”¨ Internal maintenance

<details>
<summary>Allow installing AmpForm v0.11.x (310)</summary>

Page 4 of 7

Β© 2025 Safety CLI Cybersecurity Inc. All Rights Reserved.