def test_operations_as_set():
    q = QubitPlaceholder.register(6)
    term_1 = PauliTerm("Z", q[0], 1.0) * PauliTerm("Z", q[1], 1.0) * PauliTerm(
        "X", q[5], 5)
    term_2 = PauliTerm("X", q[5], 5) * PauliTerm("Z", q[0], 1.0) * PauliTerm(
        "Z", q[1], 1.0)
    assert term_1.operations_as_set() == term_2.operations_as_set()
def get_calibration_program(observable: PauliTerm, noisy_program: Program = None,
                            active_reset: bool = False) -> Program:
    """
    Program required for calibrating the given observable.

    :param observable: observable to calibrate
    :param noisy_program: a program with readout and gate noise defined; only useful for QVM
    :param active_reset: whether or not to begin the program by actively resetting. If true,
        execution of each of the returned programs in a loop on the QPU will generally be faster.
    :return: Program performing the calibration
    """
    calibr_prog = Program()

    if active_reset:
        calibr_prog += RESET()

    # Inherit any noisy attributes from noisy_program, including gate definitions
    # and applications which can be handy in simulating noisy channels
    if noisy_program is not None:
        # Inherit readout error instructions from main Program
        readout_povm_instruction = [i for i in noisy_program.out().split('\n')
                                    if 'PRAGMA READOUT-POVM' in i]
        calibr_prog += readout_povm_instruction
        # Inherit any definitions of noisy gates from main Program
        kraus_instructions = [i for i in noisy_program.out().split('\n') if 'PRAGMA ADD-KRAUS' in i]
        calibr_prog += kraus_instructions

    # Prepare the +1 eigenstate for the out operator
    for q, op in observable.operations_as_set():
        calibr_prog += _one_q_pauli_prep(label=op, index=0, qubit=q)
    # Measure the out operator in this state
    for q, op in observable.operations_as_set():
        calibr_prog += _local_pauli_eig_meas(op, q)

    return calibr_prog
def prepare_random_prod_pauli_eigenstate(pauli_term: PauliTerm):
    opset = pauli_term.operations_as_set()
    prog = Program()
    s = ''.join([
        random_local_pauli_eig_prep(prog, op, qubit) for (qubit, op) in opset
    ])
    return prog
def prepare_prod_pauli_eigenstate(pauli_term: PauliTerm):
    """Returns a circuit to prepare a +1 eigenstate of the Pauli operator described in PauliTerm.

    :param pauli_term: The PauliTerm whose eigenstate we will prepare.
    :return: A program corresponding to the correct rotation into the eigenbasis for pauli_term."""
    opset = pauli_term.operations_as_set()
    prog = Program()
    for (qubit, op) in opset:
        prog += local_pauli_eig_prep(op, qubit)
    return prog
Exemple #5
0
    def apply_clifford_to_pauli(self, clifford: Program,
                                pauli_in: PauliTerm) -> PauliTerm:
        r"""
        Given a circuit that consists only of elements of the Clifford group,
        return its action on a PauliTerm.

        In particular, for Clifford C, and Pauli P, this returns the PauliTerm
        representing CPC^{\dagger}.

        :param clifford: A Program that consists only of Clifford operations.
        :param pauli_in: A PauliTerm to be acted on by clifford via conjugation.
        :return: A PauliTerm corresponding to clifford * pauli_in * clifford^{\dagger}
        """
        # do nothing if `pauli_in` is the identity
        if is_identity(pauli_in):
            return pauli_in

        indices_and_terms = list(zip(*list(pauli_in.operations_as_set())))

        payload = ConjugateByCliffordRequest(
            clifford=clifford.out(),
            pauli=rpcq.messages.PauliTerm(indices=list(indices_and_terms[0]),
                                          symbols=list(indices_and_terms[1])),
        )
        response: ConjugateByCliffordResponse = self.client.call(
            "conjugate_pauli_by_clifford", payload)
        phase_factor, paulis = response.phase, response.pauli

        pauli_out = PauliTerm("I", 0, 1.0j**phase_factor)
        clifford_qubits = clifford.get_qubits()
        pauli_qubits = pauli_in.get_qubits()
        all_qubits = sorted(
            set(cast(List[int],
                     pauli_qubits)).union(set(cast(List[int],
                                                   clifford_qubits))))
        # The returned pauli will have specified its value on all_qubits, sorted by index.
        #  This is maximal set of qubits that can be affected by this conjugation.
        for i, pauli in enumerate(paulis):
            pauli_out = cast(PauliTerm,
                             pauli_out * PauliTerm(pauli, all_qubits[i]))
        return cast(PauliTerm, pauli_out * pauli_in.coefficient)
Exemple #6
0
def test_operations_as_set():
    term_1 = PauliTerm("Z", 0, 1.0) * PauliTerm("Z", 1, 1.0) * PauliTerm("X", 5, 5)
    term_2 = PauliTerm("X", 5, 5) * PauliTerm("Z", 0, 1.0) * PauliTerm("Z", 1, 1.0)
    assert term_1.operations_as_set() == term_2.operations_as_set()
def prepare_all_prod_pauli_eigenstates(pauli_term: PauliTerm):
    opset = pauli_term.operations_as_set()
    prod_preps = itertools.product(
        *[local_pauli_eigs_prep(op, qubit) for (qubit, op) in opset])
    return [Program().inst(list(prod)) for prod in prod_preps]
def measure_prod_pauli_eigenstate(pauli_term: PauliTerm):
    opset = pauli_term.operations_as_set()
    prog = Program()
    for (qubit, op) in opset:
        prog += local_pauli_eig_meas(op, qubit)
    return prog
Exemple #9
0
def measure_prod_pauli_eigenstate(prog: Program, pauli_term: PauliTerm):
    opset = pauli_term.operations_as_set()
    for (idx, op) in opset:
        local_pauli_eig_meas(prog, op, idx)
    return prog