def test_gate_type(): qreg = LineQubit.range(3) allowed_op = ops.H.on(qreg[0]) _get_base_gate(allowed_op.gate) with pytest.raises(GateTypeException): forbidden_op = CSWAP(qreg[0], qreg[1], qreg[2]) _get_base_gate(forbidden_op)
def test_three_qubit_local_depolarizing_representation_error(): q0, q1, q2 = LineQubit.range(3) with pytest.raises(ValueError): represent_operation_with_local_depolarizing_noise( Circuit(CCNOT(q0, q1, q2)), 0.05, )
def test_non_identity_scale_1q(): """Tests that when scale factor = 1, the circuit is the same. """ qreg = LineQubit.range(3) circ = Circuit([ops.rx(np.pi * 1.0).on_each(qreg)], [ops.ry(np.pi * 1.0).on(qreg[0])]) np.random.seed(42) stretch = 2 base_noise = 0.001 noises = np.random.normal(loc=0.0, scale=np.sqrt((stretch - 1) * base_noise), size=(4, )) np.random.seed(42) scaled = scale_parameters(circ, scale_factor=stretch, base_variance=base_noise, seed=42) result = [] for moment in scaled: for op in moment.operations: gate = deepcopy(op.gate) param = gate.exponent result.append(param * np.pi - np.pi) assert np.all(np.isclose(result - noises, 0))
def test_simplify_circuit_exponents(): qreg = LineQubit.range(2) circuit = Circuit([H.on(qreg[0]), CNOT.on(*qreg), Z.on(qreg[1])]) # Invert circuit inverse_circuit = cirq.inverse(circuit) inverse_repr = inverse_circuit.__repr__() inverse_qasm = inverse_circuit._to_qasm_output().__str__() # Expected circuit after simplification expected_inv = Circuit([Z.on(qreg[1]), CNOT.on(*qreg), H.on(qreg[0])]) expected_repr = expected_inv.__repr__() expected_qasm = expected_inv._to_qasm_output().__str__() # Check inverse_circuit is logically equivalent to expected_inverse # but they have a different representation assert inverse_circuit == expected_inv assert inverse_repr != expected_repr assert inverse_qasm != expected_qasm # Simplify the circuit _simplify_circuit_exponents(inverse_circuit) # Check inverse_circuit has the expected simplified representation simplified_repr = inverse_circuit.__repr__() simplified_qasm = inverse_circuit._to_qasm_output().__str__() assert inverse_circuit == expected_inv assert simplified_repr == expected_repr assert simplified_qasm == expected_qasm
def test_get_coefficients(gate: Gate): q = LineQubit(0) coeffs = get_coefficients(gate.on(q), DECO_DICT) epsilon = BASE_NOISE * 4.0 / 3.0 c_neg = -(1 / 4) * epsilon / (1 - epsilon) c_pos = 1 - 3 * c_neg assert np.isclose(np.sum(coeffs), 1.0) assert np.allclose(coeffs, [c_pos, c_neg, c_neg, c_neg])
def test_simplify_circuit_exponents_controlled_gate(): circuit = Circuit( ControlledGate(CNOT, num_controls=1).on(*LineQubit.range(3)) ) copy = circuit.copy() _simplify_circuit_exponents(circuit) assert _equal(circuit, copy)
def test_to_braket_raises_on_unsupported_gates(): for num_qubits in range(3, 5): print(num_qubits) qubits = [LineQubit(int(qubit)) for qubit in range(num_qubits)] op = ops.MatrixGate(_rotation_of_pi_over_7(num_qubits)).on(*qubits) circuit = Circuit(op) with pytest.raises(ValueError): to_braket(circuit)
def test_single_qubit_representation_norm(gate: Gate, noise: float): q = LineQubit(0) optimal_norm = single_qubit_depolarizing_overhead(noise) norm = represent_operation_with_global_depolarizing_noise( Circuit(gate(q)), noise, ).norm assert np.isclose(optimal_norm, norm)
def test_two_qubit_representation_norm(gate: Gate, noise: float): qreg = LineQubit.range(2) optimal_norm = two_qubit_depolarizing_overhead(noise) norm = represent_operation_with_global_depolarizing_noise( Circuit(gate(*qreg)), noise, ).norm assert np.isclose(optimal_norm, norm)
def test_identity_scale_1q(): """Tests that when scale factor = 1, the circuit is the same. """ qreg = LineQubit.range(3) circ = Circuit([ops.X.on_each(qreg)], [ops.Y.on(qreg[0])]) scaled = scale_parameters(circ, scale_factor=1, sigma=0.001) assert _equal(circ, scaled)
def test_qubitop_to_paulisum_setting_qubits(self): # Given qubit_operator = QubitOperator("Z0 Z1", -1.5) expected_qubits = (LineQubit(0), LineQubit(5)) expected_paulisum = ( PauliSum() + PauliString(Z.on(expected_qubits[0])) * PauliString(Z.on(expected_qubits[1])) * -1.5 ) # When paulisum = qubitop_to_paulisum(qubit_operator, qubits=expected_qubits) # Then self.assertEqual(paulisum.qubits, expected_qubits) self.assertEqual(paulisum, expected_paulisum)
def test_identity_scale_2q(): """Tests that when scale factor = 1, the circuit is the same. """ qreg = LineQubit.range(2) circ = Circuit([ops.CNOT.on(qreg[0], qreg[1])]) scaled = scale_parameters(circ, scale_factor=1, sigma=0.001) assert _equal(circ, scaled)
def test_sample_sequence_types(gate: Gate): num_qubits = gate.num_qubits() qreg = LineQubit.range(num_qubits) for _ in range(1000): imp_seq, sign, norm = sample_sequence(gate.on(*qreg), DECO_DICT) assert all([isinstance(op, Operation) for op in imp_seq]) assert sign in {1, -1} assert norm > 1
def test_single_qubit_representation_norm(gate: Gate, noise: float): q = LineQubit(0) optimal_norm = (1 + noise) / (1 - noise) norm = _represent_operation_with_amplitude_damping_noise( Circuit(gate(q)), noise, ).norm assert np.isclose(optimal_norm, norm)
def generate_rb_circuits( n_qubits: int, num_cliffords: int, trials: int = 1, return_type: Optional[str] = None, ) -> List[QPROGRAM]: """Returns a list of randomized benchmarking circuits, i.e. circuits that are equivalent to the identity. Args: n_qubits: The number of qubits. Can be either 1 or 2. num_cliffords: The number of Clifford group elements in the random circuits. This is proportional to the depth per circuit. trials: The number of random circuits at each num_cfd. return_type: String which specifies the type of the returned circuits. See the keys of ``mitiq.SUPPORTED_PROGRAM_TYPES`` for options. If ``None``, the returned circuits have type ``cirq.Circuit``. Returns: A list of randomized benchmarking circuits. """ if n_qubits not in (1, 2): raise ValueError( "Only generates RB circuits on one or two " f"qubits not {n_qubits}." ) qubits = LineQubit.range(n_qubits) cliffords = _single_qubit_cliffords() if n_qubits == 1: c1 = cliffords.c1_in_xy cfd_mat_1q = cast( np.ndarray, [_gate_seq_to_mats(gates) for gates in c1] ) circuits = [ _random_single_q_clifford(qubits[0], num_cliffords, c1, cfd_mat_1q) for _ in range(trials) ] else: cfd_matrices = _two_qubit_clifford_matrices( qubits[0], qubits[1], cliffords, ) circuits = [ _random_two_q_clifford( qubits[0], qubits[1], num_cliffords, cfd_matrices, cliffords, ) for _ in range(trials) ] return_type = "cirq" if not return_type else return_type return [convert_from_mitiq(circuit, return_type) for circuit in circuits]
def test_qubitop_to_paulisum_more_terms(self): # Given qubit_operator = (QubitOperator("Z0 Z1 Z2", -1.5) + QubitOperator("X0", 2.5) + QubitOperator("Y1", 3.5)) expected_qubits = (LineQubit(0), LineQubit(5), LineQubit(8)) expected_paulisum = (PauliSum() + (PauliString(Z.on(expected_qubits[0])) * PauliString(Z.on(expected_qubits[1])) * PauliString(Z.on(expected_qubits[2])) * -1.5) + (PauliString(X.on(expected_qubits[0]) * 2.5)) + (PauliString(Y.on(expected_qubits[1]) * 3.5))) # When paulisum = qubitop_to_paulisum(qubit_operator, qubits=expected_qubits) # Then self.assertEqual(paulisum.qubits, expected_qubits) self.assertEqual(paulisum, expected_paulisum)
def test_single_qubit_representation_norm( gate: Gate, epsilon: float, eta: float ): q = LineQubit(0) optimal_norm = single_qubit_biased_noise_overhead(epsilon, eta) norm = represent_operation_with_local_biased_noise( Circuit(gate(q)), epsilon, eta ).norm assert np.isclose(optimal_norm, norm)
def test_get_imp_sequences_no_simplify(gate: Gate): q = LineQubit(0) expected_imp_sequences = [ [gate.on(q)], [gate.on(q), X.on(q)], [gate.on(q), Y.on(q)], [gate.on(q), Z.on(q)], ] assert get_imp_sequences(gate.on(q), DECO_DICT) == expected_imp_sequences
def test_F0Gate_text_diagram(): qubits = LineQubit.range(2) circuit = cirq.Circuit(_F0Gate().on(*qubits)) assert circuit.to_text_diagram(use_unicode_characters=False).strip() == """ 0: ---F0--- | 1: ---F0--- """.strip()
def test_generate_parameter_calibration_circuit_failure(): """Tests that parameter calibration circuit generation fails because there are too many qubits""" n_qubits = 3 qubits = LineQubit.range(n_qubits) depth = 10 # Should raise exception because too many qubits with pytest.raises(CircuitMismatchException): _generate_parameter_calibration_circuit(qubits, depth, ZPowGate)
def test_F0Gate_text_unicode_diagram(): qubits = LineQubit.range(2) circuit = cirq.Circuit(_F0Gate().on(*qubits)) assert circuit.to_text_diagram().strip() == """ 0: ───F₀─── │ 1: ───F₀─── """.strip()
def test_range(): assert LineQubit.range(0) == [] assert LineQubit.range(1) == [LineQubit(0)] assert LineQubit.range(2) == [LineQubit(0), LineQubit(1)] assert LineQubit.range(5) == [ LineQubit(0), LineQubit(1), LineQubit(2), LineQubit(3), LineQubit(4), ] assert LineQubit.range(0, 0) == [] assert LineQubit.range(0, 1) == [LineQubit(0)] assert LineQubit.range(1, 4) == [LineQubit(1), LineQubit(2), LineQubit(3)] assert LineQubit.range(3, 1, -1) == [LineQubit(3), LineQubit(2)] assert LineQubit.range(3, 5, -1) == [] assert LineQubit.range(1, 5, 2) == [LineQubit(1), LineQubit(3)]
def test_ffft_multi_fermionic_mode(n, initial): initial_state = _multi_fermionic_mode_base_state(n, *initial) expected_state = _fourier_transform_multi_fermionic_mode(n, *initial) qubits = LineQubit.range(n) circuit = cirq.Circuit(ffft(qubits), strategy=cirq.InsertStrategy.EARLIEST) state = circuit.final_wavefunction(initial_state, qubits_that_should_be_present=qubits) assert np.allclose(state, expected_state, rtol=0.0)
def test_TwiddleGate_transform(k, n, qubit, initial, expected): qubits = LineQubit.range(2) initial_state = _single_fermionic_modes_state(initial) expected_state = _single_fermionic_modes_state(expected) circuit = cirq.Circuit(_TwiddleGate(k, n).on(qubits[qubit])) state = circuit.final_wavefunction(initial_state, qubits_that_should_be_present=qubits) assert np.allclose(state, expected_state, rtol=0.0)
def test_F0Gate_transform(amplitudes): qubits = LineQubit.range(2) initial_state = _single_fermionic_modes_state(amplitudes) expected_state = _single_fermionic_modes_state( _fourier_transform_single_fermionic_modes(amplitudes)) circuit = cirq.Circuit(_F0Gate().on(*qubits)) state = circuit.final_wavefunction(initial_state) assert np.allclose(state, expected_state, rtol=0.0)
def test_F0Gate_transform(amplitudes): qubits = LineQubit.range(2) initial_state = _single_fermionic_modes_state(amplitudes) expected_state = _single_fermionic_modes_state( _fourier_transform_single_fermionic_modes(amplitudes)) circuit = cirq.Circuit.from_ops(_F0Gate().on(*qubits)) state = circuit.apply_unitary_effect_to_state(initial_state) assert np.allclose(state, expected_state, rtol=0.0)
def test_generate_parameter_calibration_circuit(): """Tests generating a simple Parameter Calibration circuit""" n_qubits = 1 qubits = LineQubit.range(n_qubits) depth = 10 circuit = _generate_parameter_calibration_circuit(qubits, depth, ZPowGate) assert len(circuit) == depth # Make sure the exponents in the for i in range(len(circuit)): assert circuit[i].operations[0].gate.exponent == 2 * np.pi / depth
def test_execute_with_cdr(circuit_type): circuit = random_x_z_circuit(LineQubit.range(2), n_moments=2, random_state=1) circuit = convert_from_mitiq(circuit, circuit_type) # Define observables for testing. sigma_z = np.diag([1, -1]) obs = np.kron(np.identity(2), sigma_z) obs2 = np.kron(sigma_z, sigma_z) obs_list = [np.diag(obs), np.diag(obs2)] exact_solution = [ calculate_observable(simulator_statevector(circuit), observable=obs) for obs in obs_list ] kwargs = { "method_select": "gaussian", "method_replace": "gaussian", "sigma_select": 0.5, "sigma_replace": 0.5, "random_state": 1, } num_circuits = 4 frac_non_cliff = 0.5 noisy_executor = partial(executor, noise_level=0.5) results0 = execute_with_cdr( circuit, noisy_executor, simulator_statevector, obs_list, num_circuits, frac_non_cliff, full_output=True, ) results1 = execute_with_cdr( circuit, noisy_executor, simulator_statevector, obs_list, num_circuits, frac_non_cliff, ansatz=linear_fit_function_no_intercept, num_fit_parameters=1, scale_noise=fold_gates_from_left, scale_factors=[3], full_output=True, **kwargs, ) for results in [results0, results1]: for i in range(len(results[1])): assert abs(results[1][i][0] - exact_solution[i]) >= abs(results[0][i] - exact_solution[i])
def test_bogoliubov_transform_quadratic_hamiltonian(n_qubits, conserves_particle_number, atol=5e-5): qubits = LineQubit.range(n_qubits) # Initialize a random quadratic Hamiltonian quad_ham = random_quadratic_hamiltonian(n_qubits, conserves_particle_number, real=False) quad_ham_sparse = get_sparse_operator(quad_ham) # Compute the orbital energies and circuit orbital_energies, constant = quad_ham.orbital_energies() transformation_matrix = quad_ham.diagonalizing_bogoliubov_transform() circuit = cirq.Circuit.from_ops( bogoliubov_transform(qubits, transformation_matrix)) # Pick some random eigenstates to prepare, which correspond to random # subsets of [0 ... n_qubits - 1] n_eigenstates = min(2**n_qubits, 5) subsets = [ numpy.random.choice(range(n_qubits), numpy.random.randint(1, n_qubits + 1), False) for _ in range(n_eigenstates) ] # Also test empty subset subsets += [()] for occupied_orbitals in subsets: # Compute the energy of this eigenstate energy = (sum(orbital_energies[i] for i in occupied_orbitals) + constant) # Construct initial state initial_state = sum(2**(n_qubits - 1 - int(i)) for i in occupied_orbitals) # Get the state using a circuit simulation state1 = circuit.apply_unitary_effect_to_state(initial_state) # Also test the option to start with a computational basis state special_circuit = cirq.Circuit.from_ops( bogoliubov_transform(qubits, transformation_matrix, initial_state=initial_state)) state2 = special_circuit.apply_unitary_effect_to_state( initial_state, qubits_that_should_be_present=qubits) # Check that the result is an eigenstate with the correct eigenvalue numpy.testing.assert_allclose(quad_ham_sparse.dot(state1), energy * state1, atol=atol) numpy.testing.assert_allclose(quad_ham_sparse.dot(state2), energy * state2, atol=atol)
def test_ffft_single_fermionic_modes(amplitudes): initial_state = _single_fermionic_modes_state(amplitudes) expected_state = _single_fermionic_modes_state( _fourier_transform_single_fermionic_modes(amplitudes)) qubits = LineQubit.range(len(amplitudes)) circuit = cirq.Circuit(ffft(qubits), strategy=cirq.InsertStrategy.EARLIEST) state = circuit.final_wavefunction(initial_state, qubits_that_should_be_present=qubits) assert np.allclose(state, expected_state, rtol=0.0)
def init_truth(n): q = [LineQubit(i) for i in range(n)] init_type = cirq.I.on_each(*q) circuit_unitary = np.identity(2**n) node_0 = EveryNode(None, init_type, 0, circuit_unitary) # tree_queue = queue.Queue() tree_queue = [node_0] com_circuit(tree_queue, type_circuit(n)) print('(数组列表):[代价,node标号]') # print(result_dict) print('真值表可表达的情况数目:{}'.format(len(result_dict)))
from cirq import LineQubit print(LineQubit.range(6))