Source code for

from __future__ import division

import numpy as np
from scipy.spatial.distance import pdist

from .domain import TOL
from .linineq import LinIneqDomain
from ..exceptions import EmptyDomainException

[docs]class BoxDomain(LinIneqDomain): r""" Implements a domain specified by box constraints Given a set of lower and upper bounds, this class defines the domain .. math:: \mathcal{D} := \lbrace \mathbf{x} \in \mathbb{R}^m : \text{lb} \le \mathbf{x} \le \text{ub} \rbrace \subset \mathbb{R}^m. Parameters ---------- lb: array-like (m,) Lower bounds ub: array-like (m,) Upper bounds """ def __init__(self, lb, ub, names = None): LinIneqDomain.__init__(self, lb = lb, ub = ub, names = names) #assert np.all(np.isfinite(lb)) and np.all(np.isfinite(ub)), "Both lb and ub must be finite to construct a box domain" @property def is_empty(self): try: return self._empty except AttributeError: self._empty = np.any( > self.ub) self._point = False self._unbounded = False return self._empty @property def is_point(self): try: return self._point except AttributeError: self._point = np.all(np.abs(self.ub - < TOL) return self._point @property def is_unbounded(self): try: return self._unbounded except AttributeError: self._unbounded = np.any(np.isinf( | np.any(np.isinf(self.ub)) return self._unbounded # Due to the simplicity of this domain, we can use a more efficient sampling routine def _sample(self, draw = 1): if self.is_empty: raise EmptyDomainException x_sample = np.random.uniform(, self.ub, size = (draw, len(self))) return x_sample def _corner(self, p, **kwargs): # Since the domain is a box, we can find the corners simply by looking at the sign of p x = np.copy( I = (p>=0) x[I] = self.ub[I] if not self.isinside(x): raise EmptyDomainException return x def _extent(self, x, p): return self._extent_bounds(x, p) def _isinside(self, X, tol = TOL): return self._isinside_bounds(X, tol = tol) def _normalized_domain(self, **kwargs): names_norm = [name + ' (normalized)' for name in self.names] return BoxDomain(lb = self.lb_norm, ub = self.ub_norm, names = names_norm) @property def A(self): return np.zeros((0,len(self))) @property def b(self): return np.zeros((0)) @property def A_eq(self): return np.zeros((0,len(self))) @property def b_eq(self): return np.zeros((0))