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 assert_channel_sums_to_identity(cirq.X.with_probability(0.25)) assert_channel_sums_to_identity(cirq.bit_flip(0.75).with_probability(0.25)) assert_channel_sums_to_identity(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_bit_flip_channel_eq(): et = cirq.testing.EqualsTester() c = cirq.bit_flip(0.0) et.make_equality_group(lambda: c) et.add_equality_group(cirq.bit_flip(0.1)) et.add_equality_group(cirq.bit_flip(0.4)) et.add_equality_group(cirq.bit_flip(0.6)) et.add_equality_group(cirq.bit_flip(0.8))
def __init__(self, abstract_circuit: QCircuit, variables, qubit_map=None, noise=None, device=None, *args, **kwargs): """ Parameters ---------- abstract_circuit: QCircuit: Tequila unitary to compile to cirq variables: dict: values of all variables in the circuit, to compile with. qubit_map: dictionary: a qubit map which maps the abstract qubits in the abstract_circuit to the qubits on the backend there is no need to initialize the corresponding backend types the dictionary should simply be {int:int} (preferred) or {int:name} if None the default will map to qubits 0 ... n_qubits -1 in the backend noise: Noise to apply to the circuit. device: device on which to emulatedly execute all sampling. args kwargs """ self.op_lookup = { 'I': (cirq.ops.IdentityGate, None), 'X': (cirq.ops.common_gates.XPowGate, map_1), 'Y': (cirq.ops.common_gates.YPowGate, map_1), 'Z': (cirq.ops.common_gates.ZPowGate, map_1), 'H': (cirq.ops.common_gates.HPowGate, map_1), 'Rx': (cirq.ops.common_gates.XPowGate, map_2), 'Ry': (cirq.ops.common_gates.YPowGate, map_2), 'Rz': (cirq.ops.common_gates.ZPowGate, map_2), 'SWAP': (cirq.ops.SwapPowGate, None), } self.tq_to_sympy = {} self.counter = 0 if device is not None: self.compiler_arguments['cc_max'] = True super().__init__(abstract_circuit=abstract_circuit, variables=variables, noise=noise, qubit_map=qubit_map, device=device, *args, **kwargs) if len(self.tq_to_sympy.keys()) is None: self.sympy_to_tq = None self.resolver = None else: self.sympy_to_tq = {v: k for k, v in self.tq_to_sympy.items()} self.resolver = cirq.ParamResolver({k: v(variables) for k, v in self.sympy_to_tq.items()}) if self.device is not None: self.circuit = self.build_device_circuit() if self.noise is not None: if self.noise == 'device': raise TequilaException('cannot get device noise for cirq yet, sorry!') self.noise_lookup = { 'bit flip': [lambda x: cirq.bit_flip(x)], 'phase flip': [lambda x: cirq.phase_flip(x)], 'phase damp': [cirq.phase_damp], 'amplitude damp': [cirq.amplitude_damp], 'phase-amplitude damp': [cirq.amplitude_damp, cirq.phase_damp], 'depolarizing': [lambda x: cirq.depolarize(p=(3 / 4) * x)] } self.circuit = self.build_noisy_circuit(self.noise)
def test_run_mixture(dtype): q0 = cirq.LineQubit(0) simulator = cirq.Simulator(dtype=dtype) circuit = cirq.Circuit(cirq.bit_flip(0.5)(q0), cirq.measure(q0)) result = simulator.run(circuit, repetitions=100) assert sum(result.measurements['0'])[0] < 80 assert sum(result.measurements['0'])[0] > 20
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_bit_flip_channel_text_diagram(): bf = cirq.bit_flip(0.1234567) assert cirq.circuit_diagram_info( bf, args=round_to_6_prec) == cirq.CircuitDiagramInfo( wire_symbols=('BF(0.123457)', )) assert cirq.circuit_diagram_info( bf, args=round_to_2_prec) == cirq.CircuitDiagramInfo( wire_symbols=('BF(0.12)', ))
def test_not_unitary(gates): if bit_flip(p=0.1) in gates: with pytest.raises(TypeError, match="cirq.unitary failed"): general_rule(slack_length=17, gates=gates) else: with pytest.raises(ValueError, match="is not equivalent to the identity"): general_rule(slack_length=17, gates=gates)
def test_channel(): a = cirq.NamedQubit('a') op = cirq.bit_flip(0.5).on(a) np.testing.assert_allclose(cirq.channel(op), cirq.channel(op.gate)) assert cirq.has_channel(op) assert cirq.channel(cirq.SingleQubitGate()(a), None) is None assert not cirq.has_channel(cirq.SingleQubitGate()(a))
def optimization_at(self, circuit, index, op): if isinstance(op.gate, cirq.MeasurementGate): noise_gate = cirq.bit_flip(self.error_rate).on_each(*op.qubits) decomposition = [op.gate(*op.qubits)] + noise_gate return cirq.PointOptimizationSummary(clear_span=1, clear_qubits=op.qubits, new_operations=decomposition) else: return None
def test_run_mixture(dtype): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit(cirq.bit_flip(0.5)(q0), cirq.measure(q0), cirq.measure(q1)) simulator = cirq.DensityMatrixSimulator(dtype=dtype) result = simulator.run(circuit, repetitions=100) np.testing.assert_equal(result.measurements['1'], [[0]] * 100) # Test that we get at least one of each result. Probability of this test # failing is 2 ** (-99). q0_measurements = set(x[0] for x in result.measurements['0'].tolist()) assert q0_measurements == {0, 1}
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_mapped_circuit_keeps_keys_under_parent_path(): q = cirq.LineQubit(0) op1 = cirq.CircuitOperation( cirq.FrozenCircuit( cirq.measure(q, key='A'), cirq.measure_single_paulistring(cirq.X(q), key='B'), cirq.MixedUnitaryChannel.from_mixture(cirq.bit_flip(0.5), key='C').on(q), cirq.KrausChannel.from_channel(cirq.phase_damp(0.5), key='D').on(q), ) ) op2 = op1.with_key_path(('X',)) assert cirq.measurement_key_names(op2.mapped_circuit()) == {'X:A', 'X:B', 'X:C', 'X:D'}
def test_simulate_mixtures(dtype: Type[np.number], split: bool): q0 = cirq.LineQubit(0) simulator = cirq.Simulator(dtype=dtype, split_untangled_states=split) circuit = cirq.Circuit(cirq.bit_flip(0.5)(q0), cirq.measure(q0)) count = 0 for _ in range(100): result = simulator.simulate(circuit, qubit_order=[q0]) if result.measurements['0']: np.testing.assert_almost_equal(result.final_state_vector, np.array([0, 1])) count += 1 else: np.testing.assert_almost_equal(result.final_state_vector, np.array([1, 0])) assert count < 80 and count > 20
def test_kraus(): I = np.eye(2) X = np.array([[0, 1], [1, 0]]) Y = np.array([[0, -1j], [1j, 0]]) Z = np.diag([1, -1]) a, b = cirq.LineQubit.range(2) m = cirq.Moment() assert cirq.has_kraus(m) k = cirq.kraus(m) assert len(k) == 1 assert np.allclose(k[0], np.array([[1.0]])) m = cirq.Moment(cirq.S(a)) assert cirq.has_kraus(m) k = cirq.kraus(m) assert len(k) == 1 assert np.allclose(k[0], np.diag([1, 1j])) m = cirq.Moment(cirq.CNOT(a, b)) assert cirq.has_kraus(m) k = cirq.kraus(m) print(k[0]) assert len(k) == 1 assert np.allclose( k[0], np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])) p = 0.1 m = cirq.Moment(cirq.depolarize(p).on(a)) assert cirq.has_kraus(m) k = cirq.kraus(m) assert len(k) == 4 assert np.allclose(k[0], np.sqrt(1 - p) * I) assert np.allclose(k[1], np.sqrt(p / 3) * X) assert np.allclose(k[2], np.sqrt(p / 3) * Y) assert np.allclose(k[3], np.sqrt(p / 3) * Z) p = 0.2 q = 0.3 m = cirq.Moment(cirq.bit_flip(p).on(a), cirq.phase_flip(q).on(b)) assert cirq.has_kraus(m) k = cirq.kraus(m) assert len(k) == 4 assert np.allclose(k[0], np.sqrt((1 - p) * (1 - q)) * np.kron(I, I)) assert np.allclose(k[1], np.sqrt(q * (1 - p)) * np.kron(I, Z)) assert np.allclose(k[2], np.sqrt(p * (1 - q)) * np.kron(X, I)) assert np.allclose(k[3], np.sqrt(p * q) * np.kron(X, Z))
def test_simulate_mixtures(dtype, ): q0 = cirq.LineQubit(0) simulator = cirq.Simulator(dtype=dtype) circuit = cirq.Circuit.from_ops(cirq.bit_flip(0.5)(q0), cirq.measure(q0)) count = 0 for _ in range(100): result = simulator.simulate(circuit, qubit_order=[q0]) if result.measurements['0']: np.testing.assert_almost_equal(result.final_state, np.array([0, 1])) count += 1 else: np.testing.assert_almost_equal(result.final_state, np.array([1, 0])) assert count < 80 and count > 20
def test_bit_flip_channel_eq(): a = cirq.bit_flip(0.0099999) b = cirq.bit_flip(0.01) c = cirq.bit_flip(0.0) assert cirq.approx_eq(a, b, atol=1e-2) et = cirq.testing.EqualsTester() et.make_equality_group(lambda: c) et.add_equality_group(cirq.bit_flip(0.1)) et.add_equality_group(cirq.bit_flip(0.4)) et.add_equality_group(cirq.bit_flip(0.6)) et.add_equality_group(cirq.bit_flip(0.8))
def test_simulate_mixtures(dtype, ): q0 = cirq.LineQubit(0) circuit = cirq.Circuit(cirq.bit_flip(0.5)(q0), cirq.measure(q0)) simulator = cirq.KnowledgeCompilationSimulator(circuit, dtype=dtype) count = 0 for _ in range(100): result = simulator.simulate(circuit, qubit_order=[q0]) if result.measurements['0']: # np.testing.assert_almost_equal(result.final_state_vector, # np.array([0, 1])) count += 1 else: pass # np.testing.assert_almost_equal(result.final_state_vector, # np.array([1, 0])) assert count < 80 and count > 20
def __init__(self, abstract_circuit: QCircuit, variables, use_mapping=True, noise=None, *args, **kwargs): self.op_lookup = { 'I': (cirq.ops.IdentityGate, None), 'X': (cirq.ops.common_gates.XPowGate, map_1), 'Y': (cirq.ops.common_gates.YPowGate, map_1), 'Z': (cirq.ops.common_gates.ZPowGate, map_1), 'H': (cirq.ops.common_gates.HPowGate, map_1), 'Rx': (cirq.ops.common_gates.XPowGate, map_2), 'Ry': (cirq.ops.common_gates.YPowGate, map_2), 'Rz': (cirq.ops.common_gates.ZPowGate, map_2), 'SWAP': (cirq.ops.SwapPowGate, None), } self.tq_to_sympy = {} self.counter = 0 super().__init__(abstract_circuit=abstract_circuit, variables=variables, noise=noise, use_mapping=use_mapping, *args, **kwargs) if len(self.tq_to_sympy.keys()) is None: self.sympy_to_tq = None self.resolver = None else: self.sympy_to_tq = {v: k for k, v in self.tq_to_sympy.items()} self.resolver = cirq.ParamResolver( {k: v(variables) for k, v in self.sympy_to_tq.items()}) if self.noise is not None: self.noise_lookup = { 'bit flip': [lambda x: cirq.bit_flip(x)], 'phase flip': [lambda x: cirq.phase_flip(x)], 'phase damp': [cirq.phase_damp], 'amplitude damp': [cirq.amplitude_damp], 'phase-amplitude damp': [cirq.amplitude_damp, cirq.phase_damp], 'depolarizing': [lambda x: cirq.depolarize(p=(3 / 4) * x)] } self.circuit = self.build_noisy_circuit(self.noise)
def test_is_measurement(): q = cirq.NamedQubit('q') assert cirq.is_measurement(cirq.measure(q)) assert cirq.is_measurement(cirq.MeasurementGate(num_qubits=1, key='b')) assert not cirq.is_measurement(cirq.X(q)) assert not cirq.is_measurement(cirq.X) assert not cirq.is_measurement(cirq.bit_flip(1)) class NotImplementedOperation(cirq.Operation): def with_qubits(self, *new_qubits) -> 'NotImplementedOperation': raise NotImplementedError() @property def qubits(self): return cirq.LineQubit.range(2) assert not cirq.is_measurement(NotImplementedOperation())
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 test_mixture_simulation(): q0, q1 = cirq.LineQubit.range(2) pflip = cirq.phase_flip(p=0.4) bflip = cirq.bit_flip(p=0.6) cirq_circuit = cirq.Circuit( cirq.X(q0)**0.5, cirq.X(q1)**0.5, pflip.on(q0), bflip.on(q1), ) possible_circuits = [ cirq.Circuit(cirq.X(q0)**0.5, cirq.X(q1)**0.5, pf, bf) # Extract the operators from the mixtures to construct trajectories. for pf in [NoiseStep(m).on(q0) for m in cirq.channel(pflip)] for bf in [NoiseStep(m).on(q1) for m in cirq.channel(bflip)] ] possible_states = [ cirq.Simulator().simulate(pc).state_vector() for pc in possible_circuits ] # Since some "gates" were non-unitary, we must normalize. possible_states = [ps / np.linalg.norm(ps) for ps in possible_states] # Minimize flaky tests with a fixed seed. qsimSim = qsimcirq.QSimSimulator(seed=1) result_hist = [0] * len(possible_states) run_count = 100 for _ in range(run_count): result = qsimSim.simulate(cirq_circuit, qubit_order=[q0, q1]) for i, ps in enumerate(possible_states): if cirq.allclose_up_to_global_phase(result.state_vector(), ps): result_hist[i] += 1 break # Each observed result should match one of the possible_results. assert sum(result_hist) == run_count # Over 100 runs, it's reasonable to expect all four outcomes. assert all(result_count > 0 for result_count in result_hist)
def _get_noise_proto_pairs(): q0 = cirq.GridQubit(0, 0) pairs = [ # Depolarization. (cirq.Circuit(cirq.depolarize(p=0.3)(q0)), _build_op_proto("DP", ['p'], [0.3], ['0_0'])), # Asymmetric depolarization. (cirq.Circuit( cirq.asymmetric_depolarize(p_x=0.1, p_y=0.2, p_z=0.3)(q0)), _build_op_proto("ADP", ['p_x', 'p_y', 'p_z'], [0.1, 0.2, 0.3], ['0_0'])), # Generalized Amplitude damp. (cirq.Circuit(cirq.generalized_amplitude_damp(p=0.1, gamma=0.2)(q0)), _build_op_proto("GAD", ['p', 'gamma'], [0.1, 0.2], ['0_0'])), # Amplitude damp. (cirq.Circuit(cirq.amplitude_damp(gamma=0.1)(q0)), _build_op_proto("AD", ['gamma'], [0.1], ['0_0'])), # Reset. (cirq.Circuit(cirq.reset(q0)), _build_op_proto("RST", [], [], ['0_0'])), # Phase damp. (cirq.Circuit(cirq.phase_damp(gamma=0.1)(q0)), _build_op_proto("PD", ['gamma'], [0.1], ['0_0'])), # Phase flip. (cirq.Circuit(cirq.phase_flip(p=0.1)(q0)), _build_op_proto("PF", ['p'], [0.1], ['0_0'])), # Bit flip. (cirq.Circuit(cirq.bit_flip(p=0.1)(q0)), _build_op_proto("BF", ['p'], [0.1], ['0_0'])) ] return pairs
def test_bit_flip_overload(): d = cirq.bit_flip() d2 = cirq.bit_flip(0.3) assert str(d) == 'X' assert str(d2) == 'bit_flip(p=0.3)'
[X, Y, Z], ], ) def test_repeated_sequences(slack_length, gates): sequence = repeated_rule( slack_length=slack_length, gates=gates, ) num_reps = slack_length // len(gates) gate_set = {X, Y, Z} seq_gates = [op.gate for op in sequence.all_operations()] assert len(sequence) == slack_length assert gates * num_reps == [gate for gate in seq_gates if gate in gate_set] @pytest.mark.parametrize( "gates", [ [bit_flip(p=0.1), bit_flip(p=0.1)], [X, X, X], ], ) def test_not_unitary(gates): if bit_flip(p=0.1) in gates: with pytest.raises(TypeError, match="cirq.unitary failed"): general_rule(slack_length=17, gates=gates) else: with pytest.raises(ValueError, match="is not equivalent to the identity"): general_rule(slack_length=17, gates=gates)
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_bit_flip_channel(): d = cirq.bit_flip(0.3) np.testing.assert_almost_equal( cirq.channel(d), (np.sqrt(1.0 - 0.3) * np.eye(2), np.sqrt(0.3) * X)) assert cirq.has_channel(d)
def test_bit_flip_channel_text_diagram(): assert (cirq.circuit_diagram_info( cirq.bit_flip(0.3)) == cirq.CircuitDiagramInfo( wire_symbols=('BF(0.3)', )))
def test_bit_flip_channel_invalid_probability(): with pytest.raises(ValueError, match='was less than 0'): cirq.bit_flip(-0.1) with pytest.raises(ValueError, match='was greater than 1'): cirq.bit_flip(1.1)
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_bit_flip_channel_str(): assert str(cirq.bit_flip(0.3)) == 'bit_flip(p=0.3)'