Пример #1
0
    def test_signed_curvature(self):
        # Convex argument.
        expr = cvx.abs(1 + cvx.exp(cvx.Variable()))
        self.assertEqual(expr.curvature, s.CONVEX)

        expr = cvx.abs(-cvx.entr(cvx.Variable()))
        self.assertEqual(expr.curvature, s.UNKNOWN)

        expr = cvx.abs(-cvx.log(cvx.Variable()))
        self.assertEqual(expr.curvature, s.UNKNOWN)

        # Concave argument.
        expr = cvx.abs(cvx.log(cvx.Variable()))
        self.assertEqual(expr.curvature, s.UNKNOWN)

        expr = cvx.abs(-cvx.square(cvx.Variable()))
        self.assertEqual(expr.curvature, s.CONVEX)

        expr = cvx.abs(cvx.entr(cvx.Variable()))
        self.assertEqual(expr.curvature, s.UNKNOWN)

        # Affine argument.
        expr = cvx.abs(cvx.NonNegative())
        self.assertEqual(expr.curvature, s.CONVEX)

        expr = cvx.abs(-cvx.NonNegative())
        self.assertEqual(expr.curvature, s.CONVEX)

        expr = cvx.abs(cvx.Variable())
        self.assertEqual(expr.curvature, s.CONVEX)
Пример #2
0
    def test_dcp_curvature(self):
        expr = 1 + cvx.exp(cvx.Variable())
        self.assertEqual(expr.curvature, s.CONVEX)

        expr = cvx.Parameter() * cvx.NonNegative()
        self.assertEqual(expr.curvature, s.AFFINE)

        f = lambda x: x**2 + x**0.5
        expr = f(cvx.Constant(2))
        self.assertEqual(expr.curvature, s.CONSTANT)

        expr = cvx.exp(cvx.Variable())**2
        self.assertEqual(expr.curvature, s.CONVEX)

        expr = 1 - cvx.sqrt(cvx.Variable())
        self.assertEqual(expr.curvature, s.CONVEX)

        expr = cvx.log(cvx.sqrt(cvx.Variable()))
        self.assertEqual(expr.curvature, s.CONCAVE)

        expr = -(cvx.exp(cvx.Variable()))**2
        self.assertEqual(expr.curvature, s.CONCAVE)

        expr = cvx.log(cvx.exp(cvx.Variable()))
        self.assertEqual(expr.is_dcp(), False)

        expr = cvx.entr(cvx.NonNegative())
        self.assertEqual(expr.curvature, s.CONCAVE)

        expr = ((cvx.Variable()**2)**0.5)**0
        self.assertEqual(expr.curvature, s.CONSTANT)
Пример #3
0
    def calculateEmbeddingMatrix(
        D, verbose=False, target_dist=1.1, jlt_tries=30
    ):
        assert isMetricSpaceMatrix(D)
        n = D.shape[0]
        if int(cvx.__version__.split(".")[0]) == 0:
            Q = cvx.Semidef(n)
            d = cvx.NonNegative()
        else:
            Q = cvx.Variable(shape=(n, n), PSD=True)
            d = cvx.Variable(shape=(1, 1), nonneg=True)
        # print(D)

        # c = matrix(([1]*n))
        log.debug("Generating constraints for embedding:")
        log.debug(f"Distance matrix: {D}")
        constraints = []
        for i in range(n):
            for j in range(i, n):
                constraints += [D[i, j] ** 2 <= Q[i, i] + Q[j, j] - 2 * Q[i, j]]
                constraints += [
                    Q[i, i] + Q[j, j] - 2 * Q[i, j] <= d * D[i, j] ** 2
                ]
                log.debug(
                    f"adding constraint: {D[i,j]}**2 <= Q{[i,i]} + Q{[j,j]} - 2*Q{[i,j]}"
                )
                log.debug(
                    f"adding constraint: Q{[i,i]} + Q{[j,j]} - 2*Q{[i,j]} <= d * {D[i,j]}**2 "
                )

        obj = cvx.Minimize(d)
        prob = cvx.Problem(obj, constraints)
        solvers = cvx.installed_solvers()
        if "MOSEK" in solvers:
            log.info("Solving problem with MOSEK solver")
            prob.solve(solver=cvx.MOSEK, verbose=verbose)
        elif "CVXOPT" in solvers:
            prob.solve(
                solver=cvx.CVXOPT,
                kktsolver=cvx.ROBUST_KKTSOLVER,
                verbose=verbose,
            )
            log.info("Solving problem with CVXOPT solver")
        else:
            prob.solve(verbose=verbose)
            log.warning(
                "CVXOPT not installed. Solving problem with default solver."
            )
        if prob.status != cvx.OPTIMAL:
            log.warning(
                "embedding optimization status non-optimal: " + str(prob.status)
            )
            return None, None
        # print(Q.value)
        # print(np.linalg.eigvals(np.matrix(Q.value)))
        # print(np.linalg.eigh(np.matrix(Q.value)))
        # print(type(np.matrix(Q.value)))
        # print(np.matrix(Q.value))
        try:
            L = np.linalg.cholesky(np.array(Q.value))
        except np.linalg.LinAlgError:
            eigenvals, eigenvecs = np.linalg.eigh(np.array(Q.value))
            min_eigenv = min(eigenvals)
            if min_eigenv < 0:
                log.warning(
                    "Warning, matrix not positive semidefinite."
                    + "Trying to correct for numerical errors with minimal eigenvalue: "
                    + str(min_eigenv)
                    + " (max. eigenvalue:"
                    + str(max(eigenvals))
                    + ")."
                )

                Q_new_t = (
                    np.transpose(eigenvecs) @ np.array(Q.value) @ eigenvecs
                )
                # print(eigenvals)
                # print(Q_new_t) # should be = diagonal(eigenvalues)
                # print(np.transpose(eigenvecs) * eigenvecs) # should be = Identity matrix
                Q_new_t += np.diag([-min_eigenv] * len(eigenvals))
                Q_new = eigenvecs @ Q_new_t @ np.transpose(eigenvecs)
                L = np.linalg.cholesky(Q_new)

        log.debug(f"Shape of lower-triangular matrix L: {L.shape}")
        lowerdim, d = jlt_search(D, L, target_dist, num_tries=jlt_tries)
        # print(lowerdim)
        # return L,d.value
        return lowerdim, d