def _stim_append_depolarizing_channel(c: stim.Circuit, g: cirq.DepolarizingChannel, t: List[int]): if g.num_qubits() == 1: c.append_operation("DEPOLARIZE1", t, g.p) elif g.num_qubits() == 2: c.append_operation("DEPOLARIZE2", t, g.p) else: raise TypeError(f"Don't know how to turn {g!r} into Stim operations.")
def global_depolarizing_kraus(noise_level: float, num_qubits: int) -> List[np.ndarray]: """Returns the kraus operators of a global depolarizing channel at a given noise level. """ noisy_op = DepolarizingChannel(noise_level, num_qubits) return list(channel(noisy_op))
def test_find_optimal_representation_depolarizing_two_qubit_gates(circ_type): """Test optimal representation agrees with a known analytic result.""" for ideal_gate, noise_level in product([CNOT, CZ], [0.1, 0.5]): q = LineQubit.range(2) ideal_op = Circuit(ideal_gate(*q)) implementable_circuits = [Circuit(ideal_op)] # Append two-qubit-gate with Paulis on one qubit for gate in [X, Y, Z]: implementable_circuits.append(Circuit([ideal_op, gate(q[0])])) implementable_circuits.append(Circuit([ideal_op, gate(q[1])])) # Append two-qubit gate with Paulis on both qubits for gate_a, gate_b in product([X, Y, Z], repeat=2): implementable_circuits.append( Circuit([ideal_op, gate_a(q[0]), gate_b(q[1])]) ) noisy_circuits = [ circ + Circuit(DepolarizingChannel(noise_level).on_each(*q)) for circ in implementable_circuits ] super_operators = [ choi_to_super(_circuit_to_choi(circ)) for circ in noisy_circuits ] # Define circuits with native types implementable_native = [ convert_from_mitiq(c, circ_type) for c in implementable_circuits ] ideal_op_native = convert_from_mitiq(ideal_op, circ_type) noisy_operations = [ NoisyOperation(ideal, real) for ideal, real in zip(implementable_native, super_operators) ] # Find optimal representation noisy_basis = NoisyBasis(*noisy_operations) rep = find_optimal_representation( ideal_op_native, noisy_basis, tol=1.0e-8 ) # Expected analytical result expected_rep = represent_operation_with_local_depolarizing_noise( ideal_op_native, noise_level, ) assert np.allclose(np.sort(rep.coeffs), np.sort(expected_rep.coeffs)) assert rep == expected_rep
def test_depolarizing_representation_with_choi(gate: Gate, noise: float): """Tests the representation by comparing exact Choi matrices.""" qreg = LineQubit.range(gate.num_qubits()) ideal_choi = _operation_to_choi(gate.on(*qreg)) op_rep = represent_operation_with_global_depolarizing_noise( Circuit(gate.on(*qreg)), noise, ) choi_components = [] for noisy_op, coeff in op_rep.basis_expansion.items(): implementable_circ = noisy_op.circuit() # Apply noise after each sequence. # NOTE: noise is not applied after each operation. depolarizing_op = DepolarizingChannel(noise, len(qreg))(*qreg) implementable_circ.append(depolarizing_op) sequence_choi = _circuit_to_choi(implementable_circ) choi_components.append(coeff * sequence_choi) combination_choi = np.sum(choi_components, axis=0) assert np.allclose(ideal_choi, combination_choi, atol=10 ** -6)
def test_minimize_one_norm_with_depolarized_choi(): for noise_level in [0.01, 0.02, 0.03]: q = LineQubit(0) ideal_matrix = _operation_to_choi(H(q)) basis_matrices = [ _operation_to_choi( [H(q), gate(q), DepolarizingChannel(noise_level, 1)(q)]) for gate in [I, X, Y, Z, H] ] optimal_coeffs = minimize_one_norm(ideal_matrix, basis_matrices) represented_mat = sum( [eta * mat for eta, mat in zip(optimal_coeffs, basis_matrices)]) assert np.allclose(ideal_matrix, represented_mat) # Optimal analytic result by Takagi (arXiv:2006.12509) eps = 4.0 / 3.0 * noise_level expected = (1.0 + 0.5 * eps) / (1.0 - eps) assert np.isclose(np.linalg.norm(optimal_coeffs, 1), expected)
def test_find_optimal_representation_single_qubit_depolarizing(circ_type): """Test optimal representation agrees with a known analytic result.""" for ideal_gate, noise_level in product([X, Y, H], [0.1, 0.3]): q = LineQubit(0) ideal_op = Circuit(ideal_gate(q)) implementable_circuits = [Circuit(ideal_op)] # Add ideal gate followed by Paulis for gate in [X, Y, Z]: implementable_circuits.append(Circuit([ideal_op, gate(q)])) noisy_circuits = [ circ + Circuit(DepolarizingChannel(noise_level).on_each(q)) for circ in implementable_circuits ] super_operators = [ choi_to_super(_circuit_to_choi(circ)) for circ in noisy_circuits ] # Define circuits with native types implementable_native = [ convert_from_mitiq(c, circ_type) for c in implementable_circuits ] ideal_op_native = convert_from_mitiq(ideal_op, circ_type) noisy_operations = [ NoisyOperation(ideal, real) for ideal, real in zip(implementable_native, super_operators) ] # Find optimal representation noisy_basis = NoisyBasis(*noisy_operations) rep = find_optimal_representation( ideal_op_native, noisy_basis, tol=1.0e-8 ) # Expected analytical result expected_rep = represent_operation_with_local_depolarizing_noise( ideal_op_native, noise_level, ) assert np.allclose(np.sort(rep.coeffs), np.sort(expected_rep.coeffs)) assert rep == expected_rep