Source code for secml.optim.constraints.c_constraint

"""
.. module:: CConstraint
   :synopsis: Interface for equality/inequality constraints
                in the canonic form c(x) <= 0

.. moduleauthor:: Battista Biggio <battista.biggio@unica.it>

"""
from abc import ABCMeta, abstractmethod

from secml.core import CCreator
from secml.array import CArray


[docs]class CConstraint(CCreator, metaclass=ABCMeta): """Interface for equality/inequality constraints.""" __super__ = 'CConstraint'
[docs] def is_active(self, x, tol=1e-4): """Returns True if constraint is active. A constraint is active if c(x) = 0. By default we assume constraints of the form c(x) <= 0. Parameters ---------- x : CArray Input sample. tol : float, optional Tolerance to use for comparing c(x) against 0. Default 1e-4. Returns ------- bool True if constraint is active, False otherwise. """ if not x.is_vector_like: raise ValueError("only a vector-like array is accepted") if abs(self._constraint(x)) <= tol: return True return False
[docs] def is_violated(self, x): """Returns the violated status of the constraint for the sample x. We assume the constraint violated if c(x) <= 0. Parameters ---------- x : CArray Input sample. Returns ------- bool True if constraint is violated, False otherwise. """ if not x.is_vector_like: raise ValueError("only a vector-like array is accepted") if self._constraint(x) > 0: return True return False
@abstractmethod def _constraint(self, x): """Returns the value of the constraint for the sample x. Parameters ---------- x : CArray Input sample. Returns ------- float Value of the constraint. """ raise NotImplementedError
[docs] def constraint(self, x): """Returns the value of the constraint for the sample x. Parameters ---------- x : CArray Input sample. Returns ------- float Value of the constraint. """ if not x.is_vector_like: raise ValueError("only a vector-like array is accepted") return float(self._constraint(x))
@abstractmethod def _projection(self, x): """Project x onto feasible domain / within the given constraint. Parameters ---------- x : CArray Input sample. Returns ------- CArray Projected x onto feasible domain if constraint is violated. """ raise NotImplementedError
[docs] def projection(self, x): """Project x onto feasible domain / within the given constraint. If constraint is not violated by x, x is returned. Parameters ---------- x : CArray Input sample. Returns ------- CArray Projected x onto feasible domain if constraint is violated. Otherwise, x is returned as is. """ if not x.is_vector_like: raise ValueError("only a vector-like array is accepted") if self.is_violated(x) is True: self.logger.debug("Constraint violated, projecting...") x = self._projection(x.ravel()) return x.ravel()
# This is not abstract as some constraints may not be differentiable def _gradient(self, x): """Returns the gradient of c(x) in x. Parameters ---------- x : CArray Input sample. Returns ------- CArray The gradient of the constraint computed on x. """ raise NotImplementedError
[docs] def gradient(self, x): """Returns the gradient of c(x) in x. Parameters ---------- x : CArray Input sample. Returns ------- CArray The gradient of the constraint computed on x. """ if not x.is_vector_like: raise ValueError("only a vector-like array is accepted") return self._gradient(x).ravel()