def test_list_op_constructor_matches_mapping(pauli): q0, = _make_qubits(1) op = pauli.on(q0) assert cirq.PauliString([op]) == cirq.PauliString({q0: pauli})
def test_from_single(pauli): q0, = _make_qubits(1) assert (cirq.PauliString.from_single(q0, pauli) == cirq.PauliString({q0: pauli}))
def test_keys(qubit_pauli_map): pauli_string = cirq.PauliString(qubit_pauli_map) assert (len(qubit_pauli_map.keys()) == len(pauli_string.keys()) == len(pauli_string.qubits())) assert (set(qubit_pauli_map.keys()) == set(pauli_string.keys()) == set(pauli_string.qubits()))
def test_zip_items(map1, map2, out): ps1 = cirq.PauliString(map1) ps2 = cirq.PauliString(map2) out_actual = tuple(ps1.zip_items(ps2)) assert len(out_actual) == len(out) assert dict(out_actual) == out
def test_pos(): q0, q1 = _make_qubits(2) qubit_pauli_map = {q0: cirq.Pauli.X, q1: cirq.Pauli.Y} ps1 = cirq.PauliString(qubit_pauli_map) assert ps1 == +ps1
def test_values(qubit_pauli_map): pauli_string = cirq.PauliString(qubit_pauli_map) assert len(qubit_pauli_map.values()) == len(pauli_string.values()) assert set(qubit_pauli_map.values()) == set(pauli_string.values())
def test_iter(qubit_pauli_map): pauli_string = cirq.PauliString(qubit_pauli_map) assert len(tuple(qubit_pauli_map)) == len(tuple(pauli_string)) assert set(tuple(qubit_pauli_map)) == set(tuple(pauli_string))
@pytest.mark.parametrize( 'op,expected_ops', ( lambda q0, q1: ( (cirq.X(q0), cirq.SingleQubitCliffordGate.X(q0)), (cirq.Y(q0), cirq.SingleQubitCliffordGate.Y(q0)), (cirq.Z(q0), cirq.SingleQubitCliffordGate.Z(q0)), (cirq.X(q0) ** 0.5, cirq.SingleQubitCliffordGate.X_sqrt(q0)), (cirq.Y(q0) ** 0.5, cirq.SingleQubitCliffordGate.Y_sqrt(q0)), (cirq.Z(q0) ** 0.5, cirq.SingleQubitCliffordGate.Z_sqrt(q0)), (cirq.X(q0) ** -0.5, cirq.SingleQubitCliffordGate.X_nsqrt(q0)), (cirq.Y(q0) ** -0.5, cirq.SingleQubitCliffordGate.Y_nsqrt(q0)), (cirq.Z(q0) ** -0.5, cirq.SingleQubitCliffordGate.Z_nsqrt(q0)), (cirq.X(q0) ** 0.25, cirq.PauliStringPhasor(cirq.PauliString([cirq.X.on(q0)])) ** 0.25), (cirq.Y(q0) ** 0.25, cirq.PauliStringPhasor(cirq.PauliString([cirq.Y.on(q0)])) ** 0.25), (cirq.Z(q0) ** 0.25, cirq.PauliStringPhasor(cirq.PauliString([cirq.Z.on(q0)])) ** 0.25), (cirq.X(q0) ** 0, ()), (cirq.CZ(q0, q1), cirq.CZ(q0, q1)), (cirq.measure(q0, q1, key='key'), cirq.measure(q0, q1, key='key')), ) )(cirq.LineQubit(0), cirq.LineQubit(1)), ) def test_converts_various_ops(op, expected_ops): before = cirq.Circuit(op) expected = cirq.Circuit(expected_ops, strategy=cirq.InsertStrategy.EARLIEST) after = converted_gate_set(before) assert after == expected cirq.testing.assert_allclose_up_to_global_phase(
invert_mask=(True, False, True)), cirq.MeasurementGate(num_qubits=3, key='z', invert_mask=(True, False), qid_shape=(1, 2, 3)), ], 'Moment': [ cirq.Moment(operations=[cirq.X(Q0), cirq.Y(Q1), cirq.Z(Q2)]), ], 'NamedQubit': cirq.NamedQubit('hi mom'), 'PauliString': [ cirq.PauliString({ Q0: cirq.X, Q1: cirq.Y, Q2: cirq.Z }), cirq.X(Q0) * cirq.Y(Q1) * 123 ], 'PhasedXPowGate': cirq.PhasedXPowGate(phase_exponent=0.123, exponent=0.456, global_shift=0.789), 'X': cirq.X, 'Y': cirq.Y, 'Z': cirq.Z, 'S':
assert_linear_combinations_are_equal(a, expected_a) assert_linear_combinations_are_equal(b, expected_b) @pytest.mark.parametrize('op', ( cirq.X(q0), cirq.Y(q1), cirq.XX(q0, q1), cirq.CZ(q0, q1), cirq.FREDKIN(q0, q1, q2), cirq.ControlledOperation((q0, q1), cirq.H(q2)), cirq.ParallelGateOperation(cirq.X, (q0, q1, q2)), cirq.PauliString({ q0: cirq.X, q1: cirq.Y, q2: cirq.Z }), )) def test_empty_linear_combination_of_operations_accepts_all_operations(op): combination = cirq.LinearCombinationOfOperations({}) combination[op] = -0.5j assert len(combination) == 1 @pytest.mark.parametrize('terms', ( { cirq.X(q0): -2, cirq.H(q0): 2 }, {
def test_add_number_paulisum(): q = cirq.LineQubit.range(2) pstr1 = cirq.X(q[0]) * cirq.X(q[1]) psum = cirq.PauliSum.from_pauli_strings([pstr1]) + 1.3 assert psum == cirq.PauliSum.from_pauli_strings( [pstr1, cirq.PauliString({}, 1.3)])
def test_filters_identities(): q1, q2 = cirq.LineQubit.range(2) assert cirq.PauliString({q1: cirq.I, q2: cirq.X}) == \ cirq.PauliString({q2: cirq.X})
def test_commutes_with(): q0, q1, q2 = _make_qubits(3) assert cirq.PauliString([cirq.X.on(q0) ]).commutes_with(cirq.PauliString([cirq.X.on(q0) ])) assert not cirq.PauliString([cirq.X.on(q0)]).commutes_with( cirq.PauliString([cirq.Y.on(q0)])) assert cirq.PauliString([cirq.X.on(q0) ]).commutes_with(cirq.PauliString([cirq.X.on(q1) ])) assert cirq.PauliString([cirq.X.on(q0) ]).commutes_with(cirq.PauliString([cirq.Y.on(q1) ])) assert cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q0: cirq.X, q1: cirq.Y })) assert not cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q0: cirq.X, q1: cirq.Z })) assert cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q0: cirq.Y, q1: cirq.X })) assert cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q0: cirq.Y, q1: cirq.Z })) assert cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q0: cirq.X, q1: cirq.Y, q2: cirq.Z })) assert not cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q0: cirq.X, q1: cirq.Z, q2: cirq.Z })) assert cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q0: cirq.Y, q1: cirq.X, q2: cirq.Z })) assert cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q0: cirq.Y, q1: cirq.Z, q2: cirq.X })) assert cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q2: cirq.X, q1: cirq.Y })) assert not cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q2: cirq.X, q1: cirq.Z })) assert not cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q2: cirq.Y, q1: cirq.X })) assert not cirq.PauliString({ q0: cirq.X, q1: cirq.Y }).commutes_with(cirq.PauliString({ q2: cirq.Y, q1: cirq.Z }))
def test_constructor_flexibility(): a, b = cirq.LineQubit.range(2) with pytest.raises(TypeError, match='Not a `cirq.PAULI_STRING_LIKE`'): _ = cirq.PauliString(cirq.CZ(a, b)) with pytest.raises(TypeError, match='Not a `cirq.PAULI_STRING_LIKE`'): _ = cirq.PauliString('test') with pytest.raises(TypeError, match='S is not a Pauli'): _ = cirq.PauliString(qubit_pauli_map={a: cirq.S}) assert cirq.PauliString( cirq.X(a)) == cirq.PauliString(qubit_pauli_map={a: cirq.X}) assert cirq.PauliString( [cirq.X(a)]) == cirq.PauliString(qubit_pauli_map={a: cirq.X}) assert cirq.PauliString( [[[cirq.X(a)]]]) == cirq.PauliString(qubit_pauli_map={a: cirq.X}) assert cirq.PauliString([[[cirq.I(a)]]]) == cirq.PauliString() assert cirq.PauliString(1, 2, 3, cirq.X(a), cirq.Y(a)) == cirq.PauliString( qubit_pauli_map={a: cirq.Z}, coefficient=6j) assert cirq.PauliString(cirq.X(a), cirq.X(a)) == cirq.PauliString() assert cirq.PauliString(cirq.X(a), cirq.X(b)) == cirq.PauliString(qubit_pauli_map={ a: cirq.X, b: cirq.X }) assert cirq.PauliString(0) == cirq.PauliString(coefficient=0) assert cirq.PauliString(1, 2, 3, {a: cirq.X}, cirq.Y(a)) == cirq.PauliString( qubit_pauli_map={a: cirq.Z}, coefficient=6j)
def test_bool(): a = cirq.LineQubit(0) assert not bool(cirq.PauliString({})) assert bool(cirq.PauliString({a: cirq.X}))
def test_extrapolate_effect(): op1 = cirq.PauliStringPhasor(cirq.PauliString({}), exponent_neg=0.5) op2 = cirq.PauliStringPhasor(cirq.PauliString({}), exponent_neg=1.5) op3 = cirq.PauliStringPhasor(cirq.PauliString({}), exponent_neg=0.125) assert op1**3 == op2 assert op1**0.25 == op3
def test_rejects_non_paulis(): q = cirq.NamedQubit('q') with pytest.raises(TypeError): _ = cirq.PauliString({q: cirq.S})
def test_merge_with(): q0, = _make_qubits(1) op1 = cirq.PauliStringPhasor(cirq.PauliString({}), exponent_neg=0.25) op2 = cirq.PauliStringPhasor(cirq.PauliString({}), exponent_neg=0.75) op12 = cirq.PauliStringPhasor(cirq.PauliString({}), exponent_neg=1.0) assert op1.merged_with(op2).equal_up_to_global_phase(op12) op1 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, +1), exponent_neg=0.25) op2 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, +1), exponent_neg=0.75) op12 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, +1), exponent_neg=1.0) assert op1.merged_with(op2).equal_up_to_global_phase(op12) op1 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, +1), exponent_neg=0.25) op2 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, -1), exponent_neg=0.75) op12 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, +1), exponent_neg=-0.5) assert op1.merged_with(op2).equal_up_to_global_phase(op12) op1 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, -1), exponent_neg=0.25) op2 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, +1), exponent_neg=0.75) op12 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, -1), exponent_neg=-0.5) assert op1.merged_with(op2).equal_up_to_global_phase(op12) op1 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, -1), exponent_neg=0.25) op2 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, -1), exponent_neg=0.75) op12 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, -1), exponent_neg=1.0) assert op1.merged_with(op2).equal_up_to_global_phase(op12) op1 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.X}, +1), exponent_neg=0.25) op2 = cirq.PauliStringPhasor(cirq.PauliString({q0: cirq.Y}, -1), exponent_neg=0.75) with pytest.raises(ValueError): op1.merged_with(op2)
def test_len(qubit_pauli_map): pauli_string = cirq.PauliString(qubit_pauli_map) assert len(qubit_pauli_map) == len(pauli_string)
def test_is_parametrized(): op = cirq.PauliStringPhasor(cirq.PauliString({})) assert not cirq.is_parameterized(op) assert not cirq.is_parameterized(op**0.1) assert cirq.is_parameterized(op**sympy.Symbol('a'))
def test_str(): q0, q1, q2 = _make_qubits(3) pauli_string = cirq.PauliString({q2: cirq.Pauli.X, q1: cirq.Pauli.Y, q0: cirq.Pauli.Z}) assert str(pauli_string) == '{+, q0:Z, q1:Y, q2:X}' assert str(pauli_string.negate()) == '{-, q0:Z, q1:Y, q2:X}'
def cc(qubits, g): c = 0 for edge in g.edges(): c += cirq.PauliString(1 / 2 * cirq.Z(qubits[edge[0]]) * cirq.Z(qubits[edge[1]])) return c
def test_commutes_with(): q0, q1, q2 = _make_qubits(3) assert cirq.PauliString.from_single(q0, cirq.Pauli.X).commutes_with( cirq.PauliString.from_single(q0, cirq.Pauli.X)) assert not cirq.PauliString.from_single(q0, cirq.Pauli.X).commutes_with( cirq.PauliString.from_single(q0, cirq.Pauli.Y)) assert cirq.PauliString.from_single(q0, cirq.Pauli.X).commutes_with( cirq.PauliString.from_single(q1, cirq.Pauli.X)) assert cirq.PauliString.from_single(q0, cirq.Pauli.X).commutes_with( cirq.PauliString.from_single(q1, cirq.Pauli.Y)) assert cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y}).commutes_with( cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y})) assert not cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y} ).commutes_with( cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Z})) assert cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y}).commutes_with( cirq.PauliString({q0: cirq.Pauli.Y, q1: cirq.Pauli.X})) assert cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y}).commutes_with( cirq.PauliString({q0: cirq.Pauli.Y, q1: cirq.Pauli.Z})) assert cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y}).commutes_with( cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y, q2: cirq.Pauli.Z})) assert not cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y} ).commutes_with( cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Z, q2: cirq.Pauli.Z})) assert cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y}).commutes_with( cirq.PauliString({q0: cirq.Pauli.Y, q1: cirq.Pauli.X, q2: cirq.Pauli.Z})) assert cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y}).commutes_with( cirq.PauliString({q0: cirq.Pauli.Y, q1: cirq.Pauli.Z, q2: cirq.Pauli.X})) assert cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y}).commutes_with( cirq.PauliString({q2: cirq.Pauli.X, q1: cirq.Pauli.Y})) assert not cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y} ).commutes_with( cirq.PauliString({q2: cirq.Pauli.X, q1: cirq.Pauli.Z})) assert not cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y} ).commutes_with( cirq.PauliString({q2: cirq.Pauli.Y, q1: cirq.Pauli.X})) assert not cirq.PauliString({q0: cirq.Pauli.X, q1: cirq.Pauli.Y} ).commutes_with( cirq.PauliString({q2: cirq.Pauli.Y, q1: cirq.Pauli.Z}))
def test_equal_up_to_coefficient(): q0, = _make_qubits(1) assert cirq.PauliString({}, +1).equal_up_to_coefficient( cirq.PauliString({}, +1)) assert cirq.PauliString({}, -1).equal_up_to_coefficient( cirq.PauliString({}, -1)) assert cirq.PauliString({}, +1).equal_up_to_coefficient( cirq.PauliString({}, -1)) assert cirq.PauliString({}, +1).equal_up_to_coefficient( cirq.PauliString({}, 2j)) assert cirq.PauliString({ q0: cirq.X }, +1).equal_up_to_coefficient(cirq.PauliString({q0: cirq.X}, +1)) assert cirq.PauliString({ q0: cirq.X }, -1).equal_up_to_coefficient(cirq.PauliString({q0: cirq.X}, -1)) assert cirq.PauliString({ q0: cirq.X }, +1).equal_up_to_coefficient(cirq.PauliString({q0: cirq.X}, -1)) assert not cirq.PauliString({ q0: cirq.X }, +1).equal_up_to_coefficient(cirq.PauliString({q0: cirq.Y}, +1)) assert not cirq.PauliString({ q0: cirq.X }, +1).equal_up_to_coefficient(cirq.PauliString({q0: cirq.Y}, 1j)) assert not cirq.PauliString({ q0: cirq.X }, -1).equal_up_to_coefficient(cirq.PauliString({q0: cirq.Y}, -1)) assert not cirq.PauliString({ q0: cirq.X }, +1).equal_up_to_coefficient(cirq.PauliString({q0: cirq.Y}, -1)) assert not cirq.PauliString({ q0: cirq.X }, +1).equal_up_to_coefficient(cirq.PauliString({}, +1)) assert not cirq.PauliString({ q0: cirq.X }, -1).equal_up_to_coefficient(cirq.PauliString({}, -1)) assert not cirq.PauliString({ q0: cirq.X }, +1).equal_up_to_coefficient(cirq.PauliString({}, -1))
def test_pass_unsupported_operations_over(): q0, = _make_qubits(1) pauli_string = cirq.PauliString({q0: cirq.Pauli.X}) with pytest.raises(TypeError): pauli_string.pass_operations_over([cirq.X(q0)])
def test_pass_operations_over_cz(): q0, q1 = _make_qubits(2) op0 = cirq.CZ(q0, q1) ps_before = cirq.PauliString({q0: cirq.Z, q1: cirq.Y}) ps_after = cirq.PauliString({q1: cirq.Y}) _assert_pass_over([op0], ps_before, ps_after)
def test_contains(qubit_pauli_map): other = cirq.NamedQubit('other') pauli_string = cirq.PauliString(qubit_pauli_map) for key in qubit_pauli_map: assert key in pauli_string assert other not in pauli_string
def test_consistency(qubit_pauli_map): pauli_string = cirq.PauliString(qubit_pauli_map) cirq.testing.assert_implements_consistent_protocols(pauli_string)
def test_items(qubit_pauli_map): pauli_string = cirq.PauliString(qubit_pauli_map) assert len(qubit_pauli_map.items()) == len(pauli_string.items()) assert set(qubit_pauli_map.items()) == set(pauli_string.items())
def test_expectation_from_density_matrix_invalid_input(): q0, q1, q2, q3 = _make_qubits(4) ps = cirq.PauliString({q0: cirq.X, q1: cirq.Y}) wf = cirq.testing.random_superposition(4) rho = np.kron(wf.conjugate().T, wf).reshape(4, 4) q_map = {q0: 0, q1: 1} im_ps = (1j + 1) * ps with pytest.raises(NotImplementedError, match='non-Hermitian'): im_ps.expectation_from_density_matrix(rho, q_map) with pytest.raises(TypeError, match='dtype'): ps.expectation_from_density_matrix(0.5 * np.eye(2, dtype=np.int), q_map) with pytest.raises(TypeError, match='mapping'): ps.expectation_from_density_matrix(rho, "bad type") with pytest.raises(TypeError, match='mapping'): ps.expectation_from_density_matrix(rho, {"bad key": 1}) with pytest.raises(TypeError, match='mapping'): ps.expectation_from_density_matrix(rho, {q0: "bad value"}) with pytest.raises(ValueError, match='complete'): ps.expectation_from_density_matrix(rho, {q0: 0}) with pytest.raises(ValueError, match='complete'): ps.expectation_from_density_matrix(rho, {q0: 0, q2: 2}) with pytest.raises(ValueError, match='indices'): ps.expectation_from_density_matrix(rho, {q0: -1, q1: 1}) with pytest.raises(ValueError, match='indices'): ps.expectation_from_density_matrix(rho, {q0: 0, q1: 3}) with pytest.raises(ValueError, match='indices'): ps.expectation_from_density_matrix(rho, {q0: 0, q1: 0}) # Excess keys are ignored. _ = ps.expectation_from_density_matrix(rho, {q0: 0, q1: 1, q2: 0}) with pytest.raises(ValueError, match='hermitian'): ps.expectation_from_density_matrix(1j * np.eye(4), q_map) with pytest.raises(ValueError, match='trace'): ps.expectation_from_density_matrix(np.eye(4, dtype=np.complex64), q_map) with pytest.raises(ValueError, match='semidefinite'): ps.expectation_from_density_matrix( np.array( [[1.1, 0, 0, 0], [0, -.1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], dtype=np.complex64), q_map) # Incorrectly shaped density matrix input. with pytest.raises(ValueError, match='shape'): ps.expectation_from_density_matrix(np.ones((4, 5), dtype=np.complex64), q_map) q_map_2 = {q0: 0, q1: 1, q2: 2, q3: 3} with pytest.raises(ValueError, match='shape'): ps.expectation_from_density_matrix(rho.reshape((4, 4, 1)), q_map_2) with pytest.raises(ValueError, match='shape'): ps.expectation_from_density_matrix(rho.reshape((-1)), q_map_2) # Correctly shaped wavefunctions. with pytest.raises(ValueError, match='shape'): ps.expectation_from_density_matrix( np.array([1, 0], dtype=np.complex64), q_map) with pytest.raises(ValueError, match='shape'): ps.expectation_from_density_matrix(wf, q_map) # The ambiguous cases: Wavefunctions satisfying trace normalization. # This also throws an unrelated warning, which is a bug. See #2041. rho_or_wf = 0.25 * np.ones((4, 4), dtype=np.complex64) _ = ps.expectation_from_density_matrix(rho_or_wf, q_map)