Ejemplo n.º 1
0
def partial_trace(expr, dims: Tuple[int], axis: Optional[int] = 0):
    """
    Assumes :math:`\\texttt{expr} = X_1 \\otimes \\cdots \\otimes X_n` is a 2D Kronecker
    product composed of :math:`n = \\texttt{len(dims)}` implicit subsystems.
    Letting :math:`k = \\texttt{axis}`, the returned expression represents
    the *partial trace* of :math:`\\texttt{expr}` along its :math:`k^{\\text{th}}` implicit subsystem:

    .. math::

        \\text{tr}(X_k) (X_1 \\otimes \\cdots \\otimes X_{k-1} \\otimes X_{k+1} \\otimes \\cdots \\otimes X_n).

    Parameters
    ----------
    expr : :class:`~cvxpy.expressions.expression.Expression`
        The 2D expression to take the partial trace of.
    dims : tuple of ints.
        A tuple of integers encoding the dimensions of each subsystem.
    axis : int
        The index of the subsystem to be traced out
        from the tensor product that defines expr.
    """
    expr = Atom.cast_to_const(expr)
    if expr.ndim < 2 or expr.shape[0] != expr.shape[1]:
        raise ValueError("Only supports square matrices.")
    if axis < 0 or axis >= len(dims):
        raise ValueError(
            f"Invalid axis argument, should be between 0 and {len(dims)}, got {axis}."
        )
    if expr.shape[0] != np.prod(dims):
        raise ValueError(
            "Dimension of system doesn't correspond to dimension of subsystems."
        )
    return sum([_term(expr, j, dims, axis) for j in range(dims[axis])])
Ejemplo n.º 2
0
def partial_transpose(expr, dims: Tuple[int], axis: Optional[int] = 0):
    """Partial transpose of a matrix.

    Assumes :math:`expr = X1 \\odots ... \\odots Xn` is a 2D tensor product
    composed implicitly of n subsystems. Here :math:`\\odots` denotes the Kronecker product,
    and axis=k is the index of the subsystem to be transposed
    from the tensor product that defines expr.
    Returns :math:`X1 \\odots ... \\odots Xk^T \\odots ... \\odots Xn`

    Parameters
    ----------
    expr : :class:`~cvxpy.expressions.expression.Expression`
        The 2D expression to take the partial transpose of.
    dims : tuple of ints.
        A tuple of integers encoding the dimensions of each subsystem.
    axis : int
        The index of the subsystem to be transposed
        from the tensor product that defines expr.
    """
    expr = Atom.cast_to_const(expr)
    if expr.ndim < 2 or expr.shape[0] != expr.shape[1]:
        raise ValueError("Only supports square matrices.")
    if axis < 0 or axis >= len(dims):
        raise ValueError(
            f"Invalid axis argument, should be between 0 and {len(dims)}, got {axis}."
        )
    if expr.shape[0] != np.prod(dims):
        raise ValueError(
            "Dimension of system doesn't correspond to dimension of subsystems."
        )
    return sum([
        _term(expr, i, j, dims, axis) for i in range(dims[axis])
        for j in range(dims[axis])
    ])
Ejemplo n.º 3
0
    def __init__(self, y, parent):
        """
        Parameters
        ----------
        y : cvxpy.expressions.expression.Expression
            Must satisfy ``y.is_affine() == True``.

        parent : cvxpy.transforms.suppfunc.SuppFunc
            The object containing data for the convex set associated with this atom.
        """
        self.id = lu.get_id()
        self.args = [Atom.cast_to_const(y)]
        self._parent = parent
        self._eta = None  # store for debugging purposes
        self._shape = tuple()
        self.validate_arguments()
Ejemplo n.º 4
0
 def __init__(self, A, X):
     # NB: It is important that the exponent is an attribute, not
     # an argument. This prevents parametrized exponents from being replaced
     # with their logs in Dgp2Dcp.
     self.A = Atom.cast_to_const(A)
     super(gmatmul, self).__init__(X)
Ejemplo n.º 5
0
 def __init__(self, A, X):
     self.A = Atom.cast_to_const(A)
     super(gmatmul, self).__init__(X)