/
001.md
146 lines (118 loc) · 6.81 KB
/
001.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!-- cspell:ignore amplitf lambdify -->
# [ADR-001] Amplitude model
- **Status**: accepted
- **Deciders**: @redeboer @spflueger
## Context and problem statement
From the perspective of a PWA fitter package, the responsibility of the
{mod}`expertsystem` is to construct a `AmplitudeModel` that serves as blueprint for a
function that can be evaluated. Such a **function** has the following requirements:
1. It should be able to compute a list of real-valued intensities $\mathbb{R}^m$ from a
dataset of four-momenta $\mathbb{R}^{m\times n\times4}$, where $m$ is the number of
events and $n$ is the number of final state particles.
2. It should contain **parameters** that can be tweaked, so that they can be optimized
with regard to a certain estimator.
### Technical story
- [ComPWA/ampform#5](https://github.com/ComPWA/ampform/issues/5): Coupling parameters in the `AmplitudeModel` is difficult
(has to be done through the place where they are used in the `dynamics` or `intensity`
section) and counter-intuitive (cannot be done through the `parameters` section)
- [ComPWA/expertsystem#440](https://github.com/ComPWA/expertsystem/issues/440): when overwriting existing dynamics, old parameters
are not cleaned up from the `parameters` section
- [ComPWA/expertsystem#441](https://github.com/ComPWA/expertsystem/issues/441): parameters contain a name that can be changed, but
that results in a mismatch between the key that is used in the `parameters` section
and the name of the parameter to which that entry points.
- [ComPWA/ComPWA-legacy#226](https://github.com/ComPWA/ComPWA-legacy/issues/226): Use a math language for the blueprint of the function. This
was also discussed early to mid 2020, but dropped in favor of custom python code +
`amplitf`. The reasoning was that the effort of writing some new math language plus
generators converting a mathematical expression into a function (using various
back-ends) requires too much manpower.
## Decision drivers
### Solution requirements
1. The `AmplitudeModel` has to be convertible to a function which can be **evaluated
using various computation back-ends** (numpy, tensorflow, theano, jax, ...)
2. Ideally, the model should be complete in the sense that it contains all information
to construct the complete model. This means that some "common" functions like a
Breit-Wigner and Blatt-Weisskopf form factors should also be contained inside the
`AmplitudeModel`. This guarantees **reproducibility**!
3. Adding new operators/models should not trigger many code modifications
([open-closed principle](https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle)),
for instance adding new dynamics or formalisms.
4. Extendible:
- Add or replace current parts of an existing model. For example replace the dynamics
part of some decay.
- Change a function plus a dataset to an estimator function. This is a subtle but
important point. The function should hide its details (which backend and its
mathematical expression) and yet be extendable to an estimator.
5. Definition and easy extraction of components. Components are certain sub-parts of the
complete mathematical expression. This is at least needed for the calculation of fit
fractions, or plotting individual parts of the intensity.
## Considered solutions
### Customized Python classes
Currently ([v0.6.8](https://expertsystem.readthedocs.io/en/0.6.8)), the
[`AmplitudeModel`](https://expertsystem.readthedocs.io/en/0.6.8/api/expertsystem.amplitude.model.html#expertsystem.amplitude.model.AmplitudeModel)
contains five **sections** (instances of specific classes):
- `kinematics`: defines initial and final state
- `particles`: particle definitions (spin, etc.)
- `dynamics`: a mapping that defines which dynamics type to apply to which particle
- `intensity`: the actual amplitude model that is to be converted by a fitter package
into a function as described above
- `parameters`: an inventory of parameters that are used in `intensity` and `dynamics`
This structure can be represented in YAML, see an example
[here](https://github.com/ComPWA/expertsystem/blob/f4f1c55/tests/unit/io/expected_recipe.yml).
A fitter package converts `intensity` together with `dynamics` into a function. Any
references to parameters that `intensity` or `dynamics` contain are converted into a
parameter of the function. The parameters are initialized with the value as listed in
the `parameters` section of the `AmplitudeModel`.
### Alternative solutions
```{toctree}
---
maxdepth: 1
---
001/sympy
001/operators
```
## Evaluation
### Pros and Cons
#### Customized Python classes (current state)
- **Positive**
- "Faster" implementation / prototyping possible compared to python operators
- No additional dependencies
- **Negative**
- Not open-closed to new models
- Conversion to various back-ends not DRY
- Function replacement or extension feature becomes very difficult to handle.
- Model is not complete, since no complete mathematical description is used. For
example Breit-Wigner functions are referred to directly and their implementations is
not defined in the amplitude model.
#### {doc}`SymPy <001/sympy>`
- **Positive**
- Easy to render amplitude model as LaTeX
- Model description is complete! Absolutely all information about the model is
included. (reproducibility)
- Follows open-closed principle. New models and formalism can be added without any
changes to other interfacing components (here: `tensorwaves`)
- Use
[`lambdify`](https://docs.sympy.org/latest/tutorial/basic_operations.html#lambdify)
to convert the expression to any back-end
- Use
[`Expr.subs`](https://docs.sympy.org/latest/modules/core.html#sympy.core.basic.Basic.subs)
(substitute) to couple parameters or replace components of the model, for instance
to set custom dynamics
- **Negative**
- `lambdify` becomes a core dependency while its behavior cannot be modified, but is
defined by `sympy`.
- Need to keep track of components in the expression tree with symbol mappings
#### {doc}`Python's operator library <001/operators>`
- **Positive**
- More control over different components of in the expression tree
- More control over convert functionality to functions
- No additional dependencies
- **Negative**
- Essentially re-inventing SymPy
## Decision outcome
Use {doc}`001/sympy`. Initially, we leave the existing amplitude builders (modules
[`helicity_decay`](https://expertsystem.readthedocs.io/en/0.6.8/api/expertsystem.amplitude.helicity_decay.html)
and
[`canonical_decay`](https://expertsystem.readthedocs.io/en/0.6.8/api/expertsystem.amplitude.canonical_decay.html))
alongside a SymPy implementation, so that it's possible to compare the results. Once it
turns out the this set-up results in the same results and a comparable performance, we
replace the old amplitude builders with the new SymPy implementation.