Ejemplo n.º 1
0
def decompose_transfer_operator(
        ket: BitString,
        bra: BitString,
        qubits: typing.List[int] = None) -> QubitHamiltonian:
    """
    Notes
    ----------
    Create the operator

    Note that this is operator is not necessarily hermitian
    So be careful when using it as a generator for gates

    e.g.
    decompose_transfer_operator(ket="01", bra="10", qubits=[2,3])
    gives the operator

    .. math::
        \\lvert 01 \\rangle \\langle 10 \\rvert_{2,3}

    acting on qubits 2 and 3

    Parameters
    ----------
    ket: pass an integer, string, or tequila BitString
    bra: pass an integer, string, or tequila BitString
    qubits: pass the qubits onto which the operator acts

    Returns
    -------

    """

    opmap = {(0, 0): Qp, (0, 1): Sp, (1, 0): Sm, (1, 1): Qm}

    nbits = None
    if qubits is not None:
        nbits = len(qubits)

    if isinstance(bra, int):
        bra = BitString.from_int(integer=bra, nbits=nbits)
    if isinstance(ket, int):
        ket = BitString.from_int(integer=ket, nbits=nbits)

    b_arr = bra.array
    k_arr = ket.array
    assert (len(b_arr) == len(k_arr))
    n_qubits = len(k_arr)

    if qubits is None:
        qubits = range(n_qubits)

    assert (n_qubits <= len(qubits))

    result = QubitHamiltonian.unit()
    for q, b in enumerate(b_arr):
        k = k_arr[q]
        result *= opmap[(k, b)](qubit=qubits[q])

    return result
Ejemplo n.º 2
0
def test_conjugation():
    primitives = [paulis.X, paulis.Y, paulis.Z]
    factors = [1, -1, 1j, -1j, 0.5 + 1j]
    string = QubitHamiltonian.unit()
    cstring = QubitHamiltonian.unit()
    for repeat in range(10):
        for q in random.randint(0, 7, 5):
            ri = random.randint(0, 2)
            P = primitives[ri]
            sign = 1
            if ri == 1:
                sign = -1
            factor = factors[random.randint(0, len(factors) - 1)]
            cfactor = factor.conjugate()
            string *= factor * P(qubit=q)
            cstring *= cfactor * sign * P(qubit=q)

        assert (string.conjugate() == cstring)
Ejemplo n.º 3
0
def I(*args, **kwargs) -> QubitHamiltonian:
    """
    Initialize unit Operator

    Returns
    -------
    QubitHamiltonian

    """
    return QubitHamiltonian.unit()
Ejemplo n.º 4
0
def make_random_pauliword(complex=True):
    primitives = [paulis.X, paulis.Y, paulis.Z]
    result = QubitHamiltonian.unit()
    for q in random.choice(range(10), 5, replace=False):
        P = primitives[random.randint(0, 2)]
        real = random.uniform(0, 1)
        imag = 0
        if complex:
            imag = random.uniform(0, 1)
        factor = real + imag * 1j
        result *= factor * P(q)
    return result
Ejemplo n.º 5
0
def test_transposition():
    primitives = [paulis.X, paulis.Y, paulis.Z]
    factors = [1, -1, 1j, -1j, 0.5 + 1j]

    assert ((paulis.X(0) * paulis.X(1) * paulis.Y(2)).transpose() == -1 * paulis.X(0) * paulis.X(1) * paulis.Y(2))
    assert ((paulis.X(0) * paulis.X(1) * paulis.Z(2)).transpose() == paulis.X(0) * paulis.X(1) * paulis.Z(2))

    for repeat in range(10):
        string = QubitHamiltonian.unit()
        tstring = QubitHamiltonian.unit()
        for q in range(5):
            ri = random.randint(0, 2)
            P = primitives[ri]
            sign = 1
            if ri == 1:
                sign = -1
            factor = factors[random.randint(0, len(factors) - 1)]
            string *= factor * P(qubit=q)
            tstring *= factor * sign * P(qubit=q)

        assert (string.transpose() == tstring)