Esempio n. 1
0
    def distance_squared(self, u):
        idx1 = self.idx_infinite_only_xmin()
        idx2 = self.idx_infinite_only_xmax()
        idx3 = self.idx_bound_finite_all()

        dist_sq = 0.0
        for i in idx1:
            dist_sq += fn.fmax(0.0, u[i] - self.__xmax[i])**2

        for i in idx2:
            dist_sq += fn.fmin(0.0, u[i] - self.__xmin[i])**2

        for i in idx3:
            dist_sq += fn.fmin(fn.fmax(0.0, u[i] - self.__xmax[i]),
                               u[i] - self.__xmin[i])**2

        return dist_sq
Esempio n. 2
0
    def distance_squared(self, u):
        """Computes the squared distance between a given point `u` and this ball

            :param u: given point; can be a list of float, a numpy
                n-dim array (`ndarray`) or a CasADi SX/MX symbol

            :return: distance from set as a float or a CasADi symbol
        """
        if fn.is_symbolic(u):
            # Case I: `u` is a CasADi SX symbol
            v = u if self.__center is None else u - self.__center
        elif (isinstance(u, list) and all(isinstance(x, (int, float)) for x in u))\
                or isinstance(u, np.ndarray):
            # Case II: `u` is an array of numbers or an np.ndarray
            if self.__center is None:
                v = u
            else:
                # Note: self.__center is np.ndarray (`u` might be a list)
                z = self.__center.reshape(len(u))
                u = np.array(u).reshape(len(u))
                v = np.subtract(u, z)
        else:
            raise Exception("u is of invalid type")

        # Compute squared distance
        # Let B = B(xc, r) be a Euclidean ball centered at xc with radius r
        #
        # dist_B^2(u) = max(0, sign(t(u))*t(u)^2), where
        # t(u) = ||u - x_c|| - r
        #
        # Note: there is another way to take squared distances:
        # d_B^2(u) = ||u||^2 * (1 - 1 / max{r, ||u||})^2,
        # but this leads to slightly lengthier CasADi symbols for
        # the Jacobian of the squared distance, so this approach was
        # abandoned
        t = fn.norm2(v) - self.radius
        return fn.fmax(0.0, fn.sign(t) * t ** 2)