Parameter¶
Several objects in zfit, most importantly models, have one or more parameter which typically parametrise a function or distribution. There are two different kinds of parameters in zfit:
- Independent: can be changed in a fit (or explicitly be set to fixed).
- Dependent: cannot be directly changed but _may_ depend on independent parameters.
Independent Parameter¶
To create a parameter that can be changed, e.g., to fit a model, a Parameter
has to
be instantiated.
The syntax is as follows:
param1 = zfit.Parameter("param_name_human_readable", start_value[, lower_limit, upper_limit])
Parameter
can have limits (tested with has_limits()
), which will
clip the value to the limits given by lower_limit()
and
upper_limit()
.
While this closely follows the RooFit syntax, it is very important to note that the optional limits of the parameter behave differently:
if not given, the parameter will be “unbounded”, not fixed.
Parameters are therefore floating by default, but their value can be fixed by setting the attribute floating
to False
.
The value of the parameter can be changed with the set_value()
method.
Using this method as a context manager, the value can also temporarily changed.
However, be aware that anything _dependent_ on the parameter will have a value with the
parameter evaluated with the new value at run-time:
>>> mu = zfit.Parameter("mu_one", 1) # no limits
>>> with mu.set_value(3):
... # in here, mu has the value 3
... mu_val = zfit.run(mu) # 3
... five_mu = 5 * mu
... five_mu_val = zfit.run(five_mu) # is evaluated with mu = 5. -> five_mu_val is 15
>>> # here, mu is again 1
>>> mu_val_after = zfit.run(mu) # 1
>>> five_mu_val_after = zfit.run(five_mu) # is evaluated with mu = 1! -> five_mu_val_after is 5
Dependent Parameter¶
A parameter can be composed of several other parameters. We can use any Tensor
for that
and the dependency will be detected automatically. They can be used equivalently to Parameter
.
>>> mu2 = zfit.Parameter("mu_two", 7)
>>> dependent_tensor = mu * 5 + mu2 # or any kind of computation
>>> dep_param = zfit.ComposedParameter("dependent_param", dependent_tensor)
>>> dependents = dep_param.get_dependents_auto() # returns set(mu, mu2)
A special case of the above is ComplexParameter
: it takes a complex tf.Tensor
as input and provides a few special methods (like real()
, ComplexParameterconj()
etc.) to easier deal with them.
Additionally, the from_cartesian()
and from_polar()
methods can be used to initialize polar parameters from floats, avoiding the need of creating complex tf.Tensor
objects.