def test_has_mixture(): assert cirq.has_mixture(ReturnsValidTuple()) assert not cirq.has_mixture(ReturnsNotImplemented()) assert cirq.has_mixture(ReturnsMixtureButNoHasMixture()) assert cirq.has_mixture(ReturnsUnitary()) assert not cirq.has_mixture(ReturnsNotImplementedUnitary()) class NoAtom(cirq.Operation): @property def qubits(self): return cirq.LineQubit.range(2) def with_qubits(self): raise NotImplementedError() class No1: def _decompose_(self): return [NoAtom()] class Yes1: def _decompose_(self): return [cirq.X(cirq.LineQubit(0))] with cirq.testing.assert_logs('cirq.has_mixture', ' has_mixture_channel '): assert not cirq.has_mixture_channel(No1()) with cirq.testing.assert_logs('cirq.has_mixture', ' has_mixture_channel '): assert cirq.has_mixture_channel(Yes1())
def test_controlled_mixture(): a, b = cirq.LineQubit.range(2) class NoDetails(cirq.Operation): @property def qubits(self): return (a, ) def with_qubits(self, *new_qubits): raise NotImplementedError() c_no = cirq.ControlledOperation( controls=[b], sub_operation=NoDetails(), ) assert not cirq.has_mixture(c_no) assert cirq.mixture(c_no, None) is None c_yes = cirq.ControlledOperation( controls=[b], sub_operation=cirq.phase_flip(0.25).on(a), ) assert cirq.has_mixture(c_yes) assert cirq.approx_eq( cirq.mixture(c_yes), [ (0.75, np.eye(4)), (0.25, cirq.unitary(cirq.CZ)), ], )
def test_mixture(): a = cirq.NamedQubit('a') op = cirq.bit_flip(0.5).on(a) assert_mixtures_equal(cirq.mixture(op), cirq.mixture(op.gate)) assert cirq.has_mixture(op) assert cirq.mixture(cirq.X(a), None) is None assert not cirq.has_mixture(cirq.X(a))
def test_parameterized(): op = cirq.X.with_probability(sympy.Symbol('x')) assert cirq.is_parameterized(op) assert not cirq.has_channel(op) assert not cirq.has_mixture(op) op2 = cirq.resolve_parameters(op, {'x': 0.5}) assert op2 == cirq.X.with_probability(0.5) assert not cirq.is_parameterized(op2) assert cirq.has_channel(op2) assert cirq.has_mixture(op2)
def test_parameterized(resolve_fn): op = cirq.X.with_probability(sympy.Symbol('x')) assert cirq.is_parameterized(op) assert not cirq.has_kraus(op) assert not cirq.has_mixture(op) op2 = resolve_fn(op, {'x': 0.5}) assert op2 == cirq.X.with_probability(0.5) assert not cirq.is_parameterized(op2) assert cirq.has_kraus(op2) assert cirq.has_mixture(op2)
def test_mixture(): a = cirq.NamedQubit('a') op = cirq.bit_flip(0.5).on(a) assert_mixtures_equal(cirq.mixture(op), cirq.mixture(op.gate)) assert cirq.has_mixture(op) assert cirq.has_mixture(cirq.X(a)) m = cirq.mixture(cirq.X(a)) assert len(m) == 1 assert m[0][0] == 1 np.testing.assert_allclose(m[0][1], cirq.unitary(cirq.X))
def test_state_prep_channel_kraus_small(): gate = cirq.StatePreparationChannel(np.array([0.0, 1.0]))(cirq.LineQubit(0)) np.testing.assert_almost_equal(cirq.kraus(gate), (np.array( [[0.0, 0.0], [1.0, 0.0]]), np.array([[0.0, 0.0], [0.0, 1.0]]))) assert cirq.has_kraus(gate) assert not cirq.has_mixture(gate) gate = cirq.StatePreparationChannel(np.array([1.0, 0.0]))(cirq.LineQubit(0)) np.testing.assert_almost_equal(cirq.kraus(gate), (np.array( [[1.0, 0.0], [0.0, 0.0]]), np.array([[0.0, 1.0], [0.0, 0.0]]))) assert cirq.has_kraus(gate) assert not cirq.has_mixture(gate)
def test_phase_damping_channel(): d = cirq.phase_damp(0.3) np.testing.assert_almost_equal( cirq.channel(d), (np.array([[1.0, 0.], [0., np.sqrt(1 - 0.3)]]), np.array([[0., 0.], [0., np.sqrt(0.3)]]))) assert cirq.has_channel(d) assert not cirq.has_mixture(d)
def test_measurement_channel(): np.testing.assert_allclose( cirq.kraus(cirq.MeasurementGate(1, 'a')), (np.array([[1, 0], [0, 0]]), np.array([[0, 0], [0, 1]])), ) cirq.testing.assert_consistent_channel(cirq.MeasurementGate(1, 'a')) assert not cirq.has_mixture(cirq.MeasurementGate(1, 'a')) # yapf: disable np.testing.assert_allclose( cirq.kraus(cirq.MeasurementGate(2, 'a')), (np.array([[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]), np.array([[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]), np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0]]), np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1]]))) np.testing.assert_allclose( cirq.kraus(cirq.MeasurementGate(2, 'a', qid_shape=(2, 3))), (np.diag([1, 0, 0, 0, 0, 0]), np.diag([0, 1, 0, 0, 0, 0]), np.diag([0, 0, 1, 0, 0, 0]), np.diag([0, 0, 0, 1, 0, 0]), np.diag([0, 0, 0, 0, 1, 0]), np.diag([0, 0, 0, 0, 0, 1])))
def test_controlled_mixture(): a, b = cirq.LineQubit.range(2) c_yes = cirq.ControlledOperation(controls=[b], sub_operation=cirq.phase_flip(0.25).on(a)) assert cirq.has_mixture(c_yes) assert cirq.approx_eq(cirq.mixture(c_yes), [(0.75, np.eye(4)), (0.25, cirq.unitary(cirq.CZ))])
def test_reset_channel(): r = cirq.reset(cirq.LineQubit(0)) np.testing.assert_almost_equal( cirq.channel(r), (np.array([[1., 0.], [0., 0]]), np.array([[0., 1.], [0., 0.]]))) assert cirq.has_channel(r) assert not cirq.has_mixture(r) assert cirq.qid_shape(r) == (2, ) r = cirq.reset(cirq.LineQid(0, dimension=3)) np.testing.assert_almost_equal( cirq.channel(r), (np.array([[1, 0, 0], [0, 0, 0], [0, 0, 0]]), np.array([[0, 1, 0], [0, 0, 0], [0, 0, 0]]), np.array([[0, 0, 1], [0, 0, 0], [0, 0, 0]]))) # yapf: disable assert cirq.has_channel(r) assert not cirq.has_mixture(r) assert cirq.qid_shape(r) == (3, )
def test_channel(): class NoDetailsGate(cirq.Gate): def num_qubits(self) -> int: return 1 assert not cirq.has_kraus(NoDetailsGate().with_probability(0.5)) assert cirq.kraus(NoDetailsGate().with_probability(0.5), None) is None assert cirq.kraus(cirq.X.with_probability(sympy.Symbol('x')), None) is None cirq.testing.assert_consistent_channel(cirq.X.with_probability(0.25)) cirq.testing.assert_consistent_channel( cirq.bit_flip(0.75).with_probability(0.25)) cirq.testing.assert_consistent_channel( cirq.amplitude_damp(0.75).with_probability(0.25)) cirq.testing.assert_consistent_mixture(cirq.X.with_probability(0.25)) cirq.testing.assert_consistent_mixture( cirq.bit_flip(0.75).with_probability(0.25)) assert not cirq.has_mixture( cirq.amplitude_damp(0.75).with_probability(0.25)) m = cirq.kraus(cirq.X.with_probability(0.25)) assert len(m) == 2 np.testing.assert_allclose(m[0], cirq.unitary(cirq.X) * np.sqrt(0.25), atol=1e-8) np.testing.assert_allclose(m[1], cirq.unitary(cirq.I) * np.sqrt(0.75), atol=1e-8) m = cirq.kraus(cirq.bit_flip(0.75).with_probability(0.25)) assert len(m) == 3 np.testing.assert_allclose(m[0], cirq.unitary(cirq.I) * np.sqrt(0.25) * np.sqrt(0.25), atol=1e-8) np.testing.assert_allclose(m[1], cirq.unitary(cirq.X) * np.sqrt(0.25) * np.sqrt(0.75), atol=1e-8) np.testing.assert_allclose(m[2], cirq.unitary(cirq.I) * np.sqrt(0.75), atol=1e-8) m = cirq.kraus(cirq.amplitude_damp(0.75).with_probability(0.25)) assert len(m) == 3 np.testing.assert_allclose(m[0], np.array([[1, 0], [0, np.sqrt(1 - 0.75)]]) * np.sqrt(0.25), atol=1e-8) np.testing.assert_allclose(m[1], np.array([[0, np.sqrt(0.75)], [0, 0]]) * np.sqrt(0.25), atol=1e-8) np.testing.assert_allclose(m[2], cirq.unitary(cirq.I) * np.sqrt(0.75), atol=1e-8)
def test_generalized_amplitude_damping_channel(): d = cirq.generalized_amplitude_damp(0.1, 0.3) np.testing.assert_almost_equal( cirq.channel(d), (np.sqrt(0.1) * np.array([[1., 0.], [0., np.sqrt(1. - 0.3)]]), np.sqrt(0.1) * np.array([[0., np.sqrt(0.3)], [0., 0.]]), np.sqrt(0.9) * np.array([[np.sqrt(1. - 0.3), 0.], [0., 1.]]), np.sqrt(0.9) * np.array([[0., 0.], [np.sqrt(0.3), 0.]]))) assert cirq.has_channel(d) assert not cirq.has_mixture(d)
def test_phase_damping_channel(): d = cirq.phase_damp(0.3) np.testing.assert_almost_equal( cirq.kraus(d), ( np.array([[1.0, 0.0], [0.0, np.sqrt(1 - 0.3)]]), np.array([[0.0, 0.0], [0.0, np.sqrt(0.3)]]), ), ) cirq.testing.assert_consistent_channel(d) assert not cirq.has_mixture(d)
def test_amplitude_damping_channel(): d = cirq.amplitude_damp(0.3) np.testing.assert_almost_equal( cirq.channel(d), ( np.array([[1.0, 0.0], [0.0, np.sqrt(1.0 - 0.3)]]), np.array([[0.0, np.sqrt(0.3)], [0.0, 0.0]]), ), ) assert cirq.has_channel(d) assert not cirq.has_mixture(d)
def assert_consistent_mixture(gate: Any, rtol: float = 1e-5, atol: float = 1e-8): """Asserts that a given gate is a mixture and the mixture probabilities sum to one.""" assert cirq.has_mixture( gate), f"Give gate {gate!r} does not return for cirq.has_mixture." mixture = cirq.mixture(gate) total = np.sum(k for k, v in mixture) assert total - 1 <= atol + rtol * np.abs(total), ( f"The mixture for gate {gate!r} did not return coefficients that sum to 1. Summed to " f"{total}.")
def test_depolarizing_mixture_two_qubits(): d = cirq.depolarize(0.15, n_qubits=2) assert_mixtures_equal( cirq.mixture(d), ((0.85, np.eye(4)), (0.01, np.kron(np.eye(2), X)), (0.01, np.kron(np.eye(2), Y)), (0.01, np.kron(np.eye(2), Z)), (0.01, np.kron(X, np.eye(2))), (0.01, np.kron(X, X)), (0.01, np.kron(X, Y)), (0.01, np.kron(X, Z)), (0.01, np.kron(Y, np.eye(2))), (0.01, np.kron(Y, X)), (0.01, np.kron(Y, Y)), (0.01, np.kron(Y, Z)), (0.01, np.kron(Z, np.eye(2))), (0.01, np.kron(Z, X)), (0.01, np.kron(Z, Y)), (0.01, np.kron(Z, Z)))) assert cirq.has_mixture(d)
def test_generalized_amplitude_damping_channel(): d = cirq.generalized_amplitude_damp(0.1, 0.3) np.testing.assert_almost_equal( cirq.kraus(d), ( np.sqrt(0.1) * np.array([[1.0, 0.0], [0.0, np.sqrt(1.0 - 0.3)]]), np.sqrt(0.1) * np.array([[0.0, np.sqrt(0.3)], [0.0, 0.0]]), np.sqrt(0.9) * np.array([[np.sqrt(1.0 - 0.3), 0.0], [0.0, 1.0]]), np.sqrt(0.9) * np.array([[0.0, 0.0], [np.sqrt(0.3), 0.0]]), ), ) assert cirq.has_kraus(d) assert not cirq.has_mixture(d)
def test_reset_channel(): r = cirq.reset(cirq.LineQubit(0)) np.testing.assert_almost_equal( cirq.kraus(r), (np.array([[1.0, 0.0], [0.0, 0]]), np.array([[0.0, 1.0], [0.0, 0.0]]))) cirq.testing.assert_consistent_channel(r) assert not cirq.has_mixture(r) assert cirq.num_qubits(r) == 1 assert cirq.qid_shape(r) == (2, ) r = cirq.reset(cirq.LineQid(0, dimension=3)) np.testing.assert_almost_equal( cirq.kraus(r), ( np.array([[1, 0, 0], [0, 0, 0], [0, 0, 0]]), np.array([[0, 1, 0], [0, 0, 0], [0, 0, 0]]), np.array([[0, 0, 1], [0, 0, 0], [0, 0, 0]]), ), ) # yapf: disable cirq.testing.assert_consistent_channel(r) assert not cirq.has_mixture(r) assert cirq.qid_shape(r) == (3, )
def test_controlled_mixture(): class NoDetails(cirq.Gate): def num_qubits(self) -> int: return 1 c_no = cirq.ControlledGate( num_controls=1, sub_gate=NoDetails(), ) assert not cirq.has_mixture(c_no) assert cirq.mixture(c_no, None) is None c_yes = cirq.ControlledGate( sub_gate=cirq.phase_flip(0.25), num_controls=1, ) assert cirq.has_mixture(c_yes) assert cirq.approx_eq(cirq.mixture(c_yes), [ (0.75, np.eye(4)), (0.25, cirq.unitary(cirq.CZ)), ])
def test_mixture(): class NoDetailsGate(cirq.Gate): def num_qubits(self) -> int: return 1 assert not cirq.has_mixture(NoDetailsGate().with_probability(0.5)) assert cirq.mixture(NoDetailsGate().with_probability(0.5), None) is None assert cirq.mixture(cirq.X.with_probability(sympy.Symbol('x')), None) is None m = cirq.mixture(cirq.X.with_probability(0.25)) assert len(m) == 2 assert m[0][0] == 0.25 np.testing.assert_allclose(cirq.unitary(cirq.X), m[0][1]) assert m[1][0] == 0.75 np.testing.assert_allclose(cirq.unitary(cirq.I), m[1][1]) m = cirq.mixture(cirq.bit_flip(1 / 4).with_probability(1 / 8)) assert len(m) == 3 assert {p for p, _ in m} == {7 / 8, 1 / 32, 3 / 32}
def simulate_op(op, temp_state): indices = [qubit_map[q] for q in op.qubits] if cirq.op_gate_isinstance(op, cirq.ResetChannel): self._simulate_reset(op, cirq.ResetChannel) elif cirq.is_measurement(op): if perform_measurements: self._simulate_measurement( op, temp_state, indices, measurements) elif cirq.has_mixture(op): self._simulate_mixture(op, temp_state, indices) else: if cirq.num_qubits(op) <= 3: self._simulate_unitary(op, temp_state, indices) else: decomp_ops = cirq.decompose_once(op, default=None) if decomp_ops is None: self._simulate_unitary(op, temp_state, indices) else: for sub_op in cirq.flatten_op_tree(decomp_ops): simulate_op(sub_op, temp_state)
def simulate_op(op, temp_state): indices = [qubit_map[q] for q in op.qubits] if cirq.op_gate_isinstance(op, cirq.ResetChannel): self._simulate_reset(op, cirq.ResetChannel) elif cirq.is_measurement(op): if perform_measurements: self._simulate_measurement( op, temp_state, indices, measurements) elif cirq.has_mixture(op): self._simulate_mixture(op, temp_state, indices) else: decomp_ops = cirq.decompose_once(op, default=None) if decomp_ops is None: self._simulate_unitary(op, temp_state, indices) else: try: temp2_state = temp_state.copy() for sub_op in cirq.flatten_op_tree(decomp_ops): simulate_op(sub_op, temp2_state) temp_state[...] = temp2_state except ValueError: # Non-classical unitary in the decomposition self._simulate_unitary(op, temp_state, indices)
def test_state_prep_channel_kraus(state): qubits = cirq.LineQubit.range(2) gate = cirq.StatePreparationChannel(state)(qubits[0], qubits[1]) cirq.testing.assert_consistent_channel(gate) assert not cirq.has_mixture(gate) state = state / np.linalg.norm(state) np.testing.assert_almost_equal( cirq.kraus(gate), ( np.array([state, np.zeros(4), np.zeros(4), np.zeros(4)]).T, np.array([np.zeros(4), state, np.zeros(4), np.zeros(4)]).T, np.array([np.zeros(4), np.zeros(4), state, np.zeros(4)]).T, np.array([np.zeros(4), np.zeros(4), np.zeros(4), state]).T, ), )
def test_tagged_operation_forwards_protocols(): """The results of all protocols applied to an operation with a tag should be equivalent to the result without tags. """ q1 = cirq.GridQubit(1, 1) q2 = cirq.GridQubit(1, 2) h = cirq.H(q1) tag = 'tag1' tagged_h = cirq.H(q1).with_tags(tag) np.testing.assert_equal(cirq.unitary(tagged_h), cirq.unitary(h)) assert cirq.has_unitary(tagged_h) assert cirq.decompose(tagged_h) == cirq.decompose(h) assert cirq.pauli_expansion(tagged_h) == cirq.pauli_expansion(h) assert cirq.equal_up_to_global_phase(h, tagged_h) assert np.isclose(cirq.channel(h), cirq.channel(tagged_h)).all() assert cirq.measurement_key(cirq.measure(q1, key='blah').with_tags(tag)) == 'blah' parameterized_op = cirq.XPowGate(exponent=sympy.Symbol('t'))(q1).with_tags(tag) assert cirq.is_parameterized(parameterized_op) resolver = cirq.study.ParamResolver({'t': 0.25}) assert cirq.resolve_parameters(parameterized_op, resolver) == cirq.XPowGate(exponent=0.25)( q1 ).with_tags(tag) assert cirq.resolve_parameters_once(parameterized_op, resolver) == cirq.XPowGate(exponent=0.25)( q1 ).with_tags(tag) y = cirq.Y(q1) tagged_y = cirq.Y(q1).with_tags(tag) assert tagged_y ** 0.5 == cirq.YPowGate(exponent=0.5)(q1) assert tagged_y * 2 == (y * 2) assert 3 * tagged_y == (3 * y) assert cirq.phase_by(y, 0.125, 0) == cirq.phase_by(tagged_y, 0.125, 0) controlled_y = tagged_y.controlled_by(q2) assert controlled_y.qubits == ( q2, q1, ) assert isinstance(controlled_y, cirq.Operation) assert not isinstance(controlled_y, cirq.TaggedOperation) clifford_x = cirq.SingleQubitCliffordGate.X(q1) tagged_x = cirq.SingleQubitCliffordGate.X(q1).with_tags(tag) assert cirq.commutes(clifford_x, clifford_x) assert cirq.commutes(tagged_x, clifford_x) assert cirq.commutes(clifford_x, tagged_x) assert cirq.commutes(tagged_x, tagged_x) assert cirq.trace_distance_bound(y ** 0.001) == cirq.trace_distance_bound( (y ** 0.001).with_tags(tag) ) flip = cirq.bit_flip(0.5)(q1) tagged_flip = cirq.bit_flip(0.5)(q1).with_tags(tag) assert cirq.has_mixture(tagged_flip) assert cirq.has_channel(tagged_flip) flip_mixture = cirq.mixture(flip) tagged_mixture = cirq.mixture(tagged_flip) assert len(tagged_mixture) == 2 assert len(tagged_mixture[0]) == 2 assert len(tagged_mixture[1]) == 2 assert tagged_mixture[0][0] == flip_mixture[0][0] assert np.isclose(tagged_mixture[0][1], flip_mixture[0][1]).all() assert tagged_mixture[1][0] == flip_mixture[1][0] assert np.isclose(tagged_mixture[1][1], flip_mixture[1][1]).all() qubit_map = {q1: 'q1'} qasm_args = cirq.QasmArgs(qubit_id_map=qubit_map) assert cirq.qasm(h, args=qasm_args) == cirq.qasm(tagged_h, args=qasm_args) cirq.testing.assert_has_consistent_apply_unitary(tagged_h)
def test_asymmetric_depolarizing_mixture(): d = cirq.asymmetric_depolarize(0.1, 0.2, 0.3) assert_mixtures_equal(cirq.mixture(d), ((0.4, np.eye(2)), (0.1, X), (0.2, Y), (0.3, Z))) assert cirq.has_mixture(d)
def test_multi_asymmetric_depolarizing_mixture(): d = cirq.asymmetric_depolarize(error_probabilities={'II': 0.8, 'XX': 0.2}) assert_mixtures_equal(cirq.mixture(d), ((0.8, np.eye(4)), (0.2, np.kron(X, X)))) assert cirq.has_mixture(d) np.testing.assert_equal(d._num_qubits_(), 2)
def test_bit_flip_mixture(): d = cirq.bit_flip(0.3) assert_mixtures_equal(cirq.mixture(d), ((0.7, np.eye(2)), (0.3, X))) assert cirq.has_mixture(d)
def test_phase_flip_mixture(): d = cirq.phase_flip(0.3) assert_mixtures_equal(cirq.mixture(d), ((0.7, np.eye(2)), (0.3, Z))) assert cirq.has_mixture(d)
def test_depolarizing_mixture(): d = cirq.depolarize(0.3) assert_mixtures_equal(cirq.mixture(d), ((0.7, np.eye(2)), (0.1, X), (0.1, Y), (0.1, Z))) assert cirq.has_mixture(d)