How to specify constraints#

Constraints vs bounds#

Estimagic distinguishes between bounds and constraints. Bounds are lower and upper bounds for parameters. In the literature they are sometimes called box constraints. Bounds are specified as “lower_bound” and “upper_bound” column of the params DataFrame. Examples with bounds can be found in first_optimization.

Constraints are more general constraints on the parameter. This ranges from rather simple ones (e.g. Parameters are fixed to a value, a group of parameters is required to be equal) to more complex ones (like general linear constraints).

General structure of constraints#

The argument constraints of the estimagic functions minimize() and maximize() can take a list with any number of constraints. Each constraint is specified with a dictionary:

constraints = [
{"loc": "a", "type": "sdcorr"},  # first constraint
{"loc": "b", "type": "fixed"},  # second constraint
]

# pass the constraints to minimize
results = minimize(
criterion_function,
params=params,
constraints=constraints,
algorithm="nlopt_bobyqa",
algo_options={"maxeval": 200},
)


The following keys are mandatory for all types of constraints:

• “loc” or “query”, but not both:

This will select the subset of parameters to which the constraint applies. If you use “loc”, the corresponding value can be any expression that is valid for DataFrame.loc. If you are not familiar with these methods, check out our tutorial on selecting parameters.

• “type”:

The type of constraint to implement.

Depending on the type of constraints, some additional entries in the constraint dictionary might be required. Below we show you how to specify constraints with simplified examples.

Examples#

In all the examples, we denote the parameters’ DataFrame by "df". Keep in mind the params DataFrame we used to explain how to select parameters, where the first-level index denotes the parameter’s category and the second-level index further characterizes the parameter: For instance, specifying the parameter’s name if multiple parameters belong to the same category, or the time period if the model is dynamic.

If you are unfamiliar with DataFrame.loc and DataFrame.query make sure that your read that explanation first!