Parameter
and Parameters
¶
This chapter describes the Parameter
object, which is a key concept of
lmfit.
A Parameter
is the quantity to be optimized in all minimization
problems, replacing the plain floating point number used in the
optimization routines from scipy.optimize
. A Parameter
has
a value that can either be varied in the fit or held at a fixed value, and
can have lower and/or upper bounds placed on the value. It can even have a
value that is constrained by an algebraic expression of other Parameter
values. Since Parameter
objects live outside the core
optimization routines, they can be used in all optimization routines
from scipy.optimize
. By using Parameter
objects instead of
plain variables, the objective function does not have to be modified to
reflect every change of what is varied in the fit, or whether bounds can be
applied. This simplifies the writing of models, allowing general models
that describe the phenomenon and gives the user more flexibility in using
and testing variations of that model.
Whereas a Parameter
expands on an individual floating point
variable, the optimization methods actually still need an ordered group of
floating point variables. In the scipy.optimize
routines this is
required to be a one-dimensional numpy.ndarray. In lmfit, this one-dimensional
array is replaced by a Parameters
object, which works as an
ordered dictionary of Parameter
objects with a few additional
features and methods. That is, while the concept of a Parameter
is central to lmfit, one normally creates and interacts with a
Parameters
instance that contains many Parameter
objects.
For example, the objective functions you write for lmfit will take an
instance of Parameters
as its first argument. A table of
parameter values, bounds, and other attributes can be printed using
Parameters.pretty_print()
.
The Parameter
class¶
- class Parameter(name, value=None, vary=True, min=-inf, max=inf, expr=None, brute_step=None, user_data=None)¶
A Parameter is an object that can be varied in a fit.
It is a central component of lmfit, and all minimization and modeling methods use Parameter objects.
A Parameter has a name attribute, and a scalar floating point value. It also has a vary attribute that describes whether the value should be varied during the minimization. Finite bounds can be placed on the Parameter’s value by setting its min and/or max attributes. A Parameter can also have its value determined by a mathematical expression of other Parameter values held in the expr attribute. Additional attributes include brute_step used as the step size in a brute-force minimization, and user_data reserved exclusively for user’s need.
After a minimization, a Parameter may also gain other attributes, including stderr holding the estimated standard error in the Parameter’s value, and correl, a dictionary of correlation values with other Parameters used in the minimization.
- Parameters:
name (str) – Name of the Parameter.
value (float, optional) – Numerical Parameter value.
vary (bool, optional) – Whether the Parameter is varied during a fit (default is True).
min (float, optional) – Lower bound for value (default is
-numpy.inf
, no lower bound).max (float, optional) – Upper bound for value (default is
numpy.inf
, no upper bound).expr (str, optional) – Mathematical expression used to constrain the value during the fit (default is None).
brute_step (float, optional) – Step size for grid points in the brute method (default is None).
user_data (optional) – User-definable extra attribute used for a Parameter (default is None).
- correl¶
A dictionary of the correlation with the other fitted Parameters of the form:
{'decay': 0.404, 'phase': -0.020, 'frequency': 0.102}
- Type:
See Bounds Implementation for details on the math used to implement the bounds with
min
andmax
.The
expr
attribute can contain a mathematical expression that will be used to compute the value for the Parameter at each step in the fit. See Using Mathematical Constraints for more details and examples of this feature.- set(value=None, vary=None, min=None, max=None, expr=None, brute_step=None, is_init_value=True)¶
Set or update Parameter attributes.
- Parameters:
value (float, optional) – Numerical Parameter value.
vary (bool, optional) – Whether the Parameter is varied during a fit.
min (float, optional) – Lower bound for value. To remove a lower bound you must use
-numpy.inf
.max (float, optional) – Upper bound for value. To remove an upper bound you must use
numpy.inf
.expr (str, optional) – Mathematical expression used to constrain the value during the fit. To remove a constraint you must supply an empty string.
brute_step (float, optional) – Step size for grid points in the brute method. To remove the step size you must use
0
.is_init_value (bool, optional) – Whether to set value as init_value, when setting value.
Notes
Each argument to set() has a default value of None, which will leave the current value for the attribute unchanged. Thus, to lift a lower or upper bound, passing in None will not work. Instead, you must set these to
-numpy.inf
ornumpy.inf
, as with:par.set(min=None) # leaves lower bound unchanged par.set(min=-numpy.inf) # removes lower bound
Similarly, to clear an expression, pass a blank string, (not None!) as with:
par.set(expr=None) # leaves expression unchanged par.set(expr='') # removes expression
Explicitly setting a value or setting
vary=True
will also clear the expression.Finally, to clear the brute_step size, pass
0
, not None:par.set(brute_step=None) # leaves brute_step unchanged par.set(brute_step=0) # removes brute_step
The Parameters
class¶
- class Parameters(usersyms=None)¶
A dictionary of Parameter objects.
It should contain all Parameter objects that are required to specify a fit model. All minimization and Model fitting routines in lmfit will use exactly one Parameters object, typically given as the first argument to the objective function.
All keys of a Parameters() instance must be strings and valid Python symbol names, so that the name must match
[a-z_][a-z0-9_]*
and cannot be a Python reserved word.All values of a Parameters() instance must be Parameter objects.
A Parameters(xs) instance includes an asteval Interpreter used for evaluation of constrained Parameters.
Parameters() support copying and pickling, and have methods to convert to and from serializations using json strings.
- Parameters:
usersyms (dict, optional) – Dictionary of symbols to add to the
asteval.Interpreter
(default is None).
- add(name, value=None, vary=True, min=-inf, max=inf, expr=None, brute_step=None)¶
Add a Parameter.
- Parameters:
name (str or Parameter) – If
name
refers to a Parameter object it will be added directly to the Parameters instance, otherwise a new Parameter object with namestring
is created before adding it. In both cases,name
must match[a-z_][a-z0-9_]*
and cannot be a Python reserved word.value (float, optional) – Numerical Parameter value, typically the initial value.
vary (bool, optional) – Whether the Parameter is varied during a fit (default is True).
min (float, optional) – Lower bound for value (default is
-numpy.inf
, no lower bound).max (float, optional) – Upper bound for value (default is
numpy.inf
, no upper bound).expr (str, optional) – Mathematical expression used to constrain the value during the fit (default is None).
brute_step (float, optional) – Step size for grid points in the brute method (default is None).
Examples
>>> params = Parameters() >>> params.add('xvar', value=0.50, min=0, max=1) >>> params.add('yvar', expr='1.0 - xvar')
which is equivalent to:
>>> params = Parameters() >>> params['xvar'] = Parameter(name='xvar', value=0.50, min=0, max=1) >>> params['yvar'] = Parameter(name='yvar', expr='1.0 - xvar')
- add_many(*parlist)¶
Add many parameters, using a sequence of tuples.
- Parameters:
*parlist (
sequence
oftuple
or Parameter) – A sequence of tuples, or a sequence of Parameter instances. If it is a sequence of tuples, then each tuple must contain at least a name. The order in each tuple must be(name, value, vary, min, max, expr, brute_step)
.
Examples
>>> params = Parameters() # add with tuples: (NAME VALUE VARY MIN MAX EXPR BRUTE_STEP) >>> params.add_many(('amp', 10, True, None, None, None, None), ... ('cen', 4, True, 0.0, None, None, None), ... ('wid', 1, False, None, None, None, None), ... ('frac', 0.5)) # add a sequence of Parameters >>> f = Parameter('par_f', 100) >>> g = Parameter('par_g', 2.) >>> params.add_many(f, g)
- pretty_print(oneline=False, colwidth=8, precision=4, fmt='g', columns=['value', 'min', 'max', 'stderr', 'vary', 'expr', 'brute_step'])¶
Pretty-print of parameters data.
- Parameters:
oneline (bool, optional) – If True prints a one-line parameters representation [False]
colwidth (int, optional) – Column width for all columns specified in columns [8]
precision (int, optional) – Number of digits to be printed after floating point [4]
fmt ({'g', 'e', 'f'}, optional) – Single-character numeric formatter. Valid values are: ‘g’ floating point and exponential (default), ‘e’ exponential, or ‘f’ floating point.
columns (
list
ofstr
, optional) – List ofParameter
attribute names to print (default is to show all attributes).
- valuesdict()¶
Return an ordered dictionary of parameter values.
- Returns:
A dictionary of
name
:value
pairs for each Parameter.- Return type:
- create_uvars(covar=None)¶
Return a dict of uncertainties ufloats from the current Parameter values and stderr, and an optionally-supplied covariance matrix. Uncertainties in Parameters with constraint expressions will be calculated, propagating uncertaintes (and including correlations)
- Parameters:
covar (optional) – Nvar x Nvar covariance matrix from fit
- Return type:
dict with keys of Parameter names and values of uncertainties.ufloats.
Notes
if covar is provide, it must correspond to the existing variable Parameters. If covar is given, the returned uncertainties ufloats will take the correlations into account when combining values.
See the uncertainties package documentation (https://pythonhosted.org/uncertainties) for more details.
- dumps(**kws)¶
Represent Parameters as a JSON string.
- Parameters:
**kws (optional) – Keyword arguments that are passed to json.dumps.
- Returns:
JSON string representation of Parameters.
- Return type:
See also
dump
,loads
,load
,json.dumps
- dump(fp, **kws)¶
Write JSON representation of Parameters to a file-like object.
- Parameters:
fp (file-like object) – An open and .write()-supporting file-like object.
**kws (optional) – Keyword arguments that are passed to dumps.
- Returns:
Return value from fp.write(): the number of characters written.
- Return type:
- eval(expr)¶
Evaluate a statement using the asteval Interpreter.
- loads(s, **kws)¶
Load Parameters from a JSON string.
- Parameters:
**kws (optional) – Keyword arguments that are passed to json.loads.
- Returns:
Updated Parameters from the JSON string.
- Return type:
Notes
Current Parameters will be cleared before loading the data from the JSON string.
See also
dump
,dumps
,load
,json.loads
- load(fp, **kws)¶
Load JSON representation of Parameters from a file-like object.
- Parameters:
fp (file-like object) – An open and .read()-supporting file-like object.
**kws (optional) – Keyword arguments that are passed to loads.
- Returns:
Updated Parameters loaded from fp.
- Return type:
Warning
Saving Parameters with user-added functions to the _asteval
interpreter using :meth::dump and dumps()
may not be easily
recovered with the load()
and loads()
. See
Saving and Loading Models for further discussion.
The create_params()
function¶
Added in version 1.2.0.
The create_params()
function is probably the easiest method for making
Parameters
objects, as it allows defining Parameter names by keyword
with values either being the numerical initial value for the Parameter or being
a dictionary with keyword/value pairs for value
as well as other Parameter
attribute such as min
, max
, expr
, and so forth.
- create_params(**kws)¶
Create lmfit.Parameters instance and set initial values and attributes.
- Parameters:
**kws – keywords are parameter names, value are dictionaries of Parameter values and attributes.
- Return type:
Parameters instance
Notes
keyword arguments will be used to create parameter names.
values can either be numbers (floats or integers) to set the parameter value, or can be dictionaries with any of the following keywords:
value
,vary
,min
,max
,expr
,brute_step
, oris_init_value
to set those parameter attributes.for each parameter,
is_init_value
controls whether to setinit_value
when settingvalue
, and defaults to True.
Examples
>>> params = create_params(amplitude=2, center=200, sigma={'value': 3, 'min':0}, fwhm={'expr': '2.0*sigma'})
Simple Example¶
A basic example making use of Parameters
and the
minimize()
function (discussed in the next chapter)
might look like this:
# <examples/doc_parameters_basic.py>
import numpy as np
from lmfit import Minimizer, Parameters, create_params, report_fit
# create data to be fitted
x = np.linspace(0, 15, 301)
np.random.seed(2021)
data = (5.0 * np.sin(2.0*x - 0.1) * np.exp(-x*x*0.025) +
np.random.normal(size=x.size, scale=0.2))
# define objective function: returns the array to be minimized
def fcn2min(params, x, data):
"""Model a decaying sine wave and subtract data."""
amp = params['amp']
shift = params['shift']
omega = params['omega']
decay = params['decay']
model = amp * np.sin(x*omega + shift) * np.exp(-x*x*decay)
return model - data
# create a set of Parameters
params = Parameters()
params.add('amp', value=10, min=0)
params.add('decay', value=0.1)
params.add('shift', value=0.0, min=-np.pi/2., max=np.pi/2.)
params.add('omega', value=3.0)
# ... or use
params = create_params(amp=dict(value=10, min=0),
decay=0.1,
omega=3,
shift=dict(value=0, min=-np.pi/2, max=np.pi/2))
# do fit, here with the default leastsq algorithm
minner = Minimizer(fcn2min, params, fcn_args=(x, data))
result = minner.minimize()
# calculate final result
final = data + result.residual
# write error report
report_fit(result)
# try to plot results
try:
import matplotlib.pyplot as plt
plt.plot(x, data, '+')
plt.plot(x, final)
plt.show()
except ImportError:
pass
# <end of examples/doc_parameters_basic.py>
Here, the objective function explicitly unpacks each Parameter value. This
can be simplified using the Parameters
valuesdict()
method,
which would make the objective function fcn2min
above look like:
def fcn2min(params, x, data):
"""Model a decaying sine wave and subtract data."""
v = params.valuesdict()
model = v['amp'] * np.sin(x*v['omega'] + v['shift']) * np.exp(-x*x*v['decay'])
return model - data
The results are identical, and the difference is a stylistic choice.