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_channel(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_channel(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)
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 translate_cirq_to_qtrajectory( self, qubit_order: cirq.QubitOrderOrList = cirq.QubitOrder.DEFAULT ) -> qsim.NoisyCircuit: """ Translates this noisy Cirq circuit to the qsim representation. :qubit_order: Ordering of qubits :return: a tuple of (C++ qsim NoisyCircuit object, moment boundary gate indices) """ qsim_ncircuit = qsim.NoisyCircuit() ordered_qubits = cirq.QubitOrder.as_qubit_order(qubit_order).order_for( self.all_qubits()) # qsim numbers qubits in reverse order from cirq ordered_qubits = list(reversed(ordered_qubits)) qsim_ncircuit.num_qubits = len(ordered_qubits) def to_matrix(op: cirq.GateOperation): mat = cirq.unitary(op.gate, None) if mat is None: return NotImplemented return cirq.MatrixGate(mat).on(*op.qubits) qubit_to_index_dict = {q: i for i, q in enumerate(ordered_qubits)} time_offset = 0 gate_count = 0 moment_indices = [] for moment in self: moment_length = 0 ops_by_gate = [] ops_by_mix = [] ops_by_channel = [] # Capture ops of each type in the appropriate list. for qsim_op in moment: if cirq.has_unitary(qsim_op) or cirq.is_measurement(qsim_op): oplist = cirq.decompose(qsim_op, fallback_decomposer=to_matrix, keep=_has_cirq_gate_kind) ops_by_gate.append(oplist) moment_length = max(moment_length, len(oplist)) pass elif cirq.has_mixture(qsim_op): ops_by_mix.append(qsim_op) moment_length = max(moment_length, 1) pass elif cirq.has_kraus(qsim_op): ops_by_channel.append(qsim_op) moment_length = max(moment_length, 1) pass else: raise ValueError(f"Encountered unparseable op: {qsim_op}") # Gates must be added in time order. for gi in range(moment_length): # Handle gate output. for gate_ops in ops_by_gate: if gi >= len(gate_ops): continue qsim_op = gate_ops[gi] time = time_offset + gi add_op_to_circuit(qsim_op, time, qubit_to_index_dict, qsim_ncircuit) gate_count += 1 # Handle mixture output. for mixture in ops_by_mix: mixdata = [] for prob, mat in cirq.mixture(mixture): square_mat = np.reshape(mat, (int(np.sqrt(mat.size)), -1)) unitary = cirq.is_unitary(square_mat) # Package matrix into a qsim-friendly format. mat = np.reshape(mat, (-1, )).astype(np.complex64, copy=False) mixdata.append((prob, mat.view(np.float32), unitary)) qubits = [qubit_to_index_dict[q] for q in mixture.qubits] qsim.add_channel(time_offset, qubits, mixdata, qsim_ncircuit) gate_count += 1 # Handle channel output. for channel in ops_by_channel: chdata = [] for i, mat in enumerate(cirq.kraus(channel)): square_mat = np.reshape(mat, (int(np.sqrt(mat.size)), -1)) unitary = cirq.is_unitary(square_mat) singular_vals = np.linalg.svd(square_mat)[1] lower_bound_prob = min(singular_vals)**2 # Package matrix into a qsim-friendly format. mat = np.reshape(mat, (-1, )).astype(np.complex64, copy=False) chdata.append( (lower_bound_prob, mat.view(np.float32), unitary)) qubits = [qubit_to_index_dict[q] for q in channel.qubits] qsim.add_channel(time_offset, qubits, chdata, qsim_ncircuit) gate_count += 1 time_offset += moment_length moment_indices.append(gate_count) return qsim_ncircuit, moment_indices
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.kraus(h), cirq.kraus(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_kraus(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 _simulate_mixture(self, op, state, indices): probs, unitaries = zip(*cirq.mixture(op)) index = np.random.choice(range(len(unitaries)), p=probs) qid_shape = cirq.qid_shape(op) unitary = unitaries[index] self._apply_unitary(op, unitary, qid_shape, state, indices)
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_objects_with_mixture(val, mixture): assert cirq.mixture(val) == mixture assert cirq.mixture(val, ((0.3, 'a'), (0.7, 'b'))) == mixture