Exemple #1
0
def primal_problem(q_a: np.ndarray, pperm: np.ndarray, num_reps: int) -> float:
    """
    Primal problem for counterfeit attack.

    As the primal problem takes longer to solve than the dual problem (as
    the variables are of larger dimension), the primal problem is only here
    for reference.

    :return: The optimal value of performing a counterfeit attack.
    """
    num_spaces = 3

    sys = list(range(1, num_spaces * num_reps))
    sys = [elem for elem in sys if elem % num_spaces != 0]

    # The dimension of each subsystem is assumed to be of dimension 2.
    dim = 2 * np.ones((1, num_spaces * num_reps)).astype(int).flatten()
    dim = dim.tolist()

    x_var = cvxpy.Variable((8**num_reps, 8**num_reps), hermitian=True)
    if num_reps == 1:
        objective = cvxpy.Maximize(
            cvxpy.trace(cvxpy.real(q_a.conj().T @ x_var)))
    else:
        objective = cvxpy.Maximize(
            cvxpy.trace(
                cvxpy.real(pperm @ q_a.conj().T @ pperm.conj().T @ x_var)))
    constraints = [
        partial_trace(x_var, sys, dim) == np.identity(2**num_reps),
        x_var >> 0,
    ]
    problem = cvxpy.Problem(objective, constraints)

    return problem.solve()
Exemple #2
0
def StateRobustnessVerifier(OO, data, label, e):
    dim, n = data.shape[1], data.shape[0]
    non_robust_num = 0
    e = 1. - np.sqrt(1. - e)

    print('=' * 35 + '\nStarting state robustness verifier\n' + '-' * 35)
    for i in range(n):
        rho = data[i, :, :]
        # For convenience, only find real entries state
        sigma = cp.Variable((dim, dim), PSD=True)
        X = cp.Variable((dim, dim), complex=True)
        Y = cp.bmat([[rho, X], [X.H, sigma]])

        cons = [sigma >> 0., cp.trace(sigma) == 1., Y >> 0.]
        if label[i] == 0:
            cons += [cp.real(cp.trace((OO / dim) @ sigma)) >= (0.5 / dim)]
        else:
            cons += [cp.real(cp.trace((OO / dim) @ sigma)) <= (0.5 / dim)]

        obj = cp.Minimize(1 - cp.real(cp.trace(X)))

        prob = cp.Problem(obj, cons)
        prob.solve(solver=cp.SCS)
        delta = 1 - (1. - prob.value) / np.trace(sigma.value)
        if delta < e:
            non_robust_num += 1

        print('{:d}/{:d} states checked: {:d} unrobust state'.format(
            i + 1, n, non_robust_num),
              end='\r')

    print('{:d}/{:d} states checked: {:d} unrobust state'.format(
        i + 1, n, non_robust_num))
    print('=' * 35)
    return non_robust_num
Exemple #3
0
def compute_min_norm_solution(x, y, norm_type):
  """Compute the min-norm solution using a convex-program solver."""
  w = cp.Variable((x.shape[0], 1))
  if norm_type == 'linf':
    # compute minimal L_infinity solution
    constraints = [cp.multiply(y, (w.T @ x)) >= 1]
    prob = cp.Problem(cp.Minimize(cp.norm_inf(w)), constraints)
  elif norm_type == 'l2':
    # compute minimal L_2 solution
    constraints = [cp.multiply(y, (w.T @ x)) >= 1]
    prob = cp.Problem(cp.Minimize(cp.norm2(w)), constraints)
  elif norm_type == 'l1':
    # compute minimal L_1 solution
    constraints = [cp.multiply(y, (w.T @ x)) >= 1]
    prob = cp.Problem(cp.Minimize(cp.norm1(w)), constraints)
  elif norm_type[0] == 'l':
    # compute minimal Lp solution
    p = float(norm_type[1:])
    constraints = [cp.multiply(y, (w.T @ x)) >= 1]
    prob = cp.Problem(cp.Minimize(cp.pnorm(w, p)), constraints)
  elif norm_type == 'dft1':
    w = cp.Variable((x.shape[0], 1), complex=True)
    # compute minimal Fourier L1 norm (||F(w)||_1) solution
    dft = np.matrix(scipy.linalg.dft(x.shape[0], scale='sqrtn'))
    constraints = [cp.multiply(y, (cp.real(w).T @ x)) >= 1]
    prob = cp.Problem(cp.Minimize(cp.norm1(dft @ w)), constraints)
  prob.solve()
  logging.info('Min %s-norm solution found (norm=%.4f)', norm_type,
               float(norm_f(w.value, norm_type)))
  return cp.real(w).value
    def get_primal_problem(self):

        # matrix sizes for AB and A'B
        n_basis = len(self._basis_info_list)  # number of bases postselected
        mat_size_AB = self.dim_A * self.dim_B
        mat_size_ApBp = n_basis * mat_size_AB * self._n_value_A

        X11 = cvx.Variable((mat_size_ApBp, mat_size_ApBp), complex=True)
        X12 = cvx.Variable((mat_size_ApBp, mat_size_ApBp), complex=True)
        X22 = cvx.Variable((mat_size_ApBp, mat_size_ApBp), complex=True)
        rho_AB = cvx.Variable((mat_size_AB, mat_size_AB), hermitian=True)
        sigma_ApBp = cvx.Variable((mat_size_ApBp, mat_size_ApBp),
                                  hermitian=True)

        X = cvx.bmat([[X11, X12], [X12.H, X22]])

        obj = cvx.Maximize(cvx.trace(cvx.real(X12)))

        K_AB = self._basis_info_list.unpack('kraus_op')
        rho_ApBp_ = [k * rho_AB * np.conj(k.T) for k in K_AB]
        rho_ApBp = block_diagonal_stack(rho_ApBp_)

        const_X11 = (X11 << rho_ApBp)
        key_map_povm_ = [
            np.kron(np.eye(n_basis * mat_size_AB), povm)
            for povm in self._key_map_povm
        ]
        cq_sigma_ApBp = np.sum(povm * sigma_ApBp * povm
                               for povm in key_map_povm_)
        const_X22 = (X22 << cq_sigma_ApBp)
        const_sigma_AB = (cvx.real(cvx.trace(sigma_ApBp)) <= 1)
        const_X_pos = (X >> 0)

        const_rho_AB = const_rho_AB_ub = const_rho_AB_lb = []
        if self.Gamma_exact is not None:
            const_rho_AB = [(cvx.trace(rho_AB * G) == g)
                            for g, G in zip(self.gamma, self.Gamma_exact)]
        if self.Gamma_inexact is not None:
            const_rho_AB_ub = [
                (cvx.real(cvx.trace(rho_AB * G)) <= g_ub)
                for g_ub, G in zip(self.gamma_ub, self.Gamma_inexact)
            ]
            const_rho_AB_lb = [
                (cvx.real(cvx.trace(rho_AB * G)) >= g_lb)
                for g_lb, G in zip(self.gamma_lb, self.Gamma_inexact)
            ]
        const_rho_normalized = (cvx.trace(rho_AB) == 1)
        const_sigma_pos = (sigma_ApBp >> 0)
        const_rho_pos = (rho_AB >> 0)

        constraints = [const_X11, const_X22,
                       const_sigma_AB, const_X_pos,
                       const_sigma_pos, const_rho_pos, const_rho_normalized] \
            + const_rho_AB + const_rho_AB_ub + const_rho_AB_lb

        problem = cvx.Problem(obj, constraints)
        return problem
    def test_affine_atoms_canon(self):
        """Test canonicalization for affine atoms.
        """
        # Scalar.
        x = Variable()
        expr = cvx.imag(x + 1j * x)
        prob = Problem(Minimize(expr), [x >= 0])
        result = prob.solve()
        self.assertAlmostEqual(result, 0)
        self.assertAlmostEqual(x.value, 0)

        x = Variable(imag=True)
        expr = 1j * x
        prob = Problem(Minimize(expr), [cvx.imag(x) <= 1])
        result = prob.solve()
        self.assertAlmostEqual(result, -1)
        self.assertAlmostEqual(x.value, 1j)

        x = Variable(2)
        expr = x / 1j
        prob = Problem(Minimize(expr[0] * 1j + expr[1] * 1j),
                       [cvx.real(x + 1j) >= 1])
        result = prob.solve()
        self.assertAlmostEqual(result, -np.inf)
        prob = Problem(Minimize(expr[0] * 1j + expr[1] * 1j),
                       [cvx.real(x + 1j) <= 1])
        result = prob.solve()
        self.assertAlmostEqual(result, -2)
        self.assertItemsAlmostEqual(x.value, [1, 1])
        prob = Problem(
            Minimize(expr[0] * 1j + expr[1] * 1j),
            [cvx.real(x + 1j) >= 1, cvx.conj(x) <= 0])
        result = prob.solve()
        self.assertAlmostEqual(result, np.inf)

        x = Variable((2, 2))
        y = Variable((3, 2), complex=True)
        expr = cvx.vstack([x, y])
        prob = Problem(Minimize(cvx.sum(cvx.imag(cvx.conj(expr)))),
                       [x == 0, cvx.real(y) == 0,
                        cvx.imag(y) <= 1])
        result = prob.solve()
        self.assertAlmostEqual(result, -6)
        self.assertItemsAlmostEqual(y.value, 1j * np.ones((3, 2)))
        self.assertItemsAlmostEqual(x.value, np.zeros((2, 2)))

        x = Variable((2, 2))
        y = Variable((3, 2), complex=True)
        expr = cvx.vstack([x, y])
        prob = Problem(Minimize(cvx.sum(cvx.imag(expr.H))),
                       [x == 0, cvx.real(y) == 0,
                        cvx.imag(y) <= 1])
        result = prob.solve()
        self.assertAlmostEqual(result, -6)
        self.assertItemsAlmostEqual(y.value, 1j * np.ones((3, 2)))
        self.assertItemsAlmostEqual(x.value, np.zeros((2, 2)))
Exemple #6
0
def linearize(expr):
    """Returns the tangent approximation to the expression.

    Gives an elementwise lower (upper) bound for convex (concave)
    expressions. No guarantees for non-DCP expressions.

    Args:
        expr: An expression.

    Returns:
        An affine expression.
    """
    if expr.is_affine():
        return expr
    else:
        if expr.value is None:
            raise ValueError(
                "Cannot linearize non-affine expression with missing variable values."
            )
        tangent = np.real(expr.value)  #+ np.imag(expr.value)
        grad_map = expr.grad
        for var in expr.variables():
            if grad_map[var] is None:
                return None
            complex_flag = False
            if var.is_complex() or np.any(np.iscomplex(grad_map[var])):
                complex_flag = True
            if var.ndim > 1:
                temp = cvx.reshape(cvx.vec(var - var.value),
                                   (var.shape[0] * var.shape[1], 1))
                if complex_flag:
                    flattened = np.transpose(np.real(grad_map[var])) @ cvx.real(temp) + \
                    np.transpose(np.imag(grad_map[var])) @ cvx.imag(temp)
                else:
                    flattened = np.transpose(np.real(grad_map[var])) @ temp
                tangent = tangent + cvx.reshape(flattened, expr.shape)
            elif var.size > 1:
                if complex_flag:
                    tangent = tangent + np.transpose(np.real(grad_map[var])) @ (cvx.real(var) - np.real(var.value)) \
                    + np.transpose(np.imag(grad_map[var])) @ (cvx.imag(var) - np.imag(var.value))
                else:
                    tangent = tangent + np.transpose(np.real(
                        grad_map[var])) @ (var - var.value)
            else:
                if complex_flag:
                    tangent = tangent + np.real(grad_map[var]) * (cvx.real(var) - np.real(var.value)) \
                    + np.imag(grad_map[var]) * (cvx.imag(var) - np.imag(var.value))
                else:
                    tangent = tangent + np.real(
                        grad_map[var]) * (var - var.value)
        return tangent
Exemple #7
0
    def test_real(self):
        """Test real.
        """
        A = np.ones((2, 2))
        expr = Constant(A) + 1j*Constant(A)
        expr = cvx.real(expr)
        assert expr.is_real()
        assert not expr.is_complex()
        assert not expr.is_imag()
        self.assertItemsAlmostEqual(expr.value, A)

        x = Variable(complex=True)
        expr = cvx.imag(x) + cvx.real(x)
        assert expr.is_real()
Exemple #8
0
    def test_missing_imag(self):
        """Test problems where imaginary is missing.
        """
        Z = Variable((2, 2), hermitian=True)
        constraints = [cvx.trace(cvx.real(Z)) == 1]
        obj = cvx.Minimize(0)
        prob = cvx.Problem(obj, constraints)
        prob.solve()

        Z = Variable((2, 2), imag=True)
        obj = cvx.Minimize(cvx.trace(cvx.real(Z)))
        prob = cvx.Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 0)
def pure_witness_ansatz(rho):
    constraints, F, Lam = utils._UNF_witness(9, 9, hermitian=False)
    target = F - cp.real(cp.trace(rho @ Lam))
    pr = cp.Problem(cp.Minimize(target), constraints)
    pr.solve(solver=cp.MOSEK)
    eig_vals, eig_vecs = np.linalg.eig(Lam.value)
    return eig_vecs[:, 0]
def cvxpy_density_matrix_routine(D_matrix,E_matrix):
    numstate = len(D_matrix)
    #print(numstate)
    D_matrix_np = np.array(D_matrix)
    D_matrix_np = 0.5*(D_matrix_np + np.conjugate(np.transpose(D_matrix_np)))
    E_matrix_np = np.array(E_matrix)
    E_matrix_np = 0.5*(E_matrix_np + np.conjugate(np.transpose(E_matrix_np)))
    #Realification of E
    #E_real = np.real(E_matrix_np)
    #E_imag = np.imag(E_matrix_np)
    #E_realified = np.bmat([[E_real,-E_imag],[E_imag,E_real]])
    #Realification of D
    #D_real = np.real(D_matrix_np)
    #D_imag = np.imag(D_matrix_np)
    #D_realified = np.bmat([[D_real,-D_imag],[D_imag,D_real]])
    beta = cp.Variable((numstate,numstate),hermitian=True)
    #print(np.shape(beta))

    # Define and solve the CVXPY problem.
    constraints = [beta >> 0]
    #constraints += [beta == beta.H]
    constraints += [cp.trace(E_matrix_np @ beta) == 1]
    prob = cp.Problem(cp.Minimize(cp.real(cp.trace(D_matrix_np @ beta))),constraints)
    prob.solve(solver=cp.MOSEK,verbose=False)
    #Return result.
    #Returns an np array of the density matrix and the min eigenvalue
    #Needs to unrealify
    denmat = beta.value
    #denmat_real = denmat[0:numstate,0:numstate]
    #denmat_imag = denmat[numstate:numstate*2,0:numstate]
    #denmat = denmat_real+1j*denmat_imag
    minval = np.trace(denmat@D_matrix_np)
    return denmat,minval
Exemple #11
0
def convexify_constr(constr):
    """
    :param constr: a constraint of a problem
    :return:
    for a dcp constraint, return itself;
    for a non-dcp constraint, return a convexified constraint and domain constraints;
    return None if non-sub/super-diff
    """
    if not constr.is_dcp():
        dom = []
        # left hand concave
        if constr.args[0].curvature == 'CONCAVE':
            left = linearize(constr.args[0])
            if left is None:
                return None
            else:
                for con in constr.args[0].domain:
                    dom.append(con)
        else:
            left = constr.args[0]
        # right hand convex
        if constr.args[1].curvature == 'CONVEX':
            right = linearize(constr.args[1])
            if right is None:
                return None
            else:
                for con in constr.args[1].domain:
                    dom.append(con)
        else:
            right = constr.args[1]
        return cvx.real(left - right) <= 0, dom
    else:
        return constr
Exemple #12
0
    def test_symmetric(self) -> None:
        """Test symmetric variables.
        """
        with self.assertRaises(Exception) as cm:
            v = Variable((4, 3), symmetric=True)
        self.assertEqual(
            str(cm.exception),
            "Invalid dimensions (4, 3). Must be a square matrix.")

        v = Variable((2, 2), symmetric=True)
        assert v.is_symmetric()
        v = Variable((2, 2), PSD=True)
        assert v.is_symmetric()
        v = Variable((2, 2), NSD=True)
        assert v.is_symmetric()
        v = Variable((2, 2), diag=True)
        assert v.is_symmetric()
        assert self.a.is_symmetric()
        assert not self.A.is_symmetric()

        v = Variable((2, 2), symmetric=True)
        expr = v + v
        assert expr.is_symmetric()
        expr = -v
        assert expr.is_symmetric()
        expr = v.T
        assert expr.is_symmetric()
        expr = cp.real(v)
        assert expr.is_symmetric()
        expr = cp.imag(v)
        assert expr.is_symmetric()
        expr = cp.conj(v)
        assert expr.is_symmetric()
        expr = cp.promote(Variable(), (2, 2))
        assert expr.is_symmetric()
Exemple #13
0
    def test_complex_matrices(self):
        """Test complex matrices.
        """
        # Complex-valued matrix
        K = np.array(np.random.rand(2, 2) + 1j * np.random.rand(2, 2))  # example matrix
        n1 = la.svdvals(K).sum()  # trace norm of K

        # Dual Problem
        X = cp.Variable((2, 2), complex=True)
        Y = cp.Variable((2, 2), complex=True)
        # X, Y >= 0 so trace is real
        objective = cp.Minimize(
            cp.real(0.5 * cp.trace(X) + 0.5 * cp.trace(Y))
        )
        constraints = [
            cp.bmat([[X, -K.conj().T], [-K, Y]]) >> 0,
            X >> 0,
            Y >> 0,
        ]
        problem = cp.Problem(objective, constraints)

        sol_scs = problem.solve(solver='SCS')
        self.assertEqual(constraints[0].dual_value.shape, (4, 4))
        self.assertEqual(constraints[1].dual_value.shape, (2, 2))
        self.assertEqual(constraints[2].dual_value.shape, (2, 2))
        self.assertAlmostEqual(sol_scs, n1)
Exemple #14
0
    def test_hermitian(self):
        """Test Hermitian variables.
        """
        with self.assertRaises(Exception) as cm:
            v = Variable((4, 3), hermitian=True)
        self.assertEqual(
            str(cm.exception),
            "Invalid dimensions (4, 3). Must be a square matrix.")

        v = Variable((2, 2), hermitian=True)
        assert v.is_hermitian()
        # v = Variable((2,2), PSD=True)
        # assert v.is_symmetric()
        # v = Variable((2,2), NSD=True)
        # assert v.is_symmetric()
        v = Variable((2, 2), diag=True)
        assert v.is_hermitian()

        v = Variable((2, 2), hermitian=True)
        expr = v + v
        assert expr.is_hermitian()
        expr = -v
        assert expr.is_hermitian()
        expr = v.T
        assert expr.is_hermitian()
        expr = cp.real(v)
        assert expr.is_hermitian()
        expr = cp.imag(v)
        assert expr.is_hermitian()
        expr = cp.conj(v)
        assert expr.is_hermitian()
        expr = cp.promote(Variable(), (2, 2))
        assert expr.is_hermitian()
 def solve(self, solver='OLE'):
     '''
     Method to solve the model
     Args:
         solver:'OLE' Ordinary Least Squares method
         'Huber': Uses Huber smoother to down estimate the outliers.
     '''
     W = cp.Variable((self.N, 1), complex=True)
     if solver.upper() == 'OLE':  # Ordinary least squares
         _objective = cp.Minimize(cp.sum_squares(self.ALPHA @ W + self.A))
     elif solver.upper(
     ) == 'HUBER':  # TODO test Huber solver for robust optimization
         _real = cp.real(self.ALPHA @ W + self.A)
         _imag = cp.imag(self.ALPHA @ W + self.A)
         _objective = cp.Minimize(
             cp.sum_squares(cp.huber(cp.hstack([_real, _imag]), M=0)))
     elif solver.upper() == 'WLS':  #  TODO test weighted least squares
         _objective = cp.Minimize(
             cp.sum_squares(cp.diag(self.C) @ (self.ALPHA @ W + self.A)))
     else:
         raise tools.CustomError('Unrecognized Solver name')
     prob = cp.Problem(_objective)
     prob.solve()
     self.W = W.value
     return W.value
def optimize_alice(dim: int, prob_mat: np.ndarray, pred_mat: np.ndarray,
                   bob_povms) -> Tuple[Dict, float]:
    """Fix Bob's measurements and optimize over Alice's measurements."""
    # Get number of inputs and outputs.
    num_inputs_alice, num_inputs_bob = prob_mat.shape
    num_outputs_alice, num_outputs_bob = pred_mat.shape[0], pred_mat.shape[1]

    # The cvxpy package does not support optimizing over 4-dimensional objects.
    # To overcome this, we use a dictionary to index between the questions and
    # answers, while the cvxpy variables held at this positions are
    # `dim`-by-`dim` cvxpy variables.
    alice_povms = defaultdict(cvxpy.Variable)
    for x_ques in range(num_inputs_alice):
        for a_ans in range(num_outputs_bob):
            alice_povms[x_ques, a_ans] = cvxpy.Variable((dim, dim), PSD=True)

    tau = cvxpy.Variable((dim, dim), PSD=True)

    # ..math
    #    \sum_{(x,y) \in \Sigma} \pi(x, y) V(a,b|x,y) \ip{B_b^y}{A_a^x}
    win = 0
    is_real = True
    for x_ques in range(num_inputs_alice):
        for y_ques in range(num_inputs_bob):
            for a_ans in range(num_outputs_alice):
                for b_ans in range(num_outputs_bob):
                    if isinstance(bob_povms[y_ques, b_ans], np.ndarray):
                        win += (prob_mat[x_ques, y_ques] *
                                pred_mat[a_ans, b_ans, x_ques, y_ques] *
                                cvxpy.trace(bob_povms[y_ques, b_ans].conj().T
                                            @ alice_povms[x_ques, a_ans]))
                    if isinstance(bob_povms[y_ques, b_ans],
                                  cvxpy.expressions.variable.Variable):
                        is_real = False
                        win += (
                            prob_mat[x_ques, y_ques] *
                            pred_mat[a_ans, b_ans, x_ques, y_ques] *
                            cvxpy.trace(bob_povms[y_ques, b_ans].value.conj().T
                                        @ alice_povms[x_ques, a_ans]))

    if is_real:
        objective = cvxpy.Maximize(cvxpy.real(win))
    else:
        objective = cvxpy.Maximize(win)

    constraints = []

    # Sum over "a" for all "x" for Alice's measurements.
    for x_ques in range(num_inputs_alice):
        alice_sum_a = 0
        for a_ans in range(num_outputs_alice):
            alice_sum_a += alice_povms[x_ques, a_ans]
        constraints.append(alice_sum_a == tau)

    constraints.append(cvxpy.trace(tau) == 1)

    problem = cvxpy.Problem(objective, constraints)

    lower_bound = problem.solve()
    return alice_povms, lower_bound
    def sdpRho(self):
        '''
        Build and solve optimisation for rho
        With parameters, we could build it only once.
        '''
        constraints = []
        n = self.dimension**self.nbJoueurs
        rho = cp.Variable((n, n), hermitian=True)
        constraints += [rho >> 0]
        constraints += [cp.trace(rho) == 1]

        socialWelfaire = cp.Constant(0)
        winrate = cp.Constant(0)

        for question in self.game.questions():
            for answer in self.game.validAnswerIt(question):
                proba = self.probaRho(answer, question, rho)
                socialWelfaire += self.game.questionDistribution * self.game.answerPayoutWin(
                    answer) * proba
                winrate += self.game.questionDistribution * proba

        sdp = cp.Problem(cp.Maximize(cp.real(socialWelfaire)), constraints)
        sdp.solve(solver=cp.MOSEK, verbose=False)

        return rho
Exemple #18
0
 def test_cplx_mats(self):
     """Test complex matrices.
     """
     if cvx.SUPER_SCS in cvx.installed_solvers():
         # Complex-valued matrix
         K = np.matrix(np.random.rand(2, 2) +
                       1j * np.random.rand(2, 2))  #  example matrix
         n1 = la.svdvals(K).sum()  # trace norm of K
         # Dual Problem
         X = cvx.Variable((2, 2), complex=True)
         Y = cvx.Variable((2, 2), complex=True)
         Z = cvx.Variable((2, 2))
         # X, Y >= 0 so trace is real
         objective = cvx.Minimize(
             cvx.real(0.5 * cvx.trace(X) + 0.5 * cvx.trace(Y)))
         constraints = [
             cvx.bmat([[X, -K.H], [-K, Y]]) >> 0,
             X >> 0,
             Y >> 0,
         ]
         problem = cvx.Problem(objective, constraints)
         sol_scs = problem.solve(solver='SUPER_SCS')
         self.assertEqual(constraints[0].dual_value.shape, (4, 4))
         self.assertEqual(constraints[1].dual_value.shape, (2, 2))
         self.assertEqual(constraints[2].dual_value.shape, (2, 2))
         self.assertAlmostEqual(sol_scs, n1)
     else:
         pass
Exemple #19
0
    def test_pnorm(self):
        """Test complex with pnorm.
        """
        x = Variable((1, 2), complex=True)
        prob = Problem(cvx.Maximize(cvx.sum(cvx.imag(x) + cvx.real(x))), [cvx.norm1(x) <= 2])
        result = prob.solve()
        self.assertAlmostEqual(result, 2*np.sqrt(2))
        val = np.ones(2)*np.sqrt(2)/2
        # self.assertItemsAlmostEqual(x.value, val + 1j*val)

        x = Variable((2, 2), complex=True)
        prob = Problem(cvx.Maximize(cvx.sum(cvx.imag(x) + cvx.real(x))),
                       [cvx.pnorm(x, p=2) <= np.sqrt(8)])
        result = prob.solve()
        self.assertAlmostEqual(result, 8)
        val = np.ones((2, 2))
        self.assertItemsAlmostEqual(x.value, val + 1j*val)
Exemple #20
0
    def test_diag(self) -> None:
        """Test diag of mat, and of vector.
        """
        X = cvx.Variable((2, 2), complex=True)
        obj = cvx.Maximize(cvx.trace(cvx.real(X)))
        cons = [cvx.diag(X) == 1]
        prob = cvx.Problem(obj, cons)
        result = prob.solve(solver="SCS")
        self.assertAlmostEqual(result, 2)

        x = cvx.Variable(2, complex=True)
        X = cvx.diag(x)
        obj = cvx.Maximize(cvx.trace(cvx.real(X)))
        cons = [cvx.diag(X) == 1]
        prob = cvx.Problem(obj, cons)
        result = prob.solve(solver="SCS")
        self.assertAlmostEqual(result, 2)
Exemple #21
0
    def test_bool(self) -> None:
        # The purpose of this test is to make sure
        # that we don't try to recover dual variables
        # unless they're actually present.
        #
        # Added as part of fixing GitHub issue 1133.
        bool_var = cp.Variable(boolean=True)
        complex_var = cp.Variable(complex=True)

        constraints = [
            cp.real(complex_var) <= bool_var,
        ]

        obj = cp.Maximize(cp.real(complex_var))
        prob = cp.Problem(obj, constraints)
        prob.solve(solver='ECOS_BB')
        self.assertAlmostEqual(prob.value, 1, places=4)
def cvxpy_density_matrix_feasibility_sdp_routine_old(D_matrix,E_matrix,R_matrices,F_matrices,gammas,sdp_tolerance_bound):
    numstate = len(D_matrix)
    D_matrix_np = np.array(D_matrix)
    #D_matrix_np = 0.5*(D_matrix_np + np.conjugate(np.transpose(D_matrix_np)))
    E_matrix_np = np.array(E_matrix)
    #E_matrix_np = 0.5*(E_matrix_np + np.conjugate(np.transpose(E_matrix_np)))
    R_matrices_np = []
    F_matrices_np = []
    for r in R_matrices:
        R_matrices_np.append(np.array(r))
    for f in F_matrices:
        F_matrices_np.append(np.array(f))
    beta = cp.Variable((numstate,numstate),complex=True)
    constraints = [beta >> 0]
    #constraints += [cp.trace(E_matrix_np @ beta) == 1]
    constraints += [beta.H == beta]

    a = -1j*(D_matrix_np@beta@E_matrix_np-E_matrix_np@beta@D_matrix_np)
    #finalconstraints = []
    for i in range(len(gammas)):
        a = a + gammas[i]*(R_matrices_np[i]@[email protected](np.conjugate(R_matrices_np[i]))-0.5*F_matrices_np[i]@beta@E_matrix_np-0.5*E_matrix_np@beta@F_matrices_np[i])
    #a = -1j*(D_matrix_np@beta@E_matrix_np-E_matrix_np@beta@D_matrix_np)+gammas[0]*(R_matrices_np[0]@[email protected](np.conjugate(R_matrices_np[0]))-0.5*F_matrices_np[0]@beta@E_matrix_np-0.5*E_matrix_np@beta@F_matrices_np[0])
    #constraints += [cp.trace(E_matrix_np @ beta) == 1]
    constraints += [a == 0]
    #constraints += [cp.trace(a@(a.H))<=sdp_tolerance_bound]
    #constraints += [cp.trace(a@(a.H))>=-sdp_tolerance_bound]
    if sdp_tolerance_bound == 0:
        print('Feasibility SDP is set up with hard constraint  == 1')
        #constraints += [a == 0]
        constraints += [cp.trace(E_matrix_np @ beta) == 1]
    else:
        print('Feasibility SDP is set up with interval constraint <'+str(sdp_tolerance_bound)+ ' & >-'+str(sdp_tolerance_bound))
        #constraints += [cp.abs(cp.trace(a@(a.H)))<=sdp_tolerance_bound]
        #constraints += [cp.abs(cp.trace(a@(a.H)))>=-sdp_tolerance_bound]
        constraints += [cp.real(cp.trace(E_matrix_np @ beta)) <= 1+sdp_tolerance_bound]
        constraints += [cp.real(cp.trace(E_matrix_np @ beta)) >= 1-sdp_tolerance_bound]
    prob = cp.Problem(cp.Minimize(0),constraints)
    prob.solve(solver=cp.MOSEK,verbose=False)
    denmat = beta.value
    #print(denmat)
    if type(denmat) == type(None):
        return None,None
    else:
        minval = np.trace(denmat@D_matrix_np)
        return denmat,minval
Exemple #23
0
 def test_promote(self):
     """Test promotion of complex variables.
     """
     v = Variable(complex=True)
     obj = cvx.Maximize(cvx.real(cvx.sum(v * np.ones((2, 2)))))
     con = [cvx.norm(v) <= 1]
     prob = cvx.Problem(obj, con)
     result = prob.solve()
     self.assertAlmostEqual(result, 4.0)
Exemple #24
0
 def test_abs(self):
     """Test with absolute value.
     """
     x = Variable(2, complex=True)
     prob = Problem(cvx.Maximize(cvx.sum(cvx.imag(x) + cvx.real(x))), [cvx.abs(x) <= 2])
     result = prob.solve()
     self.assertAlmostEqual(result, 4*np.sqrt(2))
     val = np.ones(2)*np.sqrt(2)
     self.assertItemsAlmostEqual(x.value, val + 1j*val)
Exemple #25
0
def diamond_norm(chan0: Channel, chan1: Channel) -> float:
    """Return the diamond norm between two completely positive
    trace-preserving (CPTP) superoperators.

    Note: Requires "cvxpy" package (and dependencies) to be fully installed.

    The calculation uses the simplified semidefinite program of Watrous
    [arXiv:0901.4709](http://arxiv.org/abs/0901.4709)
    [J. Watrous, [Theory of Computing 5, 11, pp. 217-238
    (2009)](http://theoryofcomputing.org/articles/v005a011/)]
    """
    # Kudos: Based on MatLab code written by Marcus P. da Silva
    # (https://github.com/BBN-Q/matlab-diamond-norm/)
    import cvxpy as cvx

    if set(chan0.qubits) != set(chan1.qubits):
        raise ValueError("Channels must operate on same qubits")

    if chan0.qubits != chan1.qubits:
        chan1 = chan1.permute(chan0.qubits)

    N = chan0.qubit_nb
    dim = 2**N

    choi0 = chan0.choi()
    choi1 = chan1.choi()

    delta_choi = choi0 - choi1

    # Density matrix must be Hermitian, positive semidefinite, trace 1
    rho = cvx.Variable([dim, dim], complex=True)
    constraints = [rho == rho.H]
    constraints += [rho >> 0]
    constraints += [cvx.trace(rho) == 1]

    # W must be Hermitian, positive semidefinite
    W = cvx.Variable([dim**2, dim**2], complex=True)
    constraints += [W == W.H]
    constraints += [W >> 0]

    constraints += [(W - cvx.kron(np.eye(dim), rho)) << 0]

    J = cvx.Parameter([dim**2, dim**2], complex=True)
    objective = cvx.Maximize(cvx.real(cvx.trace(J.H * W)))

    prob = cvx.Problem(objective, constraints)

    J.value = delta_choi
    prob.solve()

    dnorm = prob.value * 2

    # Diamond norm is between 0 and 2. Correct for floating point errors
    dnorm = min(2, dnorm)
    dnorm = max(0, dnorm)

    return dnorm
Exemple #26
0
    def write_problem(self, complex_field=False):
        if complex_field:
            problem = cp.Problem(cp.Maximize(cp.real(self.object_function)),
                                 self.constraints)
        else:
            problem = cp.Problem(cp.Maximize(self.object_function),
                                 self.constraints)

        return problem
Exemple #27
0
    def get_primal_problem(self):

        mat_size = np.prod(self.dims)  # matrix sizes

        X11 = cvx.Variable((mat_size, mat_size), complex=True)
        X12 = cvx.Variable((mat_size, mat_size), complex=True)
        X22 = cvx.Variable((mat_size, mat_size), complex=True)
        rho_AB = cvx.Variable((mat_size, mat_size), hermitian=True)
        sigma_AB = cvx.Variable((mat_size, mat_size), hermitian=True)

        X = cvx.bmat([[X11, X12], [X12.H, X22]])

        obj = cvx.Maximize(cvx.trace(cvx.real(X12)))

        const_X11 = (X11 << rho_AB)
        cq_sigma_AB = np.sum(povm * sigma_AB * povm
                             for povm in self._key_map_povm)
        const_X22 = (X22 << cq_sigma_AB)
        const_sigma_AB = (cvx.real(cvx.trace(sigma_AB)) <= 1)
        const_X_pos = (X >> 0)

        const_rho_AB = const_rho_AB_ub = const_rho_AB_lb = []
        if self.Gamma_exact is not None:
            const_rho_AB = [(cvx.trace(rho_AB * G) == g)
                            for g, G in zip(self.gamma, self.Gamma_exact)]
        if self.Gamma_inexact is not None:
            const_rho_AB_ub = [
                (cvx.real(cvx.trace(rho_AB * G)) <= g_ub)
                for g_ub, G in zip(self.gamma_ub, self.Gamma_inexact)
            ]
            const_rho_AB_lb = [
                (cvx.real(cvx.trace(rho_AB * G)) >= g_lb)
                for g_lb, G in zip(self.gamma_lb, self.Gamma_inexact)
            ]
        const_rho_normalized = (cvx.trace(rho_AB) == 1)
        const_sigma_pos = (sigma_AB >> 0)
        const_rho_pos = (rho_AB >> 0)
        constraints = [const_X11, const_X22,
                       const_sigma_AB, const_X_pos,
                       const_sigma_pos, const_rho_pos, const_rho_normalized] \
            + const_rho_AB + const_rho_AB_ub + const_rho_AB_lb

        problem = cvx.Problem(obj, constraints)
        return problem
Exemple #28
0
def diamond_norm(J, dimA, dimB, display=False):
    '''
    Computes the diamond norm of a superoperator with Choi representation J.
    dimA is the dimension of the input space of the channel, and dimB is the
    dimension of the output space.

    The form of the SDP used comes from Theorem 3.1 of:
        
        'Simpler semidefinite programs for completely bounded norms',
            Chicago Journal of Theoretical Computer Science 2013,
            by John Watrous
    '''
    '''
    The Choi representation J in the above paper is defined using a different
    convention:
        J=(N\otimes I)(|Phi^+><Phi^+|).
    In other words, the channel N acts on the first half of the maximally-
    entangled state, while the convention used throughout this code stack
    is
        J=(I\otimes N)(|Phi^+><Phi^+|).
    We thus use syspermute to convert to the form used in the aforementioned
    paper.
    '''

    J = syspermute(J, [2, 1], [dimA, dimB])

    X = cvx.Variable((dimA * dimB, dimA * dimB), hermitian=False)
    rho0 = cvx.Variable((dimA, dimA), PSD=True)
    rho1 = cvx.Variable((dimA, dimA), PSD=True)

    M = cvx.bmat([[cvx.kron(eye(dimB), rho0), X],
                  [X.H, cvx.kron(eye(dimB), rho1)]])

    c = []
    c += [M >> 0, cvx.trace(rho0) == 1, cvx.trace(rho1) == 1]

    obj = cvx.Maximize((1 / 2) * cvx.real(cvx.trace(dag(J) @ X)) +
                       (1 / 2) * cvx.real(cvx.trace(J @ X.H)))

    prob = cvx.Problem(obj, constraints=c)

    prob.solve(verbose=display, eps=1e-7)

    return prob.value
def diamond_norm_distance(choi0: np.ndarray, choi1: np.ndarray) -> float:
    """
    Return the diamond norm distance between two completely positive
    trace-preserving (CPTP) superoperators, represented as Choi matrices.

    The calculation uses the simplified semidefinite program of Watrous in [CBN]_

    .. note::

        This calculation becomes very slow for 4 or more qubits.

    .. [CBN] Semidefinite programs for completely bounded norms.
          J. Watrous.
          Theory of Computing 5, 11, pp. 217-238 (2009).
          http://theoryofcomputing.org/articles/v005a011
          http://arxiv.org/abs/0901.4709

    :param choi0: A 4**N by 4**N matrix (where N is the number of qubits)
    :param choi1: A 4**N by 4**N matrix (where N is the number of qubits)

    """
    # Kudos: Based on MatLab code written by Marcus P. da Silva
    # (https://github.com/BBN-Q/matlab-diamond-norm/)
    import cvxpy as cvx
    assert choi0.shape == choi1.shape
    assert choi0.shape[0] == choi1.shape[1]
    dim_squared = choi0.shape[0]
    dim = int(np.sqrt(dim_squared))

    delta_choi = choi0 - choi1
    delta_choi = (delta_choi.conj().T + delta_choi) / 2  # Enforce Hermiticity

    # Density matrix must be Hermitian, positive semidefinite, trace 1
    rho = cvx.Variable([dim, dim], complex=True)
    constraints = [rho == rho.H]
    constraints += [rho >> 0]
    constraints += [cvx.trace(rho) == 1]

    # W must be Hermitian, positive semidefinite
    W = cvx.Variable([dim_squared, dim_squared], complex=True)
    constraints += [W == W.H]
    constraints += [W >> 0]

    constraints += [(W - cvx.kron(np.eye(dim), rho)) << 0]

    J = cvx.Parameter([dim_squared, dim_squared], complex=True)
    objective = cvx.Maximize(cvx.real(cvx.trace(J.H * W)))

    prob = cvx.Problem(objective, constraints)

    J.value = delta_choi
    prob.solve()

    dnorm = prob.value * 2

    return dnorm
Exemple #30
0
 def test_params(self):
     """Test with parameters.
     """
     p = cvx.Parameter(imag=True, value=1j)
     x = Variable(2, complex=True)
     prob = Problem(cvx.Maximize(cvx.sum(cvx.imag(x) + cvx.real(x))), [cvx.abs(p*x) <= 2])
     result = prob.solve()
     self.assertAlmostEqual(result, 4*np.sqrt(2))
     val = np.ones(2)*np.sqrt(2)
     self.assertItemsAlmostEqual(x.value, val + 1j*val)