def make_XY_model(num_qubits):
    import qubit_network.analytical_conditions as ac

    def X(i, num_qubits=3):
        zeros = [0] * num_qubits
        zeros[i] = 1
        return ac.pauli_product(*zeros)

    def Y(i, num_qubits=3):
        zeros = [0] * num_qubits
        zeros[i] = 2
        return ac.pauli_product(*zeros)

    def Z(i, num_qubits=3):
        zeros = [0] * num_qubits
        zeros[i] = 3
        return ac.pauli_product(*zeros)

    def XX(i, j, num_qubits=3):
        return X(i, num_qubits) * X(j, num_qubits)

    def YY(i, j, num_qubits=3):
        return Y(i, num_qubits) * Y(j, num_qubits)

    expr = sympy.zeros(2**num_qubits, 2**num_qubits)
    # all single-qubit interactions
    for idx in range(num_qubits):
        for pauli_idx in range(3):
            mol = [0] * num_qubits
            mol[idx] = pauli_idx + 1
            expr += ac.pauli_product(*mol) * ac.J(*mol)
    # only XX and YY two-qubit interactions
    for pair in itertools.combinations(range(num_qubits), 2):
        molXX = [0] * num_qubits
        molXX[pair[0]] = 1
        molXX[pair[1]] = 1
        expr += ac.J(*molXX) * XX(pair[0], pair[1], num_qubits)

        molYY = [0] * num_qubits
        molYY[pair[0]] = 2
        molYY[pair[1]] = 2
        expr += ac.J(*molYY) * YY(pair[0], pair[1], num_qubits)
    # return final expression
    return expr
Example #2
0
def make_XX_reduced_model():
    import qubit_network.analytical_conditions as ac

    def X(i, num_qubits=3):
        zeros = [0] * num_qubits
        zeros[i - 1] = 1
        return ac.pauli_product(*zeros)

    def Y(i, num_qubits=3):
        zeros = [0] * num_qubits
        zeros[i - 1] = 2
        return ac.pauli_product(*zeros)

    def Z(i, num_qubits=3):
        zeros = [0] * num_qubits
        zeros[i - 1] = 3
        return ac.pauli_product(*zeros)

    def XX(i, j, num_qubits=3):
        first_term = X(i, num_qubits) * X(j, num_qubits)
        second_term = Y(i, num_qubits) * Y(j, num_qubits)
        return first_term + second_term

    parametrized_hamiltonian = (ac.J(3, 0, 0) * Z(1) + ac.J(0, 1, 0) *
                                (X(2) + X(3)) + ac.J(0, 2, 0) * (Y(2) + Y(3)) +
                                ac.J(0, 3, 0) * (Z(2) + Z(3)) +
                                ac.J(0, 1, 1) * XX(2, 3) + ac.J(1, 1, 0) *
                                (XX(1, 2) + XX(1, 3)))
    return parametrized_hamiltonian
def make_fredkin_model():
    import qubit_network.analytical_conditions as ac

    def X(i, num_qubits=3):
        zeros = [0] * num_qubits
        zeros[i - 1] = 1
        return ac.pauli_product(*zeros)

    def Y(i, num_qubits=3):
        zeros = [0] * num_qubits
        zeros[i - 1] = 2
        return ac.pauli_product(*zeros)

    def Z(i, num_qubits=3):
        zeros = [0] * num_qubits
        zeros[i - 1] = 3
        return ac.pauli_product(*zeros)

    def XY(i, j, num_qubits=3):
        first_term = X(i, num_qubits) * X(j, num_qubits)
        second_term = Y(i, num_qubits) * Y(j, num_qubits)
        return first_term + second_term

    num_qubits = 3
    expr = sympy.zeros(2**num_qubits, 2**num_qubits)
    # all single-qubit interactions
    for idx in range(num_qubits):
        for pauli_idx in range(3):
            mol = [0] * num_qubits
            mol[pauli_idx] = 1
            expr += ac.pauli_product(*mol) * ac.J(*mol)
    # only XY two-qubit interactions
    for pair in itertools.combinations(range(num_qubits), 2):
        expr += ac.J(pair[0], pair[1]) * XY(
            pair[0], pair[1], num_qubits=num_qubits)
    # return final expression
    return expr