def test_pauli_string(): p = PauliTerm("X", 1) * PauliTerm("Z", 5) assert p.pauli_string([1, 5]) == "XZ" assert p.pauli_string([1]) == "X" assert p.pauli_string([5]) == "Z" assert p.pauli_string([5, 6]) == "ZI" assert p.pauli_string([0, 1]) == "IX"
def _evaluate_single_term(self, ansatz_circuit: Program, meas_term: PauliTerm) -> np.ndarray: """Compute the expectation value of a single PauliTerm , given a quantum circuit to evaluate on. Args: ansatz_circuit: A Program representing the quantum state to evaluate the PauliTerm on. meas_term: a PauliTerm object to be evaluated. """ # First, create the quantum circuit needed for evaluation. # concatenate operator (converted to a Program) and ansatz circuit expectation_circuit = ansatz_circuit.copy() expectation_circuit += meas_term.program ro = expectation_circuit.declare('ro', 'BIT', len(meas_term.get_qubits())) # add necessary post-rotations and measurement for i, qubit in enumerate(sorted(list(meas_term.get_qubits()))): if meas_term.pauli_string([qubit]) == 'X': expectation_circuit += H(qubit) elif meas_term.pauli_string([qubit]) == 'Y': expectation_circuit += H(qubit) expectation_circuit += S(qubit) expectation_circuit += Program().measure(qubit, ro[i]) result = self._run(expectation_circuit, num_shots=self._num_shots_evaluation) return result
def pauli_term_to_euler_memory_map( term: PauliTerm, *, prefix: str, tuple_x: Tuple[float, float, float], tuple_y: Tuple[float, float, float], tuple_z: Tuple[float, float, float], suffix_alpha: str = "alpha", suffix_beta: str = "beta", suffix_gamma: str = "gamma", ) -> Dict[str, List[float]]: """ Given a ``PauliTerm``, create a memory map corresponding to a collection of ZXZXZ-decomposed single-qubit gates. The intent is that these gate are used to prepare an eigenstate of the ``PauliTerm`` or measure in the eigenbasis of the ``PauliTerm``, which is more clearly discernible from the calling functions ``pauli_term_to_preparation_memory_map`` (for state preparation) and ``pauli_term_to_measurement_memory_map`` (for measuring in different bases). This function is not really meant to be used by itself, but rather by the aforementioned calling functions. :param term: The ``PauliTerm`` in question. :param prefix: The prefix for the declared memory region labels. For example, if the prefix is "preparation" and the alpha, beta, and gamma suffixes are left as default, the labels would be "preparation_alpha", "preparation_beta", and "preparation_gamma". :param tuple_x: A tuple of Euler angles as (alpha, beta, gamma) to be used for the ``X`` operators in the ``PauliTerm``. :param tuple_y: A tuple of Euler angles as (alpha, beta, gamma) to be used for the ``Y`` operators in the ``PauliTerm``. :param tuple_z: A tuple of Euler angles as (alpha, beta, gamma) to be used for the ``Z`` and ``I`` operators in the ``PauliTerm``. :param suffix_alpha: The suffix for the "alpha" memory region label, which corresponds to the first (rightmost) ``Z`` in the ZXZXZ decomposition. Defaults to "alpha". :param suffix_beta: The suffix for the "beta" memory region label, which corresponds to the second (middle) ``Z`` in the ZXZXZ decomposition. Defaults to "beta". :param suffix_gamma: The suffix for the "gamma" memory region label, which corresponds to the last (leftmost) ``Z`` in the ZXZXZ decomposition. Defaults to "gamma". :return: Memory map dictionary containing three entries (three labels as keys and three lists of angles as values). """ # no need to provide a memory map when no rotations are necessary if ("X" not in term.pauli_string()) and ("Y" not in term.pauli_string()): return {} alpha_label = f"{prefix}_{suffix_alpha}" beta_label = f"{prefix}_{suffix_beta}" gamma_label = f"{prefix}_{suffix_gamma}" # assume the pauli indices are equivalent to the memory region memory_size = max(term.get_qubits()) + 1 memory_map = { alpha_label: [0.0] * memory_size, beta_label: [0.0] * memory_size, gamma_label: [0.0] * memory_size, } tuples = {"X": tuple_x, "Y": tuple_y, "Z": tuple_z, "I": tuple_z} for qubit, operator in term: if operator not in tuples: raise ValueError(f"Unknown operator {operator}") memory_map[alpha_label][qubit] = tuples[operator][0] memory_map[beta_label][qubit] = tuples[operator][1] memory_map[gamma_label][qubit] = tuples[operator][2] return memory_map