Constraints
Constraints are a fundamental component in non-trivial fitting operations. They can also be used to affirm the minimum/maximum of a parameter or tie parameters together in a model.
Anatomy of a constraint
A constraint is a rule which is applied to a dependent variable. This rule can consist of a logical operation, relation to one or more independent variables or an arbitrary function.
Constraints on Parameters
easyCore.Objects.Base.Parameter
has the properties builtin_constraints and user_constraints. These are dictionaries which correspond to constraints which are intrinsic and extrinsic to the Parameter. This means that on the value change of the Parameter firstly the builtin_constraints are evaluated, followed by the user_constraints.
Constraints on Fitting
easyCore.Fitting.Fitting.Fitter
has the ability to evaluate user supplied constraints which effect the value of both fixed and non-fixed parameters. A good example of one such use case would be the ratio between two parameters, where you would create a easyCore.Fitting.Constraints.ObjConstraint
.
Using constraints
A constraint can be used in one of three ways; Assignment to a parameter, assignment to fitting or on demand. The first two are covered and on demand is shown below.
from easyCore.Fitting.Constraints import NumericConstraint
from easyCore.Objects.Base import Parameter
# Create an `a < 1` constraint
a = Parameter('a', 0.5)
constraint = NumericConstraint(a, '<=', 1)
# Evaluate the constraint on demand
a.value = 5.0
constraint()
# A will now equal 1
Constraint Reference
Examples using Constraints
Built-in constraints
These are the built in constraints which you can use
- class easyCore.Fitting.Constraints.SelfConstraint(dependent_obj, operator, value)[source]
A SelfConstraint is a constraint which tests a logical constraint on a property of itself, similar to a NumericConstraint. i.e. a > a.min.
- Parameters:
- Example:
from easyCore.Fitting.Constraints import SelfConstraint from easyCore.Objects.Base import Parameter # Create an `a < a.max` constraint a = Parameter('a', 0.2, max=1) constraint = SelfConstraint(a, '<=', 'max') a.user_constraints['MAX'] = constraint # This works a.value = 0.85 # This triggers the constraint a.value = 2.0 # `a` is set to the maximum of the constraint (`a = 1`)
- class easyCore.Fitting.Constraints.NumericConstraint(dependent_obj, operator, value)[source]
A NumericConstraint is a constraint whereby a dependent parameters value is something of an independent parameters value. I.e. a < 1, a > 5
- Parameters:
- Example:
from easyCore.Fitting.Constraints import NumericConstraint from easyCore.Objects.Base import Parameter # Create an `a < 1` constraint a = Parameter('a', 0.2) constraint = NumericConstraint(a, '<=', 1) a.user_constraints['LEQ_1'] = constraint # This works a.value = 0.85 # This triggers the constraint a.value = 2.0 # `a` is set to the maximum of the constraint (`a = 1`)
- class easyCore.Fitting.Constraints.ObjConstraint(dependent_obj, operator, independent_obj)[source]
A ObjConstraint is a constraint whereby a dependent parameter is something of an independent parameter value. E.g. a (Dependent Parameter) < b (Independent Parameter)
- Parameters:
- Example:
from easyCore.Fitting.Constraints import ObjConstraint from easyCore.Objects.Base import Parameter # Create an `a = 2 * b` constraint a = Parameter('a', 0.2) b = Parameter('b', 1) constraint = ObjConstraint(a, '2*', b) b.user_constraints['SET_A'] = constraint b.value = 1 # This triggers the constraint a.value # Should equal 2
- class easyCore.Fitting.Constraints.FunctionalConstraint(dependent_obj, func, independent_objs=None)[source]
Functional constraints do not depend on other parameters and as such can be more complex.
- Parameters:
- Example:
import numpy as np from easyCore.Fitting.Constraints import FunctionalConstraint from easyCore.Objects.Base import Parameter a = Parameter('a', 0.2, max=1) constraint = FunctionalConstraint(a, np.abs) a.user_constraints['abs'] = constraint # This triggers the constraint a.value = 0.85 # `a` is set to 0.85 # This triggers the constraint a.value = -0.5 # `a` is set to 0.5
- class easyCore.Fitting.Constraints.MultiObjConstraint(independent_objs, operator, dependent_obj, value)[source]
A MultiObjConstraint is similar to
easyCore.Fitting.Constraints.ObjConstraint
except that it relates to one or more independent objects.E.g. * a (Dependent Parameter) + b (Independent Parameter) = 1 * a (Dependent Parameter) + b (Independent Parameter) - 2*c (Independent Parameter) = 0
- Parameters:
- Example:
a + b = 1
from easyCore.Fitting.Constraints import MultiObjConstraint from easyCore.Objects.Base import Parameter # Create an `a + b = 1` constraint a = Parameter('a', 0.2) b = Parameter('b', 0.3) constraint = MultiObjConstraint([b], ['+'], a, 1) b.user_constraints['SET_A'] = constraint b.value = 0.4 # This triggers the constraint a.value # Should equal 0.6
a + b - 2c = 0
from easyCore.Fitting.Constraints import MultiObjConstraint from easyCore.Objects.Base import Parameter # Create an `a + b - 2c = 0` constraint a = Parameter('a', 0.5) b = Parameter('b', 0.3) c = Parameter('c', 0.1) constraint = MultiObjConstraint([b, c], ['+', '-2*'], a, 0) b.user_constraints['SET_A'] = constraint c.user_constraints['SET_A'] = constraint b.value = 0.4 # This triggers the constraint. Or it could be triggered by changing the value of c a.value # Should equal 0.2
Note
This constraint is evaluated as
dependent
=value
- SUM(operator_i
independent_i
)
User created constraints
You can also make your own constraints by subclassing the easyCore.Fitting.Constraints.ConstraintBase
class. For this at a minimum the abstract methods _parse_operator
and __repr__
need to be written.
- class easyCore.Fitting.Constraints.ConstraintBase(dependent_obj, independent_obj=None, operator=None, value=None)[source]
A base class used to describe a constraint to be applied to easyCore base objects.
- abstract _parse_operator(obj, *args, **kwargs)[source]
Abstract method which contains the constraint logic
- property enabled: bool
Is the current constraint enabled.
- Return type:
- Returns:
Logical answer to if the constraint is enabled.