def test_sympy_qudits(): q0 = cirq.LineQid(0, 3) q1 = cirq.LineQid(1, 5) q_result = cirq.LineQubit(2) class PlusGate(cirq.Gate): def __init__(self, dimension, increment=1): self.dimension = dimension self.increment = increment % dimension def _qid_shape_(self): return (self.dimension, ) def _unitary_(self): inc = (self.increment - 1) % self.dimension + 1 u = np.empty((self.dimension, self.dimension)) u[inc:] = np.eye(self.dimension)[:-inc] u[:inc] = np.eye(self.dimension)[-inc:] return u for i in range(15): digits = cirq.big_endian_int_to_digits(i, digit_count=2, base=(3, 5)) circuit = cirq.Circuit( PlusGate(3, digits[0]).on(q0), PlusGate(5, digits[1]).on(q1), cirq.measure(q0, q1, key='m'), cirq.X(q_result).with_classical_controls( sympy_parser.parse_expr('m % 4 <= 1')), cirq.measure(q_result, key='m_result'), ) result = cirq.Simulator().run(circuit) assert result.measurements['m_result'][0][0] == (i % 4 <= 1)
def test_eq(): eq = cirq.testing.EqualsTester() eq.make_equality_group(lambda: cirq.LineQubit(1), lambda: cirq.LineQid(1, dimension=2)) eq.add_equality_group(cirq.LineQubit(2)) eq.add_equality_group(cirq.LineQubit(0)) eq.add_equality_group(cirq.LineQid(1, dimension=3))
def test_cmp_failure(): with pytest.raises(TypeError, match='not supported between instances'): _ = 0 < cirq.LineQubit(1) with pytest.raises(TypeError, match='not supported between instances'): _ = cirq.LineQubit(1) < 0 with pytest.raises(TypeError, match='not supported between instances'): _ = 0 < cirq.LineQid(1, 3) with pytest.raises(TypeError, match='not supported between instances'): _ = cirq.LineQid(1, 3) < 0
def test_is_adjacent(): assert cirq.LineQubit(1).is_adjacent(cirq.LineQubit(2)) assert cirq.LineQubit(1).is_adjacent(cirq.LineQubit(0)) assert cirq.LineQubit(2).is_adjacent(cirq.LineQubit(3)) assert not cirq.LineQubit(1).is_adjacent(cirq.LineQubit(3)) assert not cirq.LineQubit(2).is_adjacent(cirq.LineQubit(0)) assert cirq.LineQubit(2).is_adjacent(cirq.LineQid(3, 3)) assert not cirq.LineQubit(2).is_adjacent(cirq.LineQid(0, 3))
def test_addition_subtraction_type_error(): with pytest.raises(TypeError, match='dave'): _ = cirq.LineQubit(1) + 'dave' with pytest.raises(TypeError, match='dave'): _ = cirq.LineQubit(1) - 'dave' with pytest.raises(TypeError, match='dave'): _ = cirq.LineQid(1, 3) + 'dave' with pytest.raises(TypeError, match='dave'): _ = cirq.LineQid(1, 3) - 'dave'
def test_cmp(): order = cirq.testing.OrderTester() order.add_ascending_equivalence_group(cirq.LineQubit(0), cirq.LineQid(0, 2)) order.add_ascending( cirq.LineQid(0, dimension=3), cirq.LineQid(1, dimension=1), cirq.LineQubit(1), cirq.LineQid(1, dimension=3), cirq.LineQid(2, dimension=1), )
def test_xpow_dim_4(): x = cirq.XPowGate(dimension=4) # fmt: off expected = [ [0, 0, 0, 1], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], ] # fmt: on assert np.allclose(cirq.unitary(x), expected) sim = cirq.Simulator() circuit = cirq.Circuit([x(cirq.LineQid(0, 4))**0.5] * 8) svs = [ step.state_vector(copy=True) for step in sim.simulate_moment_steps(circuit) ] # fmt: off expected = [ [0.65, 0.65, 0.27, 0.27], [0.0, 1.0, 0.0, 0.0], [0.27, 0.65, 0.65, 0.27], [0.0, 0.0, 1.0, 0.0], [0.27, 0.27, 0.65, 0.65], [0.0, 0.0, 0.0, 1.0], [0.65, 0.27, 0.27, 0.65], [1.0, 0.0, 0.0, 0.0], ] # fmt: on assert np.allclose(np.abs(svs), expected, atol=1e-2)
def test_init(): q = cirq.LineQubit(1) assert q.x == 1 q = cirq.LineQid(1, dimension=3) assert q.x == 1 assert q.dimension == 3
def test_rename_bad_dimensions(): q0 = cirq.LineQubit(0) q1 = cirq.LineQid(1, 3) args = DummyArgs() with pytest.raises(ValueError, match='Cannot rename to different dimensions'): args.rename(q0, q1)
def test_state_mixin(): class TestClass(cirq.StateVectorMixin): def state_vector(self) -> np.ndarray: return np.array([0, 0, 1, 0]) qubits = cirq.LineQubit.range(2) test = TestClass(qubit_map={qubits[i]: i for i in range(2)}) assert test.dirac_notation() == '|10⟩' np.testing.assert_almost_equal(test.bloch_vector_of(qubits[0]), np.array([0, 0, -1])) np.testing.assert_almost_equal(test.density_matrix_of(qubits[0:1]), np.array([[0, 0], [0, 1]])) assert cirq.qid_shape(TestClass({qubits[i]: 1 - i for i in range(2)})) == (2, 2) assert cirq.qid_shape( TestClass({cirq.LineQid(i, i + 1): 2 - i for i in range(3)})) == (3, 2, 1) assert cirq.qid_shape(TestClass(), 'no shape') == 'no shape' with pytest.raises(ValueError, match='Qubit index out of bounds'): _ = TestClass({qubits[0]: 1}) with pytest.raises(ValueError, match='Duplicate qubit index'): _ = TestClass({qubits[0]: 0, qubits[1]: 0}) with pytest.raises(ValueError, match='Duplicate qubit index'): _ = TestClass({qubits[0]: 1, qubits[1]: 1}) with pytest.raises(ValueError, match='Duplicate qubit index'): _ = TestClass({qubits[0]: -1, qubits[1]: 1})
def test_qudit_measure_quil(): q0 = cirq.LineQid(0, 3) qubit_id_map = {q0: '0'} assert cirq.quil( cirq.measure(q0, key='a'), formatter=cirq.QuilFormatter(qubit_id_map=qubit_id_map, measurement_id_map={})) == None
def test_json_dict(): assert cirq.LineQubit(5)._json_dict_() == { 'x': 5, } assert cirq.LineQid(5, 3)._json_dict_() == { 'x': 5, 'dimension': 3, }
def test_immutable(): with pytest.raises(AttributeError, match="can't set attribute"): q = cirq.LineQubit(5) q.x = 6 with pytest.raises(AttributeError, match="can't set attribute"): q = cirq.LineQid(5, dimension=4) q.x = 6
def test_addition_subtraction(): assert cirq.LineQubit(1) + 2 == cirq.LineQubit(3) assert cirq.LineQubit(3) - 1 == cirq.LineQubit(2) assert 1 + cirq.LineQubit(4) == cirq.LineQubit(5) assert 5 - cirq.LineQubit(3) == cirq.LineQubit(2) assert cirq.LineQid(1, 3) + 2 == cirq.LineQid(3, 3) assert cirq.LineQid(3, 3) - 1 == cirq.LineQid(2, 3) assert 1 + cirq.LineQid(4, 3) == cirq.LineQid(5, 3) assert 5 - cirq.LineQid(3, 3) == cirq.LineQid(2, 3)
def test_act_on_qutrit(): a, b = [cirq.LineQid(3, dimension=3), cirq.LineQid(1, dimension=3)] m = cirq.measure( a, b, key='out', invert_mask=(True, ), confusion_map={(1, ): np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]])}, ) args = cirq.StateVectorSimulationState( available_buffer=np.empty(shape=(3, 3, 3, 3, 3)), qubits=cirq.LineQid.range(5, dimension=3), prng=np.random.RandomState(), initial_state=cirq.one_hot(index=(0, 2, 0, 2, 0), shape=(3, 3, 3, 3, 3), dtype=np.complex64), dtype=np.complex64, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [2, 0]} args = cirq.StateVectorSimulationState( available_buffer=np.empty(shape=(3, 3, 3, 3, 3)), qubits=cirq.LineQid.range(5, dimension=3), prng=np.random.RandomState(), initial_state=cirq.one_hot(index=(0, 1, 0, 2, 0), shape=(3, 3, 3, 3, 3), dtype=np.complex64), dtype=np.complex64, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [2, 2]} args = cirq.StateVectorSimulationState( available_buffer=np.empty(shape=(3, 3, 3, 3, 3)), qubits=cirq.LineQid.range(5, dimension=3), prng=np.random.RandomState(), initial_state=cirq.one_hot(index=(0, 2, 0, 1, 0), shape=(3, 3, 3, 3, 3), dtype=np.complex64), dtype=np.complex64, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [0, 0]}
def test_repr(): def test_repr(qid: _MeasurementQid): cirq.testing.assert_equivalent_repr(qid, global_vals={'_MeasurementQid': _MeasurementQid}) test_repr(_MeasurementQid('a', cirq.LineQubit(0))) test_repr(_MeasurementQid('a', cirq.NamedQubit('x'))) test_repr(_MeasurementQid('a', cirq.NamedQid('x', 4))) test_repr(_MeasurementQid('a', cirq.GridQubit(2, 3))) test_repr(_MeasurementQid('0:1:a', cirq.LineQid(9, 4)))
def test_qudit_measure_quil(): q0 = cirq.LineQid(0, 3) qubit_id_map = {q0: '0'} with cirq.testing.assert_deprecated(deadline='v1.0', count=3): assert (cirq.quil( cirq.measure(q0, key='a'), formatter=cirq.QuilFormatter(qubit_id_map=qubit_id_map, measurement_id_map={}), ) is None)
def test_qudit_measure_qasm(): assert ( cirq.qasm( cirq.measure(cirq.LineQid(0, 3), key='a'), args=cirq.QasmArgs(), default='not implemented', ) == 'not implemented' )
def test_wrong_dims(): x3 = cirq.XPowGate(dimension=3) with pytest.raises(ValueError, match='Wrong shape'): _ = x3.on(cirq.LineQubit(0)) with pytest.raises(ValueError, match='Wrong shape'): _ = x3.on(cirq.LineQid(0, dimension=4)) z3 = cirq.ZPowGate(dimension=3) with pytest.raises(ValueError, match='Wrong shape'): _ = z3.on(cirq.LineQubit(0)) with pytest.raises(ValueError, match='Wrong shape'): _ = z3.on(cirq.LineQid(0, dimension=4)) with pytest.raises(ValueError, match='Wrong shape'): _ = cirq.X.on(cirq.LineQid(0, dimension=3)) with pytest.raises(ValueError, match='Wrong shape'): _ = cirq.Z.on(cirq.LineQid(0, dimension=3))
def test_gate_with_custom_names(): q0, q1, q2, q3 = cirq.LineQubit.range(4) gate = cirq.BooleanHamiltonianGate(['a', 'b'], ['a'], 0.1) assert cirq.decompose(gate.on(q0, q1)) == [cirq.Rz(rads=-0.05).on(q0)] assert cirq.decompose_once_with_qubits(gate, (q0, q1)) == [cirq.Rz(rads=-0.05).on(q0)] assert cirq.decompose(gate.on(q2, q3)) == [cirq.Rz(rads=-0.05).on(q2)] assert cirq.decompose_once_with_qubits(gate, (q2, q3)) == [cirq.Rz(rads=-0.05).on(q2)] with pytest.raises(ValueError, match='Wrong number of qubits'): gate.on(q2) with pytest.raises(ValueError, match='Wrong shape of qids'): gate.on(q0, cirq.LineQid(1, 3))
def test_zpow_dim_3(): L = np.exp(2 * np.pi * 1j / 3) L2 = L**2 z = cirq.ZPowGate(dimension=3) # fmt: off expected = [ [1, 0, 0], [0, L, 0], [0, 0, L2], ] # fmt: on assert np.allclose(cirq.unitary(z), expected) sim = cirq.Simulator() circuit = cirq.Circuit([z(cirq.LineQid(0, 3))**0.5] * 6) svs = [ step.state_vector(copy=True) for step in sim.simulate_moment_steps(circuit, initial_state=0) ] expected = [[1, 0, 0]] * 6 assert np.allclose((svs), expected) svs = [ step.state_vector(copy=True) for step in sim.simulate_moment_steps(circuit, initial_state=1) ] # fmt: off expected = [ [0, L**0.5, 0], [0, L**1.0, 0], [0, L**1.5, 0], [0, L**2.0, 0], [0, L**2.5, 0], [0, 1, 0], ] # fmt: on assert np.allclose((svs), expected) svs = [ step.state_vector(copy=True) for step in sim.simulate_moment_steps(circuit, initial_state=2) ] # fmt: off expected = [ [0, 0, L], [0, 0, L2], [0, 0, 1], [0, 0, L], [0, 0, L2], [0, 0, 1], ] # fmt: on assert np.allclose((svs), expected)
def test_op_validate(): op = cirq.X(cirq.LineQid(0, 2)) op2 = cirq.CNOT(*cirq.LineQid.range(2, dimension=2)) op.validate_args([cirq.LineQid(1, 2)]) # Valid op2.validate_args(cirq.LineQid.range(1, 3, dimension=2)) # Valid with pytest.raises(ValueError, match='Wrong shape'): op.validate_args([cirq.LineQid(1, 9)]) with pytest.raises(ValueError, match='Wrong number'): op.validate_args([cirq.LineQid(1, 2), cirq.LineQid(2, 2)]) with pytest.raises(ValueError, match='Duplicate'): op2.validate_args([cirq.LineQid(1, 2), cirq.LineQid(1, 2)])
def test_act_on_qutrit(): a, b = [cirq.LineQid(3, dimension=3), cirq.LineQid(1, dimension=3)] m = cirq.measure(a, b, key='out', invert_mask=(True, )) args = cirq.ActOnStateVectorArgs( target_tensor=cirq.one_hot(index=(0, 2, 0, 2, 0), shape=(3, 3, 3, 3, 3), dtype=np.complex64), available_buffer=np.empty(shape=(3, 3, 3, 3, 3)), qubits=cirq.LineQid.range(5, dimension=3), prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [2, 2]} args = cirq.ActOnStateVectorArgs( target_tensor=cirq.one_hot(index=(0, 1, 0, 2, 0), shape=(3, 3, 3, 3, 3), dtype=np.complex64), available_buffer=np.empty(shape=(3, 3, 3, 3, 3)), qubits=cirq.LineQid.range(5, dimension=3), prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [2, 1]} args = cirq.ActOnStateVectorArgs( target_tensor=cirq.one_hot(index=(0, 2, 0, 1, 0), shape=(3, 3, 3, 3, 3), dtype=np.complex64), available_buffer=np.empty(shape=(3, 3, 3, 3, 3)), qubits=cirq.LineQid.range(5, dimension=3), prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [0, 2]}
def test_simulate_qudit_mixtures(dtype, ): q0 = cirq.LineQid(0, 3) simulator = cirq.Simulator(dtype=dtype) mixture = _TestMixture([PlusGate(3, 0), PlusGate(3, 1), PlusGate(3, 2)]) circuit = cirq.Circuit(mixture(q0), cirq.measure(q0)) counts = {0: 0, 1: 0, 2: 0} for _ in range(300): result = simulator.simulate(circuit, qubit_order=[q0]) meas = result.measurements['0 (d=3)'][0] counts[meas] += 1 np.testing.assert_almost_equal( result.final_state, np.array([meas == 0, meas == 1, meas == 2])) assert counts[0] < 160 and counts[0] > 40 assert counts[1] < 160 and counts[1] > 40 assert counts[2] < 160 and counts[2] > 40
def test_controlled_operation_gate(): gate = cirq.X.controlled(control_values=[0, 1], control_qid_shape=[2, 3]) op = gate.on(cirq.LineQubit(0), cirq.LineQid(1, 3), cirq.LineQubit(2)) assert op.gate == gate class Gateless(cirq.Operation): @property def qubits(self): return () # coverage: ignore def with_qubits(self, *new_qubits): return self # coverage: ignore op = Gateless().controlled_by(cirq.LineQubit(0)) assert op.gate is None
def test_invalid_qubit_mapping(): q = cirq.LineQubit(0) q3 = cirq.LineQid(1, dimension=3) # Invalid qid remapping dict in constructor with pytest.raises(ValueError, match='Qid dimension conflict'): _ = cirq.CircuitOperation(cirq.FrozenCircuit(), qubit_map={q: q3}) # Invalid qid remapping dict in with_qubit_mapping call c_op = cirq.CircuitOperation(cirq.FrozenCircuit(cirq.X(q))) with pytest.raises(ValueError, match='Qid dimension conflict'): _ = c_op.with_qubit_mapping({q: q3}) # Invalid qid remapping function in with_qubit_mapping call with pytest.raises(ValueError, match='Qid dimension conflict'): _ = c_op.with_qubit_mapping(lambda q: q3)
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_with_custom_names(): q0, q1, q2, q3 = cirq.LineQubit.range(4) with cirq.testing.assert_deprecated( 'Use cirq.BooleanHamiltonianGate', deadline='v0.15', count=3 ): original_op = cirq.BooleanHamiltonian( {'a': q0, 'b': q1}, ['a'], 0.1, ) assert cirq.decompose(original_op) == [cirq.Rz(rads=-0.05).on(q0)] renamed_op = original_op.with_qubits(q2, q3) assert cirq.decompose(renamed_op) == [cirq.Rz(rads=-0.05).on(q2)] with pytest.raises(ValueError, match='Length of replacement qubits must be the same'): original_op.with_qubits(q2) with pytest.raises(ValueError, match='All qubits must be 2-dimensional'): original_op.with_qubits(q0, cirq.LineQid(1, 3))
def test_addition_subtraction_type_error(): with pytest.raises(TypeError, match='dave'): _ = cirq.LineQubit(1) + 'dave' with pytest.raises(TypeError, match='dave'): _ = cirq.LineQubit(1) - 'dave' with pytest.raises(TypeError, match='dave'): _ = cirq.LineQid(1, 3) + 'dave' with pytest.raises(TypeError, match='dave'): _ = cirq.LineQid(1, 3) - 'dave' with pytest.raises(TypeError, match="Can only add LineQids with identical dimension."): _ = cirq.LineQid(5, dimension=3) + cirq.LineQid(3, dimension=4) with pytest.raises(TypeError, match="Can only subtract LineQids with identical dimension."): _ = cirq.LineQid(5, dimension=3) - cirq.LineQid(3, dimension=4)
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, )