Constraints
log_barrier(lhs, comparison, rhs, *, penalty_sign, sharpness=1.0, inf=None)
¶
Return a penalty based on how close the constraint is to being violated.
If the left-hand-side is equal to the right-hand-side, or if the constraint
is violated, the returned penalty will be infinite (+inf
or -inf
,
depending on penalty_sign
). Such inf
values can result in numerical
instabilities. To overcome such instabilities, you might want to set the
keyword argument inf
as a large-enough finite positive quantity M
, so
that very large (or infinite) penalties will be clipped down to M
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
lhs |
Union[float, torch.Tensor] |
The left-hand-side of the constraint. In the non-batched case, this is expected as a scalar. If it is given as an n-dimensional tensor where n is at least 1, this is considered as a batch of left-hand-side values. |
required |
comparison |
str |
The operator used for comparing the left-hand-side and the right-hand-side. Expected as a string. Acceptable values are: '<=', '>='. |
required |
rhs |
Union[float, torch.Tensor] |
The right-hand-side of the constraint. In the non-batched case, this is expected as a scalar. If it is given as an n-dimensional tensor where n is at least 1, this is considered as a batch of right-hand-side values. |
required |
penalty_sign |
str |
Expected as string, either as '+' or '-', which
determines the sign of the penalty (i.e. determines if the penalty
will be positive or negative). One should consider the objective
sense of the fitness function at hand for deciding |
required |
sharpness |
Union[float, torch.Tensor] |
The logarithmic penalty will be divided by this number. By default, this value is 1. A sharper log-penalization allows the constraint to get closer to its boundary, and then makes a more sudden jump towards infinity. |
1.0 |
inf |
Union[float, torch.Tensor] |
When concerned about the possible numerical instabilities caused
by infinite penalties, one can specify a finite large-enough
positive quantity |
None |
Returns:
Type | Description |
---|---|
Tensor |
Log-penalty amount(s), whose sign(s) is/are determined by
|
Source code in evotorch/tools/constraints.py
def log_barrier(
lhs: Union[float, torch.Tensor],
comparison: str,
rhs: Union[float, torch.Tensor],
*,
penalty_sign: str,
sharpness: Union[float, torch.Tensor] = 1.0,
inf: Optional[Union[float, torch.Tensor]] = None,
) -> torch.Tensor:
"""
Return a penalty based on how close the constraint is to being violated.
If the left-hand-side is equal to the right-hand-side, or if the constraint
is violated, the returned penalty will be infinite (`+inf` or `-inf`,
depending on `penalty_sign`). Such `inf` values can result in numerical
instabilities. To overcome such instabilities, you might want to set the
keyword argument `inf` as a large-enough finite positive quantity `M`, so
that very large (or infinite) penalties will be clipped down to `M`.
Args:
lhs: The left-hand-side of the constraint. In the non-batched case,
this is expected as a scalar. If it is given as an n-dimensional
tensor where n is at least 1, this is considered as a batch of
left-hand-side values.
comparison: The operator used for comparing the left-hand-side and the
right-hand-side. Expected as a string. Acceptable values are:
'<=', '>='.
rhs: The right-hand-side of the constraint. In the non-batched case,
this is expected as a scalar. If it is given as an n-dimensional
tensor where n is at least 1, this is considered as a batch of
right-hand-side values.
penalty_sign: Expected as string, either as '+' or '-', which
determines the sign of the penalty (i.e. determines if the penalty
will be positive or negative). One should consider the objective
sense of the fitness function at hand for deciding `penalty_sign`.
For example, if a fitness function is written from the perspective
of maximization, the penalties should be negative, and therefore,
`penalty_sign` must be given as '-'.
sharpness: The logarithmic penalty will be divided by this number.
By default, this value is 1. A sharper log-penalization allows
the constraint to get closer to its boundary, and then makes
a more sudden jump towards infinity.
inf: When concerned about the possible numerical instabilities caused
by infinite penalties, one can specify a finite large-enough
positive quantity `M` through this argument. As a result,
infinite penalties will be clipped down to the finite `M`.
One might also think of this as temporarily replacing `inf` with
`M` while computing the log-penalties.
Returns:
Log-penalty amount(s), whose sign(s) is/are determined by
`penalty_sign`.
"""
from ..decorators import expects_ndim
if inf is None:
inf = float("inf")
return expects_ndim(_log_barrier, (0, None, 0, 0, None, 0))(lhs, comparison, rhs, sharpness, penalty_sign, inf)
penalty(lhs, comparison, rhs, *, penalty_sign, linear=None, step=None, exp=None, exp_inf=None)
¶
Return a penalty based on the amount of violation of the constraint.
Depending on the provided arguments, the penalty can be linear, or exponential, or based on step function, or a combination of these.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
lhs |
Union[float, torch.Tensor] |
The left-hand-side of the constraint. In the non-batched case, this is expected as a scalar. If it is given as an n-dimensional tensor where n is at least 1, this is considered as a batch of left-hand-side values. |
required |
comparison |
str |
The operator used for comparing the left-hand-side and the right-hand-side. Expected as a string. Acceptable values are: '<=', '==', '>='. |
required |
rhs |
Union[float, torch.Tensor] |
The right-hand-side of the constraint. In the non-batched case, this is expected as a scalar. If it is given as an n-dimensional tensor where n is at least 1, this is considered as a batch of right-hand-side values. |
required |
penalty_sign |
str |
Expected as string, either as '+' or '-', which
determines the sign of the penalty (i.e. determines if the penalty
will be positive or negative). One should consider the objective
sense of the fitness function at hand for deciding |
required |
linear |
Union[float, torch.Tensor] |
Multiplier for the linear component of the penalization. If omitted (i.e. left as None), the value of this multiplier will be 0 (meaning that there will not be any linear penalization). In the non-batched case, this argument is expected as a scalar. If this is provided as a tensor 1 or more dimensions, those dimensions will be considered as batch dimensions. |
None |
step |
Union[float, torch.Tensor] |
The constant amount that will be added onto the penalty if there is a violation. If omitted (i.e. left as None), this value is 0. In the non-batched case, this argument is expected as a scalar. If this is provided as a tensor 1 or more dimensions, those dimensions will be considered as batch dimensions. |
None |
exp |
Union[float, torch.Tensor] |
A constant |
None |
exp_inf |
Union[float, torch.Tensor] |
Upper bound for exponential penalty values. If exponential
penalty is enabled but |
None |
Returns:
Type | Description |
---|---|
Tensor |
The penalty amount(s), whose sign(s) is/are determined by
|
Source code in evotorch/tools/constraints.py
def penalty(
lhs: Union[float, torch.Tensor],
comparison: str,
rhs: Union[float, torch.Tensor],
*,
penalty_sign: str,
linear: Optional[Union[float, torch.Tensor]] = None,
step: Optional[Union[float, torch.Tensor]] = None,
exp: Optional[Union[float, torch.Tensor]] = None,
exp_inf: Optional[Union[float, torch.Tensor]] = None,
) -> torch.Tensor:
"""
Return a penalty based on the amount of violation of the constraint.
Depending on the provided arguments, the penalty can be linear,
or exponential, or based on step function, or a combination of these.
Args:
lhs: The left-hand-side of the constraint. In the non-batched case,
this is expected as a scalar. If it is given as an n-dimensional
tensor where n is at least 1, this is considered as a batch of
left-hand-side values.
comparison: The operator used for comparing the left-hand-side and the
right-hand-side. Expected as a string. Acceptable values are:
'<=', '==', '>='.
rhs: The right-hand-side of the constraint. In the non-batched case,
this is expected as a scalar. If it is given as an n-dimensional
tensor where n is at least 1, this is considered as a batch of
right-hand-side values.
penalty_sign: Expected as string, either as '+' or '-', which
determines the sign of the penalty (i.e. determines if the penalty
will be positive or negative). One should consider the objective
sense of the fitness function at hand for deciding `penalty_sign`.
For example, if a fitness function is written from the perspective
of maximization, the penalties should be negative, and therefore,
`penalty_sign` must be given as '-'.
linear: Multiplier for the linear component of the penalization.
If omitted (i.e. left as None), the value of this multiplier will
be 0 (meaning that there will not be any linear penalization).
In the non-batched case, this argument is expected as a scalar.
If this is provided as a tensor 1 or more dimensions, those
dimensions will be considered as batch dimensions.
step: The constant amount that will be added onto the penalty if there
is a violation. If omitted (i.e. left as None), this value is 0.
In the non-batched case, this argument is expected as a scalar.
If this is provided as a tensor 1 or more dimensions, those
dimensions will be considered as batch dimensions.
exp: A constant `p` that will enable exponential penalization in the
form `amount_of_violation ** p`. If this is left as None or is
given as `nan`, there will be no exponential penalization.
In the non-batched case, this argument is expected as a scalar.
If this is provided as a tensor 1 or more dimensions, those
dimensions will be considered as batch dimensions.
exp_inf: Upper bound for exponential penalty values. If exponential
penalty is enabled but `exp_inf` is omitted (i.e. left as None),
the exponential penalties can jump to very large values or to
infinity, potentially causing numerical instabilities. To avoid
such numerical instabilities, one might provide a large-enough
positive constant `M` via the argument `exp_inf`. When such a value
is given, exponential penalties will not be allowed to exceed `M`.
One might also think of this as temporarily replacing `inf` with
`M` while computing the exponential penalties.
Returns:
The penalty amount(s), whose sign(s) is/are determined by
`sign_penalty`.
"""
from ..decorators import expects_ndim
if linear is None:
linear = 0.0
if step is None:
step = 0.0
if exp is None:
exp = float("nan")
if exp_inf is None:
exp_inf = float("inf")
return expects_ndim(_penalty, (0, None, 0, None, 0, 0, 0, 0))(
lhs,
comparison,
rhs,
penalty_sign,
linear,
step,
exp,
exp_inf,
)
violation(lhs, comparison, rhs)
¶
Get the amount of constraint violation.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
lhs |
Union[float, torch.Tensor] |
The left-hand-side of the constraint. In the non-batched case, this is expected as a scalar. If it is given as an n-dimensional tensor where n is at least 1, this is considered as a batch of left-hand-side values. |
required |
comparison |
str |
The operator used for comparing the left-hand-side and the right-hand-side. Expected as a string. Acceptable values are: '<=', '==', '>='. |
required |
rhs |
Union[float, torch.Tensor] |
The right-hand-side of the constraint. In the non-batched case, this is expected as a scalar. If it is given as an n-dimensional tensor where n is at least 1, this is considered as a batch of right-hand-side values. |
required |
Returns:
Type | Description |
---|---|
Tensor |
The amount of violation of the constraint. A value of 0 means that the constraint is not violated at all. The returned violation amount(s) are always non-negative. |
Source code in evotorch/tools/constraints.py
def violation(
lhs: Union[float, torch.Tensor],
comparison: str,
rhs: Union[float, torch.Tensor],
) -> torch.Tensor:
"""
Get the amount of constraint violation.
Args:
lhs: The left-hand-side of the constraint. In the non-batched case,
this is expected as a scalar. If it is given as an n-dimensional
tensor where n is at least 1, this is considered as a batch of
left-hand-side values.
comparison: The operator used for comparing the left-hand-side and the
right-hand-side. Expected as a string. Acceptable values are:
'<=', '==', '>='.
rhs: The right-hand-side of the constraint. In the non-batched case,
this is expected as a scalar. If it is given as an n-dimensional
tensor where n is at least 1, this is considered as a batch of
right-hand-side values.
Returns:
The amount of violation of the constraint. A value of 0 means that
the constraint is not violated at all. The returned violation amount(s)
are always non-negative.
"""
from ..decorators import expects_ndim
return expects_ndim(_violation, (0, None, 0))(lhs, comparison, rhs)