def test_parameterized_single_qubit_measurement_basis(): p = Program() alpha = p.declare("measurement_alpha", "REAL", 2) beta = p.declare("measurement_beta", "REAL", 2) gamma = p.declare("measurement_gamma", "REAL", 2) for idx, q in enumerate(range(2)): p += RZ(alpha[idx], q) p += RX(np.pi / 2, q) p += RZ(beta[idx], q) p += RX(-np.pi / 2, q) p += RZ(gamma[idx], q) assert parameterized_single_qubit_measurement_basis([0, 1]).out() == p.out()
def generate_experiment_program(self) -> Program: """ Generate a parameterized program containing the main body program along with some additions to support the various state preparation, measurement, and symmetrization specifications of this ``Experiment``. State preparation and measurement are achieved via ZXZXZ-decomposed single-qubit gates, where the angles of each ``RZ`` rotation are declared parameters that can be assigned at runtime. Symmetrization is achieved by putting an ``RX`` gate (also parameterized by a declared value) before each ``MEASURE`` operation. In addition, a ``RESET`` operation is prepended to the ``Program`` if the experiment has active qubit reset enabled. Finally, each qubit specified in the settings is measured, and the number of shots is added. :return: Parameterized ``Program`` that is capable of collecting statistics for every ``ExperimentSetting`` in this ``Experiment``. """ meas_qubits = self.get_meas_qubits() p = Program() if self.reset: if any( isinstance(instr, (Reset, ResetQubit)) for instr in self.program): raise ValueError("RESET already added to program") p += RESET() for settings in self: assert len(settings) == 1 if ("X" in str(settings[0].in_state)) or ("Y" in str( settings[0].in_state)): if f"DECLARE preparation_alpha" in self.program.out(): raise ValueError( f'Memory "preparation_alpha" has been declared already.' ) if f"DECLARE preparation_beta" in self.program.out(): raise ValueError( f'Memory "preparation_beta" has been declared already.' ) if f"DECLARE preparation_gamma" in self.program.out(): raise ValueError( f'Memory "preparation_gamma" has been declared already.' ) p += parameterized_single_qubit_state_preparation(meas_qubits) break p += self.program for settings in self: assert len(settings) == 1 if ("X" in str(settings[0].out_operator)) or ("Y" in str( settings[0].out_operator)): if f"DECLARE measurement_alpha" in self.program.out(): raise ValueError( f'Memory "measurement_alpha" has been declared already.' ) if f"DECLARE measurement_beta" in self.program.out(): raise ValueError( f'Memory "measurement_beta" has been declared already.' ) if f"DECLARE measurement_gamma" in self.program.out(): raise ValueError( f'Memory "measurement_gamma" has been declared already.' ) p += parameterized_single_qubit_measurement_basis(meas_qubits) break if self.symmetrization != 0: if f"DECLARE symmetrization" in self.program.out(): raise ValueError( f'Memory "symmetrization" has been declared already.') p += parameterized_readout_symmetrization(meas_qubits) if "DECLARE ro" in self.program.out(): raise ValueError( 'Memory "ro" has already been declared for this program.') p += measure_qubits(meas_qubits) p.wrap_in_numshots_loop(self.shots) return p
def test_generate_experiment_program(): # simplest example p = Program() s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0)), out_operator=sZ(0)) e = Experiment(settings=[s], program=p, symmetrization=0) exp = e.generate_experiment_program() test_exp = Program() ro = test_exp.declare("ro", "BIT") test_exp += MEASURE(0, ro[0]) assert exp.out() == test_exp.out() assert exp.num_shots == 1 # 2Q exhaustive symmetrization p = Program() s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0) * sZ(1)), out_operator=sZ(0) * sZ(1)) e = Experiment(settings=[s], program=p) exp = e.generate_experiment_program() test_exp = Program() test_exp += parameterized_readout_symmetrization([0, 1]) ro = test_exp.declare("ro", "BIT", 2) test_exp += MEASURE(0, ro[0]) test_exp += MEASURE(1, ro[1]) assert exp.out() == test_exp.out() assert exp.num_shots == 1 # add shots p = Program() p.wrap_in_numshots_loop(1000) s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0)), out_operator=sZ(0)) e = Experiment(settings=[s], program=p, symmetrization=0) exp = e.generate_experiment_program() test_exp = Program() ro = test_exp.declare("ro", "BIT") test_exp += MEASURE(0, ro[0]) assert exp.out() == test_exp.out() assert exp.num_shots == 1000 # active reset p = Program() p += RESET() s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0)), out_operator=sZ(0)) e = Experiment(settings=[s], program=p, symmetrization=0) exp = e.generate_experiment_program() test_exp = Program() test_exp += RESET() ro = test_exp.declare("ro", "BIT") test_exp += MEASURE(0, ro[0]) assert exp.out() == test_exp.out() assert exp.num_shots == 1 # state preparation and measurement p = Program() s = ExperimentSetting(in_state=_pauli_to_product_state(sY(0)), out_operator=sX(0)) e = Experiment(settings=[s], program=p, symmetrization=0) exp = e.generate_experiment_program() test_exp = Program() test_exp += parameterized_single_qubit_state_preparation([0]) test_exp += parameterized_single_qubit_measurement_basis([0]) ro = test_exp.declare("ro", "BIT") test_exp += MEASURE(0, ro[0]) assert exp.out() == test_exp.out() assert exp.num_shots == 1 # multi-qubit state preparation and measurement p = Program() s = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0) * sY(1)), out_operator=sZ(0) * sX(1)) e = Experiment(settings=[s], program=p, symmetrization=0) exp = e.generate_experiment_program() test_exp = Program() test_exp += parameterized_single_qubit_state_preparation([0, 1]) test_exp += parameterized_single_qubit_measurement_basis([0, 1]) ro = test_exp.declare("ro", "BIT", 2) test_exp += MEASURE(0, ro[0]) test_exp += MEASURE(1, ro[1]) assert exp.out() == test_exp.out() assert exp.num_shots == 1