Example #1
0
def controlled(U, ctrl=(1,), dim=None):
    r"""Controlled gate.

    Returns the (t+1)-qudit controlled-U gate, where t == length(ctrl).
    U has to be a square matrix.

    ctrl is an integer vector defining the control nodes. It has one entry k per
    control qudit, denoting the required computational basis state :math:`|k\rangle`
    for that particular qudit. Value k == -1 denotes no control.

    dim is the dimensions vector for the control qudits. If not given, all controls
    are assumed to be qubits.

    Examples:

      controlled(NOT, [1]) gives the standard CNOT gate.
      controlled(NOT, [1, 1]) gives the Toffoli gate.
    """
    # Ville Bergholm 2009-2011

    # TODO generalization, uniformly controlled gates?
    if isscalar(dim): dim = (dim,)  # scalar into a tuple
    t = len(ctrl)
    if dim == None:
        dim = qubits(t) # qubits by default

    if t != len(dim):
        raise ValueError('ctrl and dim vectors have unequal lengths.')

    if any(array(ctrl) >= array(dim)):
        raise ValueError('Control on non-existant state.')

    yes = 1  # just the diagonal
    for k in range(t):
        if ctrl[k] >= 0:
            temp = zeros(dim[k])
            temp[ctrl[k]] = 1  # control on k
            yes = kron(yes, temp) 
        else:
            yes = kron(yes, ones(dim[k])) # no control on this qudit

    no = 1 - yes
    T = prod(dim)
    dim = list(dim)

    if isinstance(U, lmap):
        d1 = dim + list(U.dim[0])
        d2 = dim + list(U.dim[1])
        U = U.data
    else:
        d1 = dim + [U.shape[0]]
        d2 = dim + [U.shape[1]]

    # controlled gates only make sense for square matrices U (we need an identity transformation for the 'no' cases!)
    U_dim = U.shape[0]
    S = U_dim * T

    out = sparse.spdiags(kron(no, ones(U_dim)), 0, S, S) + sparse.kron(sparse.spdiags(yes, 0, T, T), U)
    return lmap(out, (d1, d2))
Example #2
0
def walsh(n):
    """Walsh-Hadamard gate.

    Returns the Walsh-Hadamard gate for n qubits.
    The returned lmap is dense.
    """
    # Ville Bergholm 2009-2010

    from base import H

    U = 1
    for k in range(n):
        U = kron(U, H)
    dim = qubits(n)
    return lmap(U, (dim, dim))