def _single_projector_generator(ket_op, bra_op, index): """ Generate the pauli sum terms corresponding to |ket_op><brak_op| :param ket_op: single qubit computational basis state :param bra_op: single qubit computational basis state :param index: qubit index to assign to the projector :return: pauli sum of single qubit projection operator :rtype: PauliSum """ if not isinstance(ket_op, int): raise TypeError("ket_op needs to be an integer") if not isinstance(bra_op, int): raise TypeError("ket_op needs to be an integer") if ket_op not in [0, 1] or bra_op not in [0, 1]: raise ValueError("bra and ket op needs to be either 0 or 1") if ket_op == 0 and bra_op == 0: return 0.5 * (sZ(index) + sI(index)) elif ket_op == 0 and bra_op == 1: return 0.5 * (sX(index) + 1j * sY(index)) elif ket_op == 1 and bra_op == 0: return 0.5 * (sX(index) - 1j * sY(index)) else: return 0.5 * (sI(index) - sZ(index))
def test_compute_action_XY(): """ Action of Pauli operators on state """ comp_basis_state = [0, 0, 0, 0] for ii in range(3): pauli_term = sX(ii) * sY(ii + 1) new_basis_state, coeff = compute_action(comp_basis_state, pauli_term, len(comp_basis_state)) # abuse of comparisons in python true_basis_state = comp_basis_state.copy() true_basis_state[ii] ^= 1 true_basis_state[ii + 1] ^= 1 assert new_basis_state == true_basis_state assert np.isclose(coeff, 1j) comp_basis_state = [1, 1, 1, 1] for ii in range(3): pauli_term = sX(ii) * sY(ii + 1) new_basis_state, coeff = compute_action(comp_basis_state, pauli_term, len(comp_basis_state)) # abuse of comparisons in python true_basis_state = comp_basis_state.copy() true_basis_state[ii] ^= 1 true_basis_state[ii + 1] ^= 1 assert new_basis_state == true_basis_state assert np.isclose(coeff, -1j)
def test_single_projector(): """ Testing the projector generator. Test if it returns the correct non-hermitian operator. These tests are for a single qubit """ zero_projector = _single_projector_generator(0, 0, 0) true_zero_projector = 0.5 * (sZ(0) + sI(0)) assert zero_projector == true_zero_projector with pytest.raises(TypeError): _single_projector_generator('a', 0, 5) with pytest.raises(TypeError): _single_projector_generator(0, 'a', 5) with pytest.raises(TypeError): _single_projector_generator(0, 0.0, 5) with pytest.raises(TypeError): _single_projector_generator(0.0, 0, 5) with pytest.raises(ValueError): _single_projector_generator(5, 0, 5) with pytest.raises(ValueError): _single_projector_generator(1, 4, 5) one_projector = _single_projector_generator(1, 1, 5) true_one_projector = 0.5 * (sI(5) - sZ(5)) assert true_one_projector == one_projector lowering_projector = _single_projector_generator(0, 1, 2) true_lowering_projector = 0.5 * (sX(2) + 1j * sY(2)) assert true_lowering_projector == lowering_projector raising_projector = _single_projector_generator(1, 0, 2) true_raising_projector = 0.5 * (sX(2) - 1j * sY(2)) assert true_raising_projector == raising_projector
def test_group_experiments_greedy(): ungrouped_tomo_expt = Experiment( [ [ ExperimentSetting( _pauli_to_product_state( PauliTerm.from_compact_str("(1+0j)*Z7Y8Z1Y4Z2Y5Y0X6")), PauliTerm.from_compact_str("(1+0j)*Z4X8Y5X3Y7Y1"), ) ], [ExperimentSetting(plusZ(7), sY(1))], ], program=Program(H(0), H(1), H(2)), ) grouped_tomo_expt = group_settings(ungrouped_tomo_expt, method="greedy") expected_grouped_tomo_expt = Experiment( [[ ExperimentSetting( TensorProductState.from_str( "Z0_7 * Y0_8 * Z0_1 * Y0_4 * Z0_2 * Y0_5 * Y0_0 * X0_6"), PauliTerm.from_compact_str("(1+0j)*Z4X8Y5X3Y7Y1"), ), ExperimentSetting(plusZ(7), sY(1)), ]], program=Program(H(0), H(1), H(2)), ) assert grouped_tomo_expt == expected_grouped_tomo_expt
def test_max_weight_operator_misc(): assert _max_weight_operator([sZ(0), sZ(0) * sZ(1)]) is not None assert _max_weight_operator([sX(5), sZ(4)]) is not None assert _max_weight_operator([sX(0), sY(0) * sZ(2)]) is None x_term = sX(0) * sX(1) z1_term = sZ(1) z0_term = sZ(0) z0z1_term = sZ(0) * sZ(1) assert _max_weight_operator([x_term, z1_term]) is None assert _max_weight_operator([z0z1_term, x_term]) is None assert _max_weight_operator([z1_term, z0_term]) is not None assert _max_weight_operator([z0z1_term, z0_term]) is not None assert _max_weight_operator([z0z1_term, z1_term]) is not None assert _max_weight_operator([z0z1_term, sI(1)]) is not None assert _max_weight_operator([z0z1_term, sI(2)]) is not None assert _max_weight_operator([z0z1_term, sX(5) * sZ(7)]) is not None xxxx_terms = (sX(1) * sX(2) + sX(2) + sX(3) * sX(4) + sX(4) + sX(1) * sX(3) * sX(4) + sX(1) * sX(4) + sX(1) * sX(2) * sX(3)) true_term = sX(1) * sX(2) * sX(3) * sX(4) assert _max_weight_operator(xxxx_terms.terms) == true_term zzzz_terms = sZ(1) * sZ(2) + sZ(3) * sZ(4) + sZ(1) * sZ(3) + sZ(1) * sZ( 3) * sZ(4) assert _max_weight_operator( zzzz_terms.terms) == sZ(1) * sZ(2) * sZ(3) * sZ(4) pauli_terms = [sZ(0), sX(1) * sZ(0), sY(2) * sX(1), sZ(5) * sI(3)] assert _max_weight_operator(pauli_terms) == sZ(5) * sY(2) * sX(1) * sZ(0)
def test_measure_observables_many_progs(forest): expts = [ ExperimentSetting(sI(), o1 * o2) for o1, o2 in itertools.product([sI(0), sX(0), sY(0), sZ(0)], [sI(1), sX(1), sY(1), sZ(1)]) ] qc = get_qc('2q-qvm') qc.qam.random_seed = 51 for prog in _random_2q_programs(): suite = TomographyExperiment(expts, program=prog, qubits=[0, 1]) assert len(suite) == 4 * 4 gsuite = group_experiments(suite) assert len( gsuite ) == 3 * 3 # can get all the terms with I for free in this case wfn = WavefunctionSimulator() wfn_exps = {} for expt in expts: wfn_exps[expt] = wfn.expectation(gsuite.program, PauliSum([expt.out_operator])) for res in measure_observables(qc, gsuite, n_shots=1_000): np.testing.assert_allclose(wfn_exps[res.setting], res.expectation, atol=0.1)
def test_marginal(): """ Generate ground state of heinsenberg spin model and general all 1-marginals Heisenberg spin model is H = sum_{<ij>} X_{i}X_{j} + Y_{i}Y_{j} + Z_{i}Z_{j} :return: """ # generate state for Heisenberg spin-model qubits = 4 hamiltonian = sI(0) * 0.0 for ii in range(qubits): hamiltonian += sX(ii) * sX((ii + 1) % qubits) hamiltonian += sY(ii) * sY((ii + 1) % qubits) hamiltonian += sZ(ii) * sZ((ii + 1) % qubits) hamiltonian_matrix = tensor_up(hamiltonian, qubits) w, v = np.linalg.eigh(hamiltonian_matrix) rho = v[:, [0]].dot(np.conj(v[:, [0]]).T) mg = MarginalGenerator(rho) marginals = mg.construct_p_marginals(2) for marginal_id, marginal in marginals.items(): assert np.isclose(marginal.trace(), 1.0)
def test_identity_removal(): test_term = 0.25 * sX(1) * sZ(2) * sX(3) + 0.25j * sX(1) * sZ(2) * sY(3) test_term += -0.25j * sY(1) * sZ(2) * sX(3) + 0.25 * sY(1) * sZ(2) * sY(3) identity_term = 200 * sI(5) new_psum, identity_term_result = remove_identity(identity_term + test_term) assert test_term == new_psum assert identity_term_result == identity_term
def test_commuting_sets_by_zbasis(): # complicated coefficients, overlap on single qubit coeff1 = 0.012870253243021476 term1 = PauliTerm.from_list([('X', 1), ('Z', 2), ('Y', 3), ('Y', 5), ('Z', 6), ('X', 7)], coefficient=coeff1) coeff2 = 0.13131672212575296 term2 = PauliTerm.from_list([('Z', 0), ('Z', 6)], coefficient=coeff2) d_result = commuting_sets_by_zbasis(term1 + term2) d_expected = { ((0, 'Z'), (1, 'X'), (2, 'Z'), (3, 'Y'), (5, 'Y'), (6, 'Z'), (7, 'X')): [ coeff1 * sX(1) * sZ(2) * sY(3) * sY(5) * sZ(6) * sX(7), coeff2 * sZ(0) * sZ(6) ] } assert d_result == d_expected # clumping terms relevant for H2 into same diagonal bases x_term = sX(0) * sX(1) z1_term = sZ(1) z2_term = sZ(0) zz_term = sZ(0) * sZ(1) z_terms = [z1_term, z2_term, zz_term] h2_hamiltonian = sum(z_terms) + x_term clumped_terms = commuting_sets_by_zbasis(h2_hamiltonian) true_set = { ((0, 'X'), (1, 'X')): {x_term}, ((0, 'Z'), (1, 'Z')): set(z_terms) } for key, value in clumped_terms.items(): assert set(value) == true_set[key] # clumping 4-qubit terms into same diagonal bases zzzz_terms = sZ(1) * sZ(2) + sZ(3) * sZ(4) + \ sZ(1) * sZ(3) + sZ(1) * sZ(3) * sZ(4) xzxz_terms = sX(1) * sZ(2) + sX(3) * sZ(4) + \ sX(1) * sZ(2) * sX(3) * sZ(4) + sX(1) * sX(3) * sZ(4) xxxx_terms = sX(1) * sX(2) + sX(2) + sX(3) * sX(4) + sX(4) + \ sX(1) * sX(3) * sX(4) + sX(1) * sX(4) + sX(1) * sX(2) * sX(3) yyyy_terms = sY(1) * sY(2) + sY(3) * sY(4) + sY(1) * sY(2) * sY(3) * sY(4) pauli_sum = zzzz_terms + xzxz_terms + xxxx_terms + yyyy_terms clumped_terms = commuting_sets_by_zbasis(pauli_sum) true_set = { ((1, 'Z'), (2, 'Z'), (3, 'Z'), (4, 'Z')): set(zzzz_terms), ((1, 'X'), (2, 'Z'), (3, 'X'), (4, 'Z')): set(xzxz_terms), ((1, 'X'), (2, 'X'), (3, 'X'), (4, 'X')): set(xxxx_terms), ((1, 'Y'), (2, 'Y'), (3, 'Y'), (4, 'Y')): set(yyyy_terms) } for key, value in clumped_terms.items(): assert set(value) == true_set[key]
def test_sum_equality(): pauli_sum = sY(0) - sX(0) assert pauli_sum != 2 * pauli_sum assert pauli_sum != pauli_sum + sZ(0) assert pauli_sum + sZ(0) != pauli_sum assert pauli_sum != sY(1) - sX(1) assert pauli_sum == -1.0 * sX(0) + sY(0) assert pauli_sum == pauli_sum * 1.0 with pytest.raises(TypeError): assert pauli_sum != 0
def test_sum_equality(): q0, q1 = QubitPlaceholder.register(2) pauli_sum = sY(q0) - sX(q0) assert pauli_sum != 2 * pauli_sum assert pauli_sum != pauli_sum + sZ(q0) assert pauli_sum + sZ(q0) != pauli_sum assert pauli_sum != sY(q1) - sX(q1) assert pauli_sum == -1.0 * sX(q0) + sY(q0) assert pauli_sum == pauli_sum * 1.0 with pytest.raises(TypeError): assert pauli_sum != 0
def test_merge_disjoint_experiments(): sett1 = ExperimentSetting(TensorProductState(), sX(0) * sY(1)) sett2 = ExperimentSetting(plusZ(1), sY(1)) sett3 = ExperimentSetting(plusZ(0), sX(0)) sett4 = ExperimentSetting(minusX(1), sY(1)) sett5 = ExperimentSetting(TensorProductState(), sZ(2)) expt1 = Experiment(settings=[sett1, sett2], program=Program(X(1))) expt2 = Experiment(settings=[sett3, sett4], program=Program(Z(0))) expt3 = Experiment(settings=[sett5], program=Program()) merged_expt = merge_disjoint_experiments([expt1, expt2, expt3]) assert len(merged_expt) == 2
def test_max_key_overlap(): # adds to already existing key x0_term = sX(0) diag_sets = { ((0, 'X'), (1, 'Z')): [sX(0) * sZ(1), sZ(1)], ((0, 'Y'), (1, 'Z')): [sY(0), sZ(1), sY(0) * sZ(1)] } d_expected = { ((0, 'X'), (1, 'Z')): [sX(0) * sZ(1), sZ(1), sX(0)], ((0, 'Y'), (1, 'Z')): [sY(0), sZ(1), sY(0) * sZ(1)] } assert _max_key_overlap(x0_term, diag_sets) == d_expected # adds a new key x0_term = sX(0) diag_sets = { ((0, 'Z'), (1, 'Z')): [sZ(0) * sZ(1), sZ(1)], ((0, 'Y'), (1, 'Z')): [sY(0), sZ(1), sY(0) * sZ(1)] } d_expected = { ((0, 'Z'), (1, 'Z')): [sZ(0) * sZ(1), sZ(1)], ((0, 'Y'), (1, 'Z')): [sY(0), sZ(1), sY(0) * sZ(1)], ((0, 'X'), ): [sX(0)] } assert _max_key_overlap(x0_term, diag_sets) == d_expected
def test_all_ops_belong_to_tpb(): expts = [ [ ExperimentSetting(sI(), sX(0) * sI(1)), ExperimentSetting(sI(), sI(0) * sX(1)) ], [ ExperimentSetting(sI(), sZ(0) * sI(1)), ExperimentSetting(sI(), sI(0) * sZ(1)) ], ] for group in expts: for e1, e2 in itertools.combinations(group, 2): assert _all_qubits_diagonal_in_tpb(e1.in_operator, e2.in_operator) assert _all_qubits_diagonal_in_tpb(e1.out_operator, e2.out_operator) assert _all_qubits_diagonal_in_tpb(sZ(0), sZ(0) * sZ(1)) assert _all_qubits_diagonal_in_tpb(sX(5), sZ(4)) assert not _all_qubits_diagonal_in_tpb(sX(0), sY(0) * sZ(2)) # this last example illustrates that a pair of commuting operators # need not be diagonal in the same tpb assert not _all_qubits_diagonal_in_tpb(sX(1) * sZ(0), sZ(1) * sX(0))
def test_no_complex_coeffs(forest): qc = get_qc('2q-qvm') suite = TomographyExperiment([ExperimentSetting(sI(), 1.j * sY(0))], program=Program(X(0)), qubits=[0]) with pytest.raises(ValueError): res = list(measure_observables(qc, suite))
def test_measure_observables(forest): expts = [ ExperimentSetting(sI(), o1 * o2) for o1, o2 in itertools.product([sI(0), sX(0), sY(0), sZ(0)], [sI(1), sX(1), sY(1), sZ(1)]) ] suite = TomographyExperiment(expts, program=Program(X(0), CNOT(0, 1)), qubits=[0, 1]) assert len(suite) == 4 * 4 gsuite = group_experiments(suite) assert len(gsuite) == 3 * 3 # can get all the terms with I for free in this case qc = get_qc('2q-qvm') for res in measure_observables(qc, gsuite, n_shots=10_000): if res.setting.out_operator in [sI(), sZ(0), sZ(1), sZ(0) * sZ(1)]: assert np.abs(res.expectation) > 0.9 else: assert np.abs(res.expectation) < 0.1
def test_group_experiments_greedy(): ungrouped_tomo_expt = TomographyExperiment( [[ExperimentSetting(PauliTerm.from_compact_str('(1+0j)*Z7Y8Z1Y4Z2Y5Y0X6'), PauliTerm.from_compact_str('(1+0j)*Z4X8Y5X3Y7Y1'))], [ExperimentSetting(sZ(7), sY(1))]], program=Program(H(0), H(1), H(2)), qubits=[0, 1, 2]) grouped_tomo_expt = group_experiments(ungrouped_tomo_expt, method='greedy') expected_grouped_tomo_expt = TomographyExperiment( [[ ExperimentSetting(TensorProductState.from_str('Z0_7 * Y0_8 * Z0_1 * Y0_4 * ' 'Z0_2 * Y0_5 * Y0_0 * X0_6'), PauliTerm.from_compact_str('(1+0j)*Z4X8Y5X3Y7Y1')), ExperimentSetting(plusZ(7), sY(1)) ]], program=Program(H(0), H(1), H(2)), qubits=[0, 1, 2]) assert grouped_tomo_expt == expected_grouped_tomo_expt
def test_expt_settings_diagonal_in_tpb(): def _expt_settings_diagonal_in_tpb(es1: ExperimentSetting, es2: ExperimentSetting): """ Extends the concept of being diagonal in the same tpb to ExperimentSettings, by determining if the pairs of in_states and out_operators are separately diagonal in the same tpb """ max_weight_in = _max_weight_state([es1.in_state, es2.in_state]) max_weight_out = _max_weight_operator([es1.out_operator, es2.out_operator]) return max_weight_in is not None and max_weight_out is not None expt_setting1 = ExperimentSetting(plusZ(1) * plusX(0), sY(1) * sZ(0)) expt_setting2 = ExperimentSetting(plusY(2) * plusZ(1), sZ(2) * sY(1)) assert _expt_settings_diagonal_in_tpb(expt_setting1, expt_setting2) expt_setting3 = ExperimentSetting(plusX(2) * plusZ(1), sZ(2) * sY(1)) expt_setting4 = ExperimentSetting(plusY(2) * plusZ(1), sX(2) * sY(1)) assert not _expt_settings_diagonal_in_tpb(expt_setting2, expt_setting3) assert not _expt_settings_diagonal_in_tpb(expt_setting2, expt_setting4)
def test_sum_power(): pauli_sum = (sY(0) - sX(0)) * (1.0 / np.sqrt(2)) assert pauli_sum ** 2 == PauliSum([sI(0)]) with pytest.raises(ValueError): _ = pauli_sum ** -1 pauli_sum = sI(0) + sI(1) assert pauli_sum ** 0 == sI(0) # Test to make sure large powers can be computed pauli_sum ** 400
def test_sum_power(): q = QubitPlaceholder.register(8) pauli_sum = (sY(q[0]) - sX(q[0])) * (1.0 / np.sqrt(2)) assert pauli_sum**2 == PauliSum([sI(q[0])]) with pytest.raises(ValueError): _ = pauli_sum**-1 pauli_sum = sI(q[0]) + sI(q[1]) assert pauli_sum**0 == sI(q[0]) # Test to make sure large powers can be computed pauli_sum**400
def test_term_powers(): for qubit in QubitPlaceholder.register(2): pauli_terms = [sI(qubit), sX(qubit), sY(qubit), sZ(qubit)] for pauli_term in pauli_terms: assert pauli_term**0 == sI(qubit) assert pauli_term**1 == pauli_term assert pauli_term**2 == sI(qubit) assert pauli_term**3 == pauli_term with pytest.raises(ValueError): pauli_terms[0]**-1
def test_qc_expectation_larger_lattice(forest): device = NxDevice(nx.complete_graph(4)) qc = QuantumComputer(name='testy!', qam=QVM(connection=forest), device=device, compiler=DummyCompiler()) q0 = 2 q1 = 3 # bell state program p = Program() p += RESET() p += H(q0) p += CNOT(q0, q1) p.wrap_in_numshots_loop(10) # XX, YY, ZZ experiment sx = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sX(q0) * sX(q1)) sy = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sY(q0) * sY(q1)) sz = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sZ(q0) * sZ(q1)) e = TomographyExperiment(settings=[sx, sy, sz], program=p) results = qc.experiment(e) # XX expectation value for bell state |00> + |11> is 1 assert np.isclose(results[0].expectation, 1) assert np.isclose(results[0].std_err, 0) assert results[0].total_counts == 40 # YY expectation value for bell state |00> + |11> is -1 assert np.isclose(results[1].expectation, -1) assert np.isclose(results[1].std_err, 0) assert results[1].total_counts == 40 # ZZ expectation value for bell state |00> + |11> is 1 assert np.isclose(results[2].expectation, 1) assert np.isclose(results[2].std_err, 0) assert results[2].total_counts == 40
def test_projector_generator(): """ Test if we are getting accurate projectors--multiqubit case """ true_zero_projector = 0.5 * (sZ(0) + sI(0)) zero_projector = projector_generator([0], [0]) assert true_zero_projector == zero_projector one_projector = projector_generator([1], [1]) true_one_projector = 0.5 * (sI(0) - sZ(0)) assert true_one_projector == one_projector lowering_projector = projector_generator([0], [1]) true_lowering_projector = 0.5 * (sX(0) + 1j * sY(0)) assert true_lowering_projector == lowering_projector raising_projector = projector_generator([1], [0]) true_raising_projector = 0.5 * (sX(0) - 1j * sY(0)) assert true_raising_projector == raising_projector
def test_rotation_programs(): """ Testing the generation of post rotations """ test_term = sZ(0) * sX(20) * sI(100) * sY(5) # note: string comparison of programs requires gates to be in the same order true_rotation_program = Program().inst( [RX(np.pi / 2)(5), RY(-np.pi / 2)(20)]) test_rotation_program = get_rotation_program(test_term) assert true_rotation_program.out() == test_rotation_program.out()
def test_max_tpb_overlap_3(): # add another ExperimentSetting to the above expt_setting = ExperimentSetting(PauliTerm.from_compact_str('(1+0j)*Z7Y8Z1Y4Z2Y5Y0X6'), PauliTerm.from_compact_str('(1+0j)*Z4X8Y5X3Y7Y1')) expt_setting2 = ExperimentSetting(sZ(7), sY(1)) p = Program(H(0), H(1), H(2)) qubits = [0, 1, 2] tomo_expt2 = TomographyExperiment([expt_setting, expt_setting2], p, qubits) expected_dict2 = {expt_setting: [expt_setting, expt_setting2]} assert expected_dict2 == _max_tpb_overlap(tomo_expt2)
def error(order, time_step_length): a_pauli = time_step_length * sZ(0) * sY(1) * sX(2) a_program = a_pauli.program b_pauli = time_step_length * sX(0) * sZ(1) * sY(2) b_program = b_pauli.program num_qubits = len(a_program.get_qubits()) assert num_qubits == len(b_program.get_qubits()) a = program_unitary(a_program, num_qubits) b = program_unitary(b_program, num_qubits) a_plus_b = a + b exp_a_plus_b = expmi(time_step_length * a_plus_b) trotter_program = trotterize(a_pauli, b_pauli, trotter_order=order) trotter = program_unitary(trotter_program, num_qubits) return np.linalg.norm(exp_a_plus_b - trotter, np.inf)
def test_qc_expectation_larger_lattice( client_configuration: QCSClientConfiguration, dummy_compiler: DummyCompiler): qc = QuantumComputer(name="testy!", qam=QVM(client_configuration=client_configuration), compiler=dummy_compiler) q0 = 2 q1 = 3 # bell state program p = Program() p += RESET() p += H(q0) p += CNOT(q0, q1) p.wrap_in_numshots_loop(10) # XX, YY, ZZ experiment sx = ExperimentSetting(in_state=_pauli_to_product_state(sZ(q0) * sZ(q1)), out_operator=sX(q0) * sX(q1)) sy = ExperimentSetting(in_state=_pauli_to_product_state(sZ(q0) * sZ(q1)), out_operator=sY(q0) * sY(q1)) sz = ExperimentSetting(in_state=_pauli_to_product_state(sZ(q0) * sZ(q1)), out_operator=sZ(q0) * sZ(q1)) e = Experiment(settings=[sx, sy, sz], program=p) results = qc.run_experiment(e) # XX expectation value for bell state |00> + |11> is 1 assert np.isclose(results[0].expectation, 1) assert np.isclose(results[0].std_err, 0) assert results[0].total_counts == 40 # YY expectation value for bell state |00> + |11> is -1 assert np.isclose(results[1].expectation, -1) assert np.isclose(results[1].std_err, 0) assert results[1].total_counts == 40 # ZZ expectation value for bell state |00> + |11> is 1 assert np.isclose(results[2].expectation, 1) assert np.isclose(results[2].std_err, 0) assert results[2].total_counts == 40
def test_max_tpb_overlap_1(): tomo_expt_settings = [ExperimentSetting(sZ(1) * sX(0), sY(2) * sY(1)), ExperimentSetting(sX(2) * sZ(1), sY(2) * sZ(0))] tomo_expt_program = Program(H(0), H(1), H(2)) tomo_expt_qubits = [0, 1, 2] tomo_expt = TomographyExperiment(tomo_expt_settings, tomo_expt_program, tomo_expt_qubits) expected_dict = { ExperimentSetting(plusX(0) * plusZ(1) * plusX(2), sZ(0) * sY(1) * sY(2)): [ ExperimentSetting(plusZ(1) * plusX(0), sY(2) * sY(1)), ExperimentSetting(plusX(2) * plusZ(1), sY(2) * sZ(0)) ] } assert expected_dict == _max_tpb_overlap(tomo_expt)
def test_group_experiments_greedy(): ungrouped_tomo_expt = TomographyExperiment([[ ExperimentSetting( PauliTerm.from_compact_str('(1+0j)*Z7Y8Z1Y4Z2Y5Y0X6'), PauliTerm.from_compact_str('(1+0j)*Z4X8Y5X3Y7Y1')) ], [ExperimentSetting(sZ(7), sY(1))]], program=Program( H(0), H(1), H(2)), qubits=[0, 1, 2]) grouped_tomo_expt = group_experiments_greedy(ungrouped_tomo_expt) expected_grouped_tomo_expt = TomographyExperiment([[ ExperimentSetting( PauliTerm.from_compact_str('(1+0j)*Z7Y8Z1Y4Z2Y5Y0X6'), PauliTerm.from_compact_str('(1+0j)*Z4X8Y5X3Y7Y1')), ExperimentSetting(sZ(7), sY(1)) ]], program=Program( H(0), H(1), H(2)), qubits=[0, 1, 2]) assert grouped_tomo_expt == expected_grouped_tomo_expt
def test_term_powers(): for qubit_id in range(2): pauli_terms = [sI(qubit_id), sX(qubit_id), sY(qubit_id), sZ(qubit_id)] for pauli_term in pauli_terms: assert pauli_term ** 0 == sI(qubit_id) assert pauli_term ** 1 == pauli_term assert pauli_term ** 2 == sI(qubit_id) assert pauli_term ** 3 == pauli_term with pytest.raises(ValueError): pauli_terms[0] ** -1 # Test to make sure large powers can be computed (PauliTerm('X', 0, 2) * PauliTerm('Y', 0, 2)) ** 400
from pyquil.paulis import ID, sX, sY, sZ from pyquil import * from pyquil.gates import H import pyquil.paulis as pl # Pauli term takes an operator "X", "Y", "Z", or "I"; a qubit to act on, and # an optional coefficient. a = 1 * ID() b = -0.75 * sX(0) * sY(1) * sZ(3) c = (5-2j) * sZ(1) * sX(2) # Construct a sum of Pauli terms. sigma = a + b + c print("sigma = {}".format(sigma)) p = Program() p.inst(pl.exponentiate_commuting_pauli_sum(sigma)) print(p)