diff --git a/dev_requirements.txt b/dev_requirements.txt index b3421e55b1..97a2f4df78 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -9,7 +9,7 @@ amazon-braket-sdk~=1.14.0 pytest-xdist[psutil]~=2.5.0 pytest-cov~=3.0.0 flake8~=4.0.1 -black~=19.10b0 +black~=22.1 mypy~=0.931 # Documentation and examples. diff --git a/mitiq/benchmarks/ghz_circuits.py b/mitiq/benchmarks/ghz_circuits.py index d31d2e21f3..5b15226d39 100644 --- a/mitiq/benchmarks/ghz_circuits.py +++ b/mitiq/benchmarks/ghz_circuits.py @@ -22,19 +22,20 @@ def generate_ghz_circuit( - n_qubits: int, return_type: Optional[str] = None, + n_qubits: int, + return_type: Optional[str] = None, ) -> QPROGRAM: """Returns a GHZ circuit ie a circuit that prepares an ``n_qubits`` GHZ state. - Args: - n_qubits: The number of qubits in the circuit. - 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``. + Args: + n_qubits: The number of qubits in the circuit. + 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 GHZ circuit acting on ``n_qubits`` qubits. + Returns: + A GHZ circuit acting on ``n_qubits`` qubits. """ if n_qubits <= 0: raise ValueError( diff --git a/mitiq/benchmarks/randomized_benchmarking.py b/mitiq/benchmarks/randomized_benchmarking.py index 419388e11c..14c5a5d9a3 100644 --- a/mitiq/benchmarks/randomized_benchmarking.py +++ b/mitiq/benchmarks/randomized_benchmarking.py @@ -71,11 +71,17 @@ def generate_rb_circuits( ] else: cfd_matrices = _two_qubit_clifford_matrices( - qubits[0], qubits[1], cliffords, + qubits[0], + qubits[1], + cliffords, ) circuits = [ _random_two_q_clifford( - qubits[0], qubits[1], num_cliffords, cfd_matrices, cliffords, + qubits[0], + qubits[1], + num_cliffords, + cfd_matrices, + cliffords, ) for _ in range(trials) ] diff --git a/mitiq/cdr/clifford_training_data.py b/mitiq/cdr/clifford_training_data.py index d4f2f1f112..2e3d4c3cd1 100644 --- a/mitiq/cdr/clifford_training_data.py +++ b/mitiq/cdr/clifford_training_data.py @@ -301,7 +301,8 @@ def _replace( return [ cirq.ops.rz(a).on(*q) for (a, q) in zip( - clifford_angles, [op.qubits for op in non_clifford_ops], + clifford_angles, + [op.qubits for op in non_clifford_ops], ) ] @@ -344,7 +345,10 @@ def _closest_clifford(angles: np.ndarray) -> float: @np.vectorize -def _is_clifford_angle(angles: np.ndarray, tol: float = 10 ** -5,) -> bool: +def _is_clifford_angle( + angles: np.ndarray, + tol: float = 10**-5, +) -> bool: """Function to check if a given angle is Clifford. Args: @@ -376,7 +380,7 @@ def _angle_to_proximities(angle: np.ndarray, sigma: float) -> List[float]: for exponent in range(4): if exponent == 0: exponent = 4 - diff = np.linalg.norm(rz_matrix - s_matrix ** exponent) + diff = np.linalg.norm(rz_matrix - s_matrix**exponent) dists.append(np.exp(-((diff / sigma) ** 2))) return dists @@ -400,7 +404,9 @@ def _angle_to_proximity(angle: np.ndarray, sigma: float) -> float: @np.vectorize def _probabilistic_angle_to_clifford( - angles: np.ndarray, sigma: float, random_state: np.random.RandomState, + angles: np.ndarray, + sigma: float, + random_state: np.random.RandomState, ) -> float: """Returns a Clifford angle sampled from the distribution diff --git a/mitiq/cdr/tests/test_cdr.py b/mitiq/cdr/tests/test_cdr.py index 6339e60d74..0d5a4d886d 100644 --- a/mitiq/cdr/tests/test_cdr.py +++ b/mitiq/cdr/tests/test_cdr.py @@ -65,7 +65,9 @@ def simulate(circuit: QPROGRAM) -> np.ndarray: @pytest.mark.parametrize("random_state", [1, 2, 3, 4, 5]) def test_execute_with_cdr(circuit_type, fit_function, kwargs, random_state): circuit = random_x_z_cnot_circuit( - LineQubit.range(2), n_moments=5, random_state=random_state, + LineQubit.range(2), + n_moments=5, + random_state=random_state, ) circuit = convert_from_mitiq(circuit, circuit_type) obs = Observable(PauliString("XZ"), PauliString("YY")) @@ -125,7 +127,10 @@ def test_no_num_fit_parameters_with_custom_fit_raises_error(): def test_execute_with_cdr_using_clifford_circuit(): a, b = cirq.LineQubit.range(2) - clifCirc = cirq.Circuit(cirq.H.on(a), cirq.H.on(b),) + clifCirc = cirq.Circuit( + cirq.H.on(a), + cirq.H.on(b), + ) obs = Observable(PauliString("XZ"), PauliString("YY")) cdr_value = execute_with_cdr( clifCirc, observable=obs, executor=execute, simulator=simulate diff --git a/mitiq/cdr/tests/test_clifford_training_data.py b/mitiq/cdr/tests/test_clifford_training_data.py index 00af27c077..d909f40667 100644 --- a/mitiq/cdr/tests/test_clifford_training_data.py +++ b/mitiq/cdr/tests/test_clifford_training_data.py @@ -156,7 +156,9 @@ def test_generate_training_circuits_bad_methods(): def test_generate_training_circuits_with_clifford_circuit(): circuit = Circuit(cirq.ops.rx(0.0).on(cirq.LineQubit(0))) assert generate_training_circuits( - circuit, num_training_circuits=2, fraction_non_clifford=0.0, + circuit, + num_training_circuits=2, + fraction_non_clifford=0.0, ) == [circuit, circuit] diff --git a/mitiq/interface/conversions.py b/mitiq/interface/conversions.py index 29cf8446e7..f0e059cebc 100644 --- a/mitiq/interface/conversions.py +++ b/mitiq/interface/conversions.py @@ -282,7 +282,8 @@ def new_scaling_function( scaled_circuit.remove_final_measurements() _transform_registers( - scaled_circuit, new_qregs=circuit.qregs, # type: ignore + scaled_circuit, + new_qregs=circuit.qregs, # type: ignore ) if circuit.cregs and not scaled_circuit.cregs: # type: ignore scaled_circuit.add_register(*circuit.cregs) # type: ignore diff --git a/mitiq/interface/mitiq_braket/conversions.py b/mitiq/interface/mitiq_braket/conversions.py index 30ef6b1e2d..175c45ad70 100644 --- a/mitiq/interface/mitiq_braket/conversions.py +++ b/mitiq/interface/mitiq_braket/conversions.py @@ -285,7 +285,8 @@ def _translate_two_qubit_braket_instruction_to_cirq_operation( def _translate_one_qubit_cirq_operation_to_braket_instruction( - op: Union[np.ndarray, cirq_ops.Operation], target: Optional[int] = None, + op: Union[np.ndarray, cirq_ops.Operation], + target: Optional[int] = None, ) -> List[Instruction]: """Translates a one-qubit Cirq operation to a (sequence of) Braket instruction(s) according to the following rules: diff --git a/mitiq/interface/mitiq_braket/tests/test_conversions_braket.py b/mitiq/interface/mitiq_braket/tests/test_conversions_braket.py index 8289ee0b6d..eb5c4e8b40 100644 --- a/mitiq/interface/mitiq_braket/tests/test_conversions_braket.py +++ b/mitiq/interface/mitiq_braket/tests/test_conversions_braket.py @@ -185,7 +185,7 @@ def test_from_braket_three_qubit_gates(): def _rotation_of_pi_over_7(num_qubits): - matrix = np.identity(2 ** num_qubits) + matrix = np.identity(2**num_qubits) matrix[0:2, 0:2] = [ [np.cos(np.pi / 7), np.sin(np.pi / 7)], [-np.sin(np.pi / 7), np.cos(np.pi / 7)], @@ -307,7 +307,11 @@ def test_to_from_braket_uncommon_two_qubit_gates(uncommon_gate): @pytest.mark.parametrize( - "common_gate", [ops.TOFFOLI, ops.FREDKIN,], + "common_gate", + [ + ops.TOFFOLI, + ops.FREDKIN, + ], ) def test_to_from_braket_common_three_qubit_gates(common_gate): """These gates should stay the same (i.e., not get decomposed) when diff --git a/mitiq/interface/mitiq_pennylane/tests/test_conversions_pennylane.py b/mitiq/interface/mitiq_pennylane/tests/test_conversions_pennylane.py index decc4ea820..c51bfb166c 100644 --- a/mitiq/interface/mitiq_pennylane/tests/test_conversions_pennylane.py +++ b/mitiq/interface/mitiq_pennylane/tests/test_conversions_pennylane.py @@ -98,7 +98,8 @@ def test_non_consecutive_wires_error(): with qml.tape.QuantumTape() as tape: qml.CNOT(wires=[0, 2]) with pytest.raises( - UnsupportedQuantumTapeError, match="contiguously pack", + UnsupportedQuantumTapeError, + match="contiguously pack", ): from_pennylane(tape) diff --git a/mitiq/interface/mitiq_pyquil/tests/test_zne_mitiq_pyquil.py b/mitiq/interface/mitiq_pyquil/tests/test_zne_mitiq_pyquil.py index c4e2709ee4..74ae508e18 100644 --- a/mitiq/interface/mitiq_pyquil/tests/test_zne_mitiq_pyquil.py +++ b/mitiq/interface/mitiq_pyquil/tests/test_zne_mitiq_pyquil.py @@ -41,7 +41,10 @@ def noiseless_executor(program: pyquil.Program) -> float: def test_run_factory(): (qp,) = benchmarks.generate_rb_circuits( - n_qubits=1, num_cliffords=TEST_DEPTH, trials=1, return_type="pyquil", + n_qubits=1, + num_cliffords=TEST_DEPTH, + trials=1, + return_type="pyquil", ) fac = zne.inference.RichardsonFactory([1.0, 2.0, 3.0]) @@ -55,7 +58,10 @@ def test_run_factory(): def test_execute_with_zne(): (qp,) = benchmarks.generate_rb_circuits( - n_qubits=1, num_cliffords=TEST_DEPTH, trials=1, return_type="pyquil", + n_qubits=1, + num_cliffords=TEST_DEPTH, + trials=1, + return_type="pyquil", ) result = zne.execute_with_zne(qp, noiseless_executor) assert np.isclose(result, 1.0, atol=1e-5) @@ -63,7 +69,10 @@ def test_execute_with_zne(): def test_mitigate_executor(): (qp,) = benchmarks.generate_rb_circuits( - n_qubits=1, num_cliffords=TEST_DEPTH, trials=1, return_type="pyquil", + n_qubits=1, + num_cliffords=TEST_DEPTH, + trials=1, + return_type="pyquil", ) new_executor = zne.mitigate_executor(noiseless_executor) @@ -78,7 +87,10 @@ def decorated_executor(qp: pyquil.Program) -> float: def test_zne_decorator(): (qp,) = benchmarks.generate_rb_circuits( - n_qubits=1, num_cliffords=TEST_DEPTH, trials=1, return_type="pyquil", + n_qubits=1, + num_cliffords=TEST_DEPTH, + trials=1, + return_type="pyquil", ) result = decorated_executor(qp) diff --git a/mitiq/interface/mitiq_qiskit/qiskit_utils.py b/mitiq/interface/mitiq_qiskit/qiskit_utils.py index b40e6d53e2..924f716246 100644 --- a/mitiq/interface/mitiq_qiskit/qiskit_utils.py +++ b/mitiq/interface/mitiq_qiskit/qiskit_utils.py @@ -80,7 +80,10 @@ def execute_with_shots( """ return execute_with_shots_and_noise( - circuit, obs, noise_model=None, shots=shots, + circuit, + obs, + noise_model=None, + shots=shots, ) diff --git a/mitiq/interface/mitiq_qiskit/tests/test_qiskit_utils.py b/mitiq/interface/mitiq_qiskit/tests/test_qiskit_utils.py index 51558352aa..683d44391b 100644 --- a/mitiq/interface/mitiq_qiskit/tests/test_qiskit_utils.py +++ b/mitiq/interface/mitiq_qiskit/tests/test_qiskit_utils.py @@ -32,7 +32,7 @@ def test_execute(): - """ Tests the Qiskit wavefunction simulation executor returns + """Tests the Qiskit wavefunction simulation executor returns appropriate expectation value given an observable. """ @@ -47,7 +47,7 @@ def test_execute(): def test_execute_with_shots(): - """ Tests the Qiskit wavefunction sampling simulation executor returns + """Tests the Qiskit wavefunction sampling simulation executor returns appropriate expectation value given an observable. """ @@ -66,7 +66,7 @@ def test_execute_with_shots(): def test_execute_with_depolarizing_noise_single_qubit(): - """ Tests the noisy sampling executor across increasing levels + """Tests the noisy sampling executor across increasing levels of single qubit gate noise """ @@ -88,7 +88,7 @@ def test_execute_with_depolarizing_noise_single_qubit(): def test_execute_with_depolarizing_noise_two_qubit(): - """ Tests the noisy sampling executor across increasing levels of + """Tests the noisy sampling executor across increasing levels of two qubit gate noise. """ @@ -110,7 +110,7 @@ def test_execute_with_depolarizing_noise_two_qubit(): def test_execute_with_shots_and_depolarizing_noise_single_qubit(): - """ Tests the noisy sampling executor across increasing levels + """Tests the noisy sampling executor across increasing levels of single qubit gate noise. """ @@ -133,7 +133,7 @@ def test_execute_with_shots_and_depolarizing_noise_single_qubit(): def test_execute_with_shots_and_depolarizing_noise_two_qubit(): - """ Tests the noisy sampling executor across increasing levels of + """Tests the noisy sampling executor across increasing levels of two qubit gate noise. """ diff --git a/mitiq/observable/observable.py b/mitiq/observable/observable.py index a179593b88..ac9a13bf22 100644 --- a/mitiq/observable/observable.py +++ b/mitiq/observable/observable.py @@ -25,7 +25,7 @@ class Observable: """A quantum observable typically used to compute its mitigated expectation - value. + value. """ @@ -115,7 +115,7 @@ def matrix( qubit_indices = self.qubit_indices n = len(qubit_indices) - matrix = np.zeros(shape=(2 ** n, 2 ** n), dtype=dtype) + matrix = np.zeros(shape=(2**n, 2**n), dtype=dtype) for pauli in self._paulis: matrix += pauli.matrix( qubit_indices_to_include=qubit_indices diff --git a/mitiq/observable/tests/test_pauli.py b/mitiq/observable/tests/test_pauli.py index fdd8c8ac2e..8bb1950f73 100644 --- a/mitiq/observable/tests/test_pauli.py +++ b/mitiq/observable/tests/test_pauli.py @@ -222,7 +222,8 @@ def test_expectation_from_measurements_identity(seed, nqubits): rng.randint(low=0, high=1 + 1, size=(100, nqubits)).tolist() ) assert np.isclose( - pauli._expectation_from_measurements(measurements), coeff, + pauli._expectation_from_measurements(measurements), + coeff, ) @@ -230,17 +231,32 @@ def test_expectation_from_measurements_two_qubits(): measurements = MeasurementResult([[0, 1] * 1_000]) z0 = PauliString(spec="Z", support=(0,)) - assert np.isclose(z0._expectation_from_measurements(measurements), 1.0,) + assert np.isclose( + z0._expectation_from_measurements(measurements), + 1.0, + ) zi = PauliString(spec="ZI") - assert np.isclose(zi._expectation_from_measurements(measurements), 1.0,) + assert np.isclose( + zi._expectation_from_measurements(measurements), + 1.0, + ) z1 = PauliString(spec="Z", support=(1,)) - assert np.isclose(z1._expectation_from_measurements(measurements), -1.0,) + assert np.isclose( + z1._expectation_from_measurements(measurements), + -1.0, + ) iz = PauliString(spec="IZ") - assert np.isclose(iz._expectation_from_measurements(measurements), -1.0,) + assert np.isclose( + iz._expectation_from_measurements(measurements), + -1.0, + ) zz = PauliString(spec="ZZ") - assert np.isclose(zz._expectation_from_measurements(measurements), -1.0,) + assert np.isclose( + zz._expectation_from_measurements(measurements), + -1.0, + ) def test_pstringcollection(): diff --git a/mitiq/pec/channels.py b/mitiq/pec/channels.py index 5eb9b89852..aab4c26782 100644 --- a/mitiq/pec/channels.py +++ b/mitiq/pec/channels.py @@ -126,12 +126,13 @@ def matrix_to_vector(density_matrix: np.ndarray) -> np.ndarray: def _safe_sqrt( - perfect_square: int, error_str: str = "The input must be a square number.", + perfect_square: int, + error_str: str = "The input must be a square number.", ) -> int: """Takes the square root of the input integer and raises an error if the input is not a perfect square.""" square_root = int(np.round(np.sqrt(perfect_square))) - if square_root ** 2 != perfect_square: + if square_root**2 != perfect_square: raise ValueError(error_str) return square_root @@ -182,7 +183,7 @@ def choi_to_super(choi_state: np.ndarray) -> np.ndarray: choi_kl_ij = choi_state.reshape(dim, dim, dim, dim) choi_ki_lj = choi_kl_ij.transpose(0, 2, 1, 3) - super_not_normalized = choi_ki_lj.reshape(dim ** 2, dim ** 2) + super_not_normalized = choi_ki_lj.reshape(dim**2, dim**2) return dim * super_not_normalized diff --git a/mitiq/pec/pec.py b/mitiq/pec/pec.py index 32a7f9f3ef..70bec55644 100644 --- a/mitiq/pec/pec.py +++ b/mitiq/pec/pec.py @@ -37,8 +37,7 @@ class LargeSampleWarning(Warning): - """Warning is raised when PEC sample size is greater than 10 ** 5 - """ + """Warning is raised when PEC sample size is greater than 10 ** 5""" pass @@ -128,7 +127,9 @@ def execute_with_pec( # Get the 1-norm of the circuit quasi-probability representation _, _, norm = sample_circuit( - converted_circuit, representations, num_samples=1, + converted_circuit, + representations, + num_samples=1, ) # Deduce the number of samples (if not given by the user) @@ -136,7 +137,7 @@ def execute_with_pec( num_samples = int((norm / precision) ** 2) # Issue warning for very large sample size - if num_samples > 10 ** 5: + if num_samples > 10**5: warnings.warn(_LARGE_SAMPLE_WARN, LargeSampleWarning) # Sample all the circuits diff --git a/mitiq/pec/representations/damping.py b/mitiq/pec/representations/damping.py index ae0c15e983..67c216ab43 100644 --- a/mitiq/pec/representations/damping.py +++ b/mitiq/pec/representations/damping.py @@ -34,7 +34,8 @@ # TODO: this may be extended to an arbitrary QPROGRAM (GitHub issue gh-702). def _represent_operation_with_amplitude_damping_noise( - ideal_operation: Circuit, noise_level: float, + ideal_operation: Circuit, + noise_level: float, ) -> OperationRepresentation: r"""Returns the quasi-probability representation of the input single-qubit ``ideal_operation`` with respect to a basis of noisy @@ -96,7 +97,8 @@ def _represent_operation_with_amplitude_damping_noise( def amplitude_damping_kraus( - noise_level: float, num_qubits: int, + noise_level: float, + num_qubits: int, ) -> List[np.ndarray]: """Returns the Kraus operators of the tensor product of local depolarizing channels acting on each qubit. diff --git a/mitiq/pec/representations/depolarizing.py b/mitiq/pec/representations/depolarizing.py index 8361414b5f..69b79f5de1 100644 --- a/mitiq/pec/representations/depolarizing.py +++ b/mitiq/pec/representations/depolarizing.py @@ -197,7 +197,8 @@ def represent_operation_with_local_depolarizing_noise( if len(qubits) == 1: return represent_operation_with_global_depolarizing_noise( - ideal_operation, noise_level, + ideal_operation, + noise_level, ) # The two-qubit case: tensor product of two depolarizing channels. @@ -281,7 +282,8 @@ def represent_operations_in_circuit_with_global_depolarizing_noise( continue representations.append( represent_operation_with_global_depolarizing_noise( - Circuit(op), noise_level, + Circuit(op), + noise_level, ) ) return representations @@ -326,14 +328,16 @@ def represent_operations_in_circuit_with_local_depolarizing_noise( continue representations.append( represent_operation_with_local_depolarizing_noise( - Circuit(op), noise_level, + Circuit(op), + noise_level, ) ) return representations def global_depolarizing_kraus( - noise_level: float, num_qubits: int, + noise_level: float, + num_qubits: int, ) -> List[np.ndarray]: """Returns the kraus operators of a global depolarizing channel at a given noise level. @@ -343,7 +347,8 @@ def global_depolarizing_kraus( def local_depolarizing_kraus( - noise_level: float, num_qubits: int, + noise_level: float, + num_qubits: int, ) -> List[np.ndarray]: """Returns the kraus operators of the tensor product of local depolarizing channels acting on each qubit. diff --git a/mitiq/pec/representations/optimal.py b/mitiq/pec/representations/optimal.py index 241c627ccd..d59842ffea 100644 --- a/mitiq/pec/representations/optimal.py +++ b/mitiq/pec/representations/optimal.py @@ -144,7 +144,10 @@ def find_optimal_representation( # Run numerical optimization problem quasi_prob_dist = minimize_one_norm( - ideal_matrix, basis_matrices, tol=tol, initial_guess=initial_guess, + ideal_matrix, + basis_matrices, + tol=tol, + initial_guess=initial_guess, ) basis_expansion = {op: eta for op, eta in zip(basis_set, quasi_prob_dist)} diff --git a/mitiq/pec/representations/tests/test_damping.py b/mitiq/pec/representations/tests/test_damping.py index 3d25243ad2..9d215b7bf2 100644 --- a/mitiq/pec/representations/tests/test_damping.py +++ b/mitiq/pec/representations/tests/test_damping.py @@ -41,7 +41,8 @@ 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, + Circuit(gate(q)), + noise, ).norm assert np.isclose(optimal_norm, norm) @@ -52,14 +53,17 @@ def test_single_qubit_representation_norm(gate: Gate, noise: float): @pytest.mark.parametrize("noise", [0, 0.1, 0.7]) @pytest.mark.parametrize("gate", [X, Y, Z, H]) def test_amplitude_damping_representation_with_choi( - gate: Gate, noise: float, circuit_type: str, + gate: Gate, + noise: float, + circuit_type: str, ): """Tests the representation by comparing exact Choi matrices.""" q = LineQubit(0) ideal_circuit = convert_from_mitiq(Circuit(gate.on(q)), circuit_type) ideal_choi = _circuit_to_choi(Circuit(gate.on(q))) op_rep = _represent_operation_with_amplitude_damping_noise( - ideal_circuit, noise, + ideal_circuit, + noise, ) choi_components = [] for noisy_op, coeff in op_rep.basis_expansion.items(): @@ -72,7 +76,7 @@ def test_amplitude_damping_representation_with_choi( choi_components.append(coeff * sequence_choi) combination_choi = np.sum(choi_components, axis=0) - assert np.allclose(ideal_choi, combination_choi, atol=10 ** -8) + assert np.allclose(ideal_choi, combination_choi, atol=10**-8) def test_damping_kraus(): @@ -88,4 +92,4 @@ def test_damping_kraus(): for noise_level in (0.1, 1): kraus_ops = amplitude_damping_kraus(noise_level, num_qubits) dual_channel = sum([k.conj().T @ k for k in kraus_ops]) - assert np.allclose(dual_channel, np.eye(2 ** num_qubits)) + assert np.allclose(dual_channel, np.eye(2**num_qubits)) diff --git a/mitiq/pec/representations/tests/test_depolarizing.py b/mitiq/pec/representations/tests/test_depolarizing.py index 0835bd96df..8c1b26f16b 100644 --- a/mitiq/pec/representations/tests/test_depolarizing.py +++ b/mitiq/pec/representations/tests/test_depolarizing.py @@ -64,10 +64,10 @@ def single_qubit_depolarizing_overhead(noise_level: float) -> float: def two_qubit_depolarizing_overhead(noise_level: float) -> float: """See [Temme2017]_ for more information. - .. [Temme2017] : Kristan Temme, Sergey Bravyi, Jay M. Gambetta, - "Error mitigation for short-depth quantum circuits," - *Phys. Rev. Lett.* **119**, 180509 (2017), - (https://arxiv.org/abs/1612.02058). + .. [Temme2017] : Kristan Temme, Sergey Bravyi, Jay M. Gambetta, + "Error mitigation for short-depth quantum circuits," + *Phys. Rev. Lett.* **119**, 180509 (2017), + (https://arxiv.org/abs/1612.02058). """ epsilon = 16 / 15 * noise_level return (1 + 7 * epsilon / 8) / (1 - epsilon) @@ -79,7 +79,8 @@ 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, + Circuit(gate(q)), + noise, ).norm assert np.isclose(optimal_norm, norm) @@ -90,7 +91,8 @@ 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, + Circuit(gate(*qreg)), + noise, ).norm assert np.isclose(optimal_norm, norm) @@ -99,7 +101,8 @@ def test_three_qubit_depolarizing_representation_error(): q0, q1, q2 = LineQubit.range(3) with pytest.raises(ValueError): represent_operation_with_global_depolarizing_noise( - Circuit(CCNOT(q0, q1, q2)), 0.05, + Circuit(CCNOT(q0, q1, q2)), + 0.05, ) @@ -110,7 +113,8 @@ def test_depolarizing_representation_with_choi(gate: Gate, noise: float): 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, + Circuit(gate.on(*qreg)), + noise, ) choi_components = [] for noisy_op, coeff in op_rep.basis_expansion.items(): @@ -122,7 +126,7 @@ def test_depolarizing_representation_with_choi(gate: Gate, noise: float): 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) + assert np.allclose(ideal_choi, combination_choi, atol=10**-6) @pytest.mark.parametrize("noise", [0, 0.1, 0.7]) @@ -132,7 +136,8 @@ def test_local_depolarizing_representation_with_choi(gate: Gate, noise: float): qreg = LineQubit.range(gate.num_qubits()) ideal_choi = _operation_to_choi(gate.on(*qreg)) op_rep = represent_operation_with_local_depolarizing_noise( - Circuit(gate.on(*qreg)), noise, + Circuit(gate.on(*qreg)), + noise, ) choi_components = [] for noisy_op, coeff in op_rep.basis_expansion.items(): @@ -145,14 +150,15 @@ def test_local_depolarizing_representation_with_choi(gate: Gate, noise: float): 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) + assert np.allclose(ideal_choi, combination_choi, atol=10**-6) 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, + Circuit(CCNOT(q0, q1, q2)), + 0.05, ) @@ -164,7 +170,8 @@ def test_represent_operations_in_circuit_global(circuit_type: str): circ = convert_from_mitiq(circ_mitiq, circuit_type) reps = represent_operations_in_circuit_with_global_depolarizing_noise( - ideal_circuit=circ, noise_level=0.1, + ideal_circuit=circ, + noise_level=0.1, ) # For each operation in circ we should find its representation @@ -187,7 +194,8 @@ def test_represent_operations_in_circuit_local(circuit_type: str): circ = convert_from_mitiq(circ_mitiq, circuit_type) reps = represent_operations_in_circuit_with_local_depolarizing_noise( - ideal_circuit=circ, noise_level=0.1, + ideal_circuit=circ, + noise_level=0.1, ) for op in convert_to_mitiq(circ)[0].all_operations(): @@ -210,7 +218,8 @@ def test_represent_operations_in_circuit_local(circuit_type: str): ) @pytest.mark.parametrize("circuit_type", ["cirq", "qiskit", "pyquil"]) def test_represent_operations_in_circuit_with_measurements( - circuit_type: str, rep_function, + circuit_type: str, + rep_function, ): """Tests measurements in circuit are ignored (not represented).""" q0, q1 = LineQubit.range(2) @@ -239,7 +248,8 @@ def test_represent_operations_in_circuit_with_measurements( @pytest.mark.parametrize( - "kraus_function", [global_depolarizing_kraus, local_depolarizing_kraus], + "kraus_function", + [global_depolarizing_kraus, local_depolarizing_kraus], ) def test_depolarizing_kraus(kraus_function): expected = [ @@ -254,4 +264,4 @@ def test_depolarizing_kraus(kraus_function): for noise_level in (0.1, 1): kraus_ops = kraus_function(noise_level, num_qubits) dual_channel = sum([k.conj().T @ k for k in kraus_ops]) - assert np.allclose(dual_channel, np.eye(2 ** num_qubits)) + assert np.allclose(dual_channel, np.eye(2**num_qubits)) diff --git a/mitiq/pec/representations/tests/test_optimal.py b/mitiq/pec/representations/tests/test_optimal.py index f83fe43125..60ed0eaece 100644 --- a/mitiq/pec/representations/tests/test_optimal.py +++ b/mitiq/pec/representations/tests/test_optimal.py @@ -224,7 +224,8 @@ def test_find_optimal_representation_depolarizing_two_qubit_gates(circ_type): ) # Expected analytical result expected_rep = represent_operation_with_local_depolarizing_noise( - ideal_op_native, noise_level, + ideal_op_native, + noise_level, ) assert np.allclose(np.sort(rep.coeffs), np.sort(expected_rep.coeffs)) assert rep == expected_rep @@ -267,7 +268,8 @@ def test_find_optimal_representation_single_qubit_depolarizing(circ_type): ) # Expected analytical result expected_rep = represent_operation_with_local_depolarizing_noise( - ideal_op_native, noise_level, + ideal_op_native, + noise_level, ) assert np.allclose(np.sort(rep.coeffs), np.sort(expected_rep.coeffs)) assert rep == expected_rep @@ -312,7 +314,8 @@ def test_find_optimal_representation_single_qubit_amp_damping(circ_type): ) # Expected analytical result expected_rep = _represent_operation_with_amplitude_damping_noise( - ideal_op_native, noise_level, + ideal_op_native, + noise_level, ) assert np.allclose(np.sort(rep.coeffs), np.sort(expected_rep.coeffs)) assert rep == expected_rep diff --git a/mitiq/pec/tests/test_channels.py b/mitiq/pec/tests/test_channels.py index c05eb9d5f6..5014182b84 100644 --- a/mitiq/pec/tests/test_channels.py +++ b/mitiq/pec/tests/test_channels.py @@ -77,7 +77,7 @@ def test_operation_to_choi(): choi_twice = sum( [ ((1.0 - epsilon) ** 2 * identity_part), - (2 * epsilon - epsilon ** 2) * mixed_part, + (2 * epsilon - epsilon**2) * mixed_part, ] ) @@ -108,13 +108,13 @@ def test_circuit_to_choi(): def test_matrix_to_vector(): for d in [1, 2, 3, 4]: mat = np.random.rand(d, d) - assert matrix_to_vector(mat).shape == (d ** 2,) + assert matrix_to_vector(mat).shape == (d**2,) assert (vector_to_matrix(matrix_to_vector(mat)) == mat).all def test_vector_to_matrix(): for d in [1, 2, 3, 4]: - vec = np.random.rand(d ** 2) + vec = np.random.rand(d**2) assert vector_to_matrix(vec).shape == (d, d) assert (matrix_to_vector(vector_to_matrix(vec)) == vec).all @@ -131,7 +131,7 @@ def test_kraus_to_super(): Channels and states are non-physical, but this is irrelevant for the test. """ for num_qubits in (1, 2, 3, 4, 5): - d = 2 ** num_qubits + d = 2**num_qubits fake_kraus_ops = [ np.random.rand(d, d) + 1.0j * np.random.rand(d, d) for _ in range(7) @@ -165,7 +165,7 @@ def test_choi_to_super(): # Note: up to normalization, choi_to_super is equal to super_to_choi # and therefore we just run the following consistency test. for dim in (2, 4, 8, 16): - rand_mat = np.random.rand(dim ** 2, dim ** 2) + rand_mat = np.random.rand(dim**2, dim**2) assert np.allclose(super_to_choi(choi_to_super(rand_mat)), rand_mat) assert np.allclose(choi_to_super(super_to_choi(rand_mat)), rand_mat) diff --git a/mitiq/pec/tests/test_pec.py b/mitiq/pec/tests/test_pec.py index bf081ed236..28e9acfbfd 100644 --- a/mitiq/pec/tests/test_pec.py +++ b/mitiq/pec/tests/test_pec.py @@ -37,7 +37,8 @@ # Noisy representations of Pauli and CNOT operations for testing. def get_pauli_and_cnot_representations( - base_noise: float, qubits: Optional[List[cirq.Qid]] = None, + base_noise: float, + qubits: Optional[List[cirq.Qid]] = None, ) -> List[OperationRepresentation]: if qubits is None: @@ -58,7 +59,8 @@ def get_pauli_and_cnot_representations( # Generate all representations return represent_operations_in_circuit_with_local_depolarizing_noise( - ideal_circuit=cirq.Circuit(ideal_operations), noise_level=base_noise, + ideal_circuit=cirq.Circuit(ideal_operations), + noise_level=base_noise, ) @@ -407,7 +409,8 @@ def test_large_sample_size_warning(): """ warnings.simplefilter("error") with pytest.raises( - Warning, match="The number of PEC samples is very large.", + Warning, + match="The number of PEC samples is very large.", ): execute_with_pec( oneq_circ, @@ -482,7 +485,10 @@ def test_mitigate_executor_qiskit(): unmitigated = serial_executor(circuit) mitigated_executor = mitigate_executor( - serial_executor, representations=[rep], num_samples=10, random_state=1, + serial_executor, + representations=[rep], + num_samples=10, + random_state=1, ) mitigated = mitigated_executor(circuit) @@ -516,7 +522,10 @@ def test_mitigate_executor_cirq(): unmitigated = serial_executor(circuit) mitigated_executor = mitigate_executor( - serial_executor, representations=[rep], num_samples=10, random_state=1, + serial_executor, + representations=[rep], + num_samples=10, + random_state=1, ) mitigated = mitigated_executor(circuit) @@ -548,7 +557,10 @@ def test_mitigate_executor_pyquil(): unmitigated = serial_executor(circuit) mitigated_executor = mitigate_executor( - serial_executor, representations=[rep], num_samples=10, random_state=1, + serial_executor, + representations=[rep], + num_samples=10, + random_state=1, ) mitigated = mitigated_executor(circuit) diff --git a/mitiq/pec/tests/test_pec_sampling.py b/mitiq/pec/tests/test_pec_sampling.py index caa49d1f2e..177026f9fe 100644 --- a/mitiq/pec/tests/test_pec_sampling.py +++ b/mitiq/pec/tests/test_pec_sampling.py @@ -71,7 +71,8 @@ def test_sample_sequence_qiskit(): noisy_zop = NoisyOperation(zcircuit) rep = OperationRepresentation( - ideal=circuit, basis_expansion={noisy_xop: 0.5, noisy_zop: -0.5}, + ideal=circuit, + basis_expansion={noisy_xop: 0.5, noisy_zop: -0.5}, ) for _ in range(5): @@ -88,7 +89,8 @@ def test_sample_sequence_pyquil(): noisy_zop = NoisyOperation(pyquil.Program(pyquil.gates.Z(0))) rep = OperationRepresentation( - ideal=circuit, basis_expansion={noisy_xop: 0.5, noisy_zop: -0.5}, + ideal=circuit, + basis_expansion={noisy_xop: 0.5, noisy_zop: -0.5}, ) for _ in range(50): @@ -279,7 +281,8 @@ def test_sample_sequence_choi(gate: cirq.Gate): noisy_choi = _operation_to_choi(noisy_op_tree) representation = represent_operation_with_local_depolarizing_noise( - ideal_circ, BASE_NOISE, + ideal_circ, + BASE_NOISE, ) choi_unbiased_estimates = [] @@ -305,7 +308,9 @@ def test_sample_circuit_choi(): # A simple 2-qubit circuit qreg = cirq.LineQubit.range(2) ideal_circ = cirq.Circuit( - cirq.X.on(qreg[0]), cirq.I.on(qreg[1]), cirq.CNOT.on(*qreg), + cirq.X.on(qreg[0]), + cirq.I.on(qreg[1]), + cirq.CNOT.on(*qreg), ) noisy_circuit = ideal_circ.with_noise(cirq.depolarize(BASE_NOISE)) @@ -314,7 +319,8 @@ def test_sample_circuit_choi(): noisy_choi = _operation_to_choi(noisy_circuit) rep_list = represent_operations_in_circuit_with_local_depolarizing_noise( - ideal_circuit=ideal_circ, noise_level=BASE_NOISE, + ideal_circuit=ideal_circ, + noise_level=BASE_NOISE, ) choi_unbiased_estimates = [] diff --git a/mitiq/pec/types/tests/test_types.py b/mitiq/pec/types/tests/test_types.py index b339937a31..fa2879df6c 100644 --- a/mitiq/pec/types/tests/test_types.py +++ b/mitiq/pec/types/tests/test_types.py @@ -717,13 +717,21 @@ def test_print_cirq_operation_representation(): ) # Positive first coefficient decomp = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_xop: 0.5, noisy_zop: 0.5,}, + ideal=ideal, + basis_expansion={ + noisy_xop: 0.5, + noisy_zop: 0.5, + }, ) expected = r"0: ───H─── = 0.500*(0: ───X───)+0.500*(0: ───Z───)" assert str(decomp) == expected # Negative first coefficient decomp = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_xop: -0.5, noisy_zop: 1.5,}, + ideal=ideal, + basis_expansion={ + noisy_xop: -0.5, + noisy_zop: 1.5, + }, ) expected = r"0: ───H─── = -0.500*(0: ───X───)+1.500*(0: ───Z───)" assert str(decomp) == expected @@ -733,18 +741,21 @@ def test_print_cirq_operation_representation(): assert str(decomp) == expected # Small coefficient approximation decomp = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_xop: 1.00001, noisy_zop: 0.00001}, + ideal=ideal, + basis_expansion={noisy_xop: 1.00001, noisy_zop: 0.00001}, ) expected = r"0: ───H─── = 1.000*(0: ───X───)" assert str(decomp) == expected # Small coefficient approximation different position decomp = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_xop: 0.00001, noisy_zop: 1.00001}, + ideal=ideal, + basis_expansion={noisy_xop: 0.00001, noisy_zop: 1.00001}, ) expected = r"0: ───H─── = 1.000*(0: ───Z───)" # Small coefficient approximation different position decomp = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_xop: 0.00001}, + ideal=ideal, + basis_expansion={noisy_xop: 0.00001}, ) expected = r"0: ───H─── = 0.000" assert str(decomp) == expected @@ -761,11 +772,17 @@ def test_print_operation_representation_two_qubits(): ) noisy_b = NoisyOperation.from_cirq( circuit=cirq.Circuit( - cirq.Z.on_each(qreg), cirq.CNOT(*qreg), cirq.Z.on_each(qreg), + cirq.Z.on_each(qreg), + cirq.CNOT(*qreg), + cirq.Z.on_each(qreg), ) ) decomp = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_a: 0.5, noisy_b: 0.5,}, + ideal=ideal, + basis_expansion={ + noisy_a: 0.5, + noisy_b: 0.5, + }, ) print(str(decomp)) expected = f""" @@ -800,7 +817,11 @@ def test_print_operation_representation_two_qubits_neg(): circuit=cirq.Circuit(cirq.Z.on_each(qreg[1])) ) decomp = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_a: -0.5, noisy_b: 1.5,}, + ideal=ideal, + basis_expansion={ + noisy_a: -0.5, + noisy_b: 1.5, + }, ) print(str(decomp)) expected = f""" @@ -824,29 +845,36 @@ def test_equal_method_of_representations(): q = cirq.LineQubit(0) ideal = cirq.Circuit(cirq.H(q)) noisy_xop_a = NoisyOperation( - circuit=cirq.Circuit(cirq.X(q)), channel_matrix=np.zeros(shape=(4, 4)), + circuit=cirq.Circuit(cirq.X(q)), + channel_matrix=np.zeros(shape=(4, 4)), ) noisy_zop_a = NoisyOperation( - circuit=cirq.Circuit(cirq.Z(q)), channel_matrix=np.zeros(shape=(4, 4)), + circuit=cirq.Circuit(cirq.Z(q)), + channel_matrix=np.zeros(shape=(4, 4)), ) rep_a = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_xop_a: 0.5, noisy_zop_a: 0.5}, + ideal=ideal, + basis_expansion={noisy_xop_a: 0.5, noisy_zop_a: 0.5}, ) noisy_xop_b = NoisyOperation( - circuit=cirq.Circuit(cirq.X(q)), channel_matrix=np.ones(shape=(4, 4)), + circuit=cirq.Circuit(cirq.X(q)), + channel_matrix=np.ones(shape=(4, 4)), ) noisy_zop_b = NoisyOperation( - circuit=cirq.Circuit(cirq.Z(q)), channel_matrix=np.ones(shape=(4, 4)), + circuit=cirq.Circuit(cirq.Z(q)), + channel_matrix=np.ones(shape=(4, 4)), ) rep_b = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_xop_b: 0.5, noisy_zop_b: 0.5}, + ideal=ideal, + basis_expansion={noisy_xop_b: 0.5, noisy_zop_b: 0.5}, ) # Equal representation up to real superoperators assert rep_a == rep_b # Different ideal ideal_b = cirq.Circuit(cirq.X(q)) rep_b = OperationRepresentation( - ideal=ideal_b, basis_expansion={noisy_xop_b: 0.5, noisy_zop_b: 0.5}, + ideal=ideal_b, + basis_expansion={noisy_xop_b: 0.5, noisy_zop_b: 0.5}, ) assert rep_a != rep_b # Different type @@ -854,22 +882,26 @@ def test_equal_method_of_representations(): ideal_b = qiskit.QuantumCircuit(q_b) ideal_b.x(q_b) rep_b = OperationRepresentation( - ideal=ideal_b, basis_expansion={noisy_xop_b: 0.5, noisy_zop_b: 0.5}, + ideal=ideal_b, + basis_expansion={noisy_xop_b: 0.5, noisy_zop_b: 0.5}, ) assert rep_a != rep_b # Different length rep_b = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_xop_b: 0.5}, + ideal=ideal, + basis_expansion={noisy_xop_b: 0.5}, ) assert rep_a != rep_b # Different operations noisy_diff = NoisyOperation(circuit=cirq.Circuit(cirq.H(q))) rep_b = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_xop_b: 0.5, noisy_diff: 0.5}, + ideal=ideal, + basis_expansion={noisy_xop_b: 0.5, noisy_diff: 0.5}, ) assert rep_a != rep_b # Different coefficients rep_b = OperationRepresentation( - ideal=ideal, basis_expansion={noisy_xop_b: 0.7, noisy_zop_b: 0.5}, + ideal=ideal, + basis_expansion={noisy_xop_b: 0.7, noisy_zop_b: 0.5}, ) assert rep_a != rep_b diff --git a/mitiq/pec/types/types.py b/mitiq/pec/types/types.py index 84b7feef0a..2b1834cc4e 100644 --- a/mitiq/pec/types/types.py +++ b/mitiq/pec/types/types.py @@ -112,15 +112,15 @@ def _init_from_cirq( self._qubits = tuple(self._circuit.all_qubits()) self._num_qubits = len(self._qubits) - self._dimension = 2 ** self._num_qubits + self._dimension = 2**self._num_qubits if channel_matrix is None: self._channel_matrix = None return if channel_matrix.shape != ( - self._dimension ** 2, - self._dimension ** 2, + self._dimension**2, + self._dimension**2, ): raise ValueError( f"Arg `channel_matrix` has shape {channel_matrix.shape}" @@ -175,7 +175,8 @@ def on_each( noisy_ops = [] # type: List[NoisyOperation] base_circuit = NoisyOperation.from_cirq( - circuit, channel_matrix, + circuit, + channel_matrix, )._circuit base_qubits = list(base_circuit.all_qubits()) @@ -196,7 +197,9 @@ def extend_to( self, qubits: Sequence[List[cirq.Qid]] ) -> Sequence["NoisyOperation"]: return [self] + NoisyOperation.on_each( - self._circuit, qubits, self._channel_matrix, + self._circuit, + qubits, + self._channel_matrix, ) @staticmethod diff --git a/mitiq/rem/tests/test_post_select.py b/mitiq/rem/tests/test_post_select.py index e64478160a..aa4a258bf9 100644 --- a/mitiq/rem/tests/test_post_select.py +++ b/mitiq/rem/tests/test_post_select.py @@ -39,7 +39,10 @@ def test_post_select_inverted(): assert post_select(res, lambda bits: sum(bits) == 1).result == [[0, 0, 1]] assert post_select( res, lambda bits: sum(bits) == 1, inverted=True - ).result == [[1, 1, 0], [0, 0, 0],] + ).result == [ + [1, 1, 0], + [0, 0, 0], + ] assert post_select(res, lambda bits: sum(bits) == 3).result == [] assert ( diff --git a/mitiq/tests/test_utils.py b/mitiq/tests/test_utils.py index 8766b46bf1..d61bf9b05f 100644 --- a/mitiq/tests/test_utils.py +++ b/mitiq/tests/test_utils.py @@ -256,7 +256,7 @@ def test_pop_measurements_and_add_measurements(): assert _equal(copy, circ) -@pytest.mark.parametrize("gate", [X ** 3, Y ** -3, Z ** -1, H ** -1]) +@pytest.mark.parametrize("gate", [X**3, Y**-3, Z**-1, H**-1]) def test_simplify_gate_exponent(gate): # Check exponent is simplified to 1 assert _simplify_gate_exponent(gate).exponent == 1 @@ -264,7 +264,7 @@ def test_simplify_gate_exponent(gate): assert _simplify_gate_exponent(gate) == gate -@pytest.mark.parametrize("gate", [T ** -1, S ** -1, MeasurementGate(1)]) +@pytest.mark.parametrize("gate", [T**-1, S**-1, MeasurementGate(1)]) def test_simplify_gate_exponent_with_gates_that_cannot_be_simplified(gate): # Check the gate is not simplified (same representation) assert _simplify_gate_exponent(gate).__repr__() == gate.__repr__() @@ -375,7 +375,7 @@ def test_circuit_to_choi_and_operation_to_choi(): choi_twice = sum( [ ((1.0 - epsilon) ** 2 * identity_part), - (2 * epsilon - epsilon ** 2) * mixed_part, + (2 * epsilon - epsilon**2) * mixed_part, ] ) diff --git a/mitiq/utils.py b/mitiq/utils.py index 5155bebd3c..067a6adb65 100644 --- a/mitiq/utils.py +++ b/mitiq/utils.py @@ -90,7 +90,9 @@ def _is_measurement(op: ops.Operation) -> bool: return isinstance(op.gate, ops.measurement_gate.MeasurementGate) -def _pop_measurements(circuit: Circuit,) -> List[Tuple[int, ops.Operation]]: +def _pop_measurements( + circuit: Circuit, +) -> List[Tuple[int, ops.Operation]]: """Removes all measurements from a circuit. Args: diff --git a/mitiq/zne/inference.py b/mitiq/zne/inference.py index 52925aa136..470804cc7b 100644 --- a/mitiq/zne/inference.py +++ b/mitiq/zne/inference.py @@ -324,7 +324,8 @@ def run( @abstractmethod def run_classical( - self, scale_factor_to_expectation_value: Callable[..., float], + self, + scale_factor_to_expectation_value: Callable[..., float], ) -> "Factory": """Calls the function scale_factor_to_expectation_value at each scale factor of the factory, and stores the results. diff --git a/mitiq/zne/scaling/folding.py b/mitiq/zne/scaling/folding.py index 69499497ae..f9e6da894c 100644 --- a/mitiq/zne/scaling/folding.py +++ b/mitiq/zne/scaling/folding.py @@ -307,7 +307,8 @@ def fold_global( def _create_weight_mask( - circuit: Circuit, fidelities: Optional[Dict[str, float]], + circuit: Circuit, + fidelities: Optional[Dict[str, float]], ) -> List[float]: """Returns a list of weights associated to each gate if the input circuit. Measurement gates are ignored. @@ -734,7 +735,10 @@ def fold_gates_at_random( weight_mask = _create_weight_mask(circuit, kwargs.get("fidelities")) num_folds_mask = _create_fold_mask( - weight_mask, scale_factor, folding_method="at_random", seed=seed, + weight_mask, + scale_factor, + folding_method="at_random", + seed=seed, ) return _apply_fold_mask( diff --git a/mitiq/zne/scaling/tests/test_folding.py b/mitiq/zne/scaling/tests/test_folding.py index 08408d9fef..ca79980ac1 100644 --- a/mitiq/zne/scaling/tests/test_folding.py +++ b/mitiq/zne/scaling/tests/test_folding.py @@ -671,14 +671,18 @@ def test_fold_gates_at_random_seed_one_qubit(): # Medium scale, fold two gates folded = fold_gates_at_random(circuit, scale_factor=2.5, seed=2) correct = Circuit( - [ops.X.on(qubit)], [ops.Y.on(qubit)] * 3, [ops.Z.on(qubit)] * 3, + [ops.X.on(qubit)], + [ops.Y.on(qubit)] * 3, + [ops.Z.on(qubit)] * 3, ) assert _equal(folded, correct) # Max scale, fold three gates folded = fold_gates_at_random(circuit, scale_factor=3, seed=3) correct = Circuit( - [ops.X.on(qubit)] * 3, [ops.Y.on(qubit)] * 3, [ops.Z.on(qubit)] * 3, + [ops.X.on(qubit)] * 3, + [ops.Y.on(qubit)] * 3, + [ops.Z.on(qubit)] * 3, ) assert _equal(folded, correct) @@ -956,7 +960,12 @@ def test_global_fold_stretch_factor_eight_terminal_measurements(): circ, inverse(circ), circ, - inverse(Circuit([ops.T.on(qreg[2])], [ops.TOFFOLI.on(*qreg)],)), + inverse( + Circuit( + [ops.T.on(qreg[2])], + [ops.TOFFOLI.on(*qreg)], + ) + ), [ops.T.on(qreg[2])], [ops.TOFFOLI.on(*qreg)], meas, @@ -1257,10 +1266,16 @@ def test_fold_and_squash_random_circuits_random_stretches(fold_method): ) scale = 2 * rng.random() + 1 folded_not_squashed = fold_method( - circuit, scale_factor=scale, squash_moments=False, seed=trial, + circuit, + scale_factor=scale, + squash_moments=False, + seed=trial, ) folded_and_squashed = fold_method( - circuit, scale_factor=scale, squash_moments=True, seed=trial, + circuit, + scale_factor=scale, + squash_moments=True, + seed=trial, ) assert len(folded_and_squashed) <= len(folded_not_squashed) @@ -1310,7 +1325,8 @@ def test_fold_local_with_fidelities(fold_method, qiskit): ) @pytest.mark.parametrize("qiskit", [True, False]) def test_fold_local_with_single_qubit_gates_fidelity_one(fold_method, qiskit): - """Tests folding only two-qubit gates by using fidelities = {"single": 1.}. + """Tests folding only two-qubit gates by using + fidelities = {"single": 1.}. """ qreg = LineQubit.range(3) circ = Circuit( @@ -1535,7 +1551,9 @@ def test_create_weight_mask_with_fidelities(): @pytest.mark.parametrize("scale_factor", (1, 3, 5, 7, 9, 11)) @pytest.mark.parametrize("method", ("at_random", "from_left", "from_right")) def test_create_fold_mask_with_odd_scale_factors( - weight_mask, scale_factor, method, + weight_mask, + scale_factor, + method, ): fold_mask = _create_fold_mask(weight_mask, scale_factor, method) num_folds = int((scale_factor - 1) / 2) @@ -1644,7 +1662,10 @@ def test_create_fold_mask_approximates_well(method): weight_mask = [rnd_state.rand() for _ in range(100)] seed = rnd_state.randint(100) fold_mask = _create_fold_mask( - weight_mask, scale_factor, folding_method=method, seed=seed, + weight_mask, + scale_factor, + folding_method=method, + seed=seed, ) out_weights = [w + 2 * n * w for w, n in zip(weight_mask, fold_mask)] actual_scale = sum(out_weights) / sum(weight_mask) @@ -1711,7 +1732,9 @@ def test_apply_fold_mask_with_squash_moments_option(): # # 1: ───T────H─── q = LineQubit.range(2) - circ = Circuit([ops.T.on_each(*q), ops.H(q[1])],) + circ = Circuit( + [ops.T.on_each(*q), ops.H(q[1])], + ) folded = _apply_fold_mask(circ, [1, 0, 0], squash_moments=False) # 0: ───T───T^-1───T─────── # diff --git a/mitiq/zne/tests/test_inference.py b/mitiq/zne/tests/test_inference.py index 5a52d9f5d5..8f4200712d 100644 --- a/mitiq/zne/tests/test_inference.py +++ b/mitiq/zne/tests/test_inference.py @@ -83,7 +83,7 @@ def f_non_lin( x: float, err: float = STAT_NOISE, rnd_state: RandomState = np.random ) -> float: """Non-linear function.""" - return A + B * x + C * x ** 2 + rnd_state.normal(scale=err) + return A + B * x + C * x**2 + rnd_state.normal(scale=err) def f_exp_down( @@ -104,14 +104,14 @@ def f_poly_exp_down( x: float, err: float = STAT_NOISE, rnd_state: RandomState = np.random ) -> float: """Poly-exponential decay.""" - return A + B * np.exp(-C * x - D * x ** 2) + rnd_state.normal(scale=err) + return A + B * np.exp(-C * x - D * x**2) + rnd_state.normal(scale=err) def f_poly_exp_up( x: float, err: float = STAT_NOISE, rnd_state: RandomState = np.random ) -> float: """Poly-exponential growth.""" - return A - B * np.exp(-C * x - D * x ** 2) + rnd_state.normal(scale=err) + return A - B * np.exp(-C * x - D * x**2) + rnd_state.normal(scale=err) def f_lin_shot(x: float, shots=1) -> float: @@ -321,7 +321,8 @@ def test_richardson_extr(test_f: Callable[[float], float]): exp_vals = fac.get_expectation_values() assert np.isclose(fac.extrapolate(X_VALS, exp_vals), zne_value) assert np.isclose( - fac.extrapolate(X_VALS, exp_vals, full_output=True)[0], zne_value, + fac.extrapolate(X_VALS, exp_vals, full_output=True)[0], + zne_value, ) @@ -342,7 +343,8 @@ def test_fake_nodes_factory(): exp_vals = fac.get_expectation_values() assert np.isclose(fac.extrapolate(UNIFORM_X, exp_vals), zne_value) assert np.isclose( - fac.extrapolate(UNIFORM_X, exp_vals, full_output=True)[0], zne_value, + fac.extrapolate(UNIFORM_X, exp_vals, full_output=True)[0], + zne_value, ) @@ -372,7 +374,8 @@ def test_linear_extr(): exp_vals = fac.get_expectation_values() assert np.isclose(fac.extrapolate(X_VALS, exp_vals), zne_value) assert np.isclose( - fac.extrapolate(X_VALS, exp_vals, full_output=True)[0], zne_value, + fac.extrapolate(X_VALS, exp_vals, full_output=True)[0], + zne_value, ) @@ -464,7 +467,8 @@ def test_exp_factory_no_asympt(test_f: Callable[[float], float]): exp_vals = fac.get_expectation_values() assert np.isclose(fac.extrapolate(X_VALS, exp_vals), zne_value) assert np.isclose( - fac.extrapolate(X_VALS, exp_vals, full_output=True)[0], zne_value, + fac.extrapolate(X_VALS, exp_vals, full_output=True)[0], + zne_value, ) @@ -519,7 +523,12 @@ def test_poly_exp_factory_no_asympt(test_f: Callable[[float], float]): exp_vals = fac.get_expectation_values() assert np.isclose(fac.extrapolate(X_VALS, exp_vals, order=2), zne_value) assert np.isclose( - fac.extrapolate(X_VALS, exp_vals, order=2, full_output=True,)[0], + fac.extrapolate( + X_VALS, + exp_vals, + order=2, + full_output=True, + )[0], zne_value, ) @@ -551,8 +560,7 @@ def test_ada_exp_factory_with_asympt( def test_ada_exp_fac_with_asympt_more_steps( test_f: Callable[[float], float], avoid_log: bool ): - """Test of the adaptive exponential extrapolator with more steps. - """ + """Test of the adaptive exponential extrapolator with more steps.""" seeded_f = apply_seed_to_func(test_f, SEED) fac = AdaExpFactory( steps=6, scale_factor=2.0, asymptote=A, avoid_log=avoid_log @@ -854,7 +862,12 @@ def test_get_methods_of_factories(): @mark.parametrize( - "factory", (LinearFactory, RichardsonFactory, PolyFactory,), + "factory", + ( + LinearFactory, + RichardsonFactory, + PolyFactory, + ), ) def test_plot_data(factory): """Test that plot_data() outputs the correct x and y values.""" @@ -890,7 +903,12 @@ def test_plot_data_exp_factory(factory): @mark.parametrize( - "factory", (LinearFactory, RichardsonFactory, PolyFactory,), + "factory", + ( + LinearFactory, + RichardsonFactory, + PolyFactory, + ), ) def test_plot_fit(factory): """Test that plot_fit() outputs the correct x and y values.""" @@ -939,7 +957,8 @@ def test_map_to_fakenodes(): fac = FakeNodesFactory(UNIFORM_X) test_argument = 1.0 assert np.isclose( - fac._map_to_fake_nodes([1.0], 2.0, test_argument), [1.0], + fac._map_to_fake_nodes([1.0], 2.0, test_argument), + [1.0], ) @@ -973,7 +992,8 @@ def executor(circuits) -> List[float]: circuit = cirq.Circuit(X(qubit), H(qubit), X(qubit)) with warns( - UserWarning, match=r"The input circuit is very short.", + UserWarning, + match=r"The input circuit is very short.", ): fac.run(circuit, executor, scale_noise=lambda circ, _: circ) diff --git a/mitiq/zne/tests/test_zne.py b/mitiq/zne/tests/test_zne.py index 4f7954a3a5..9f442b0992 100644 --- a/mitiq/zne/tests/test_zne.py +++ b/mitiq/zne/tests/test_zne.py @@ -348,7 +348,9 @@ def test_qiskit_run_factory_with_number_of_shots(): shot_list = [10_000, 30_000] fac = inference.ExpFactory( - scale_factors=scale_factors, shot_list=shot_list, asymptote=0.5, + scale_factors=scale_factors, + shot_list=shot_list, + asymptote=0.5, ) circuit = qiskit_measure( @@ -362,7 +364,9 @@ def test_qiskit_run_factory_with_number_of_shots(): ) base = qiskit_executor(circuit) zne_value = fac.run( - circuit, qiskit_executor, scale_noise=scaling.fold_gates_at_random, + circuit, + qiskit_executor, + scale_noise=scaling.fold_gates_at_random, ).reduce() assert abs(true_zne_value - zne_value) < abs(true_zne_value - base) @@ -381,7 +385,9 @@ def test_qiskit_mitigate_executor_with_shot_list(): shot_list = [10_000, 30_000] fac = inference.ExpFactory( - scale_factors=scale_factors, shot_list=shot_list, asymptote=0.5, + scale_factors=scale_factors, + shot_list=shot_list, + asymptote=0.5, ) mitigated_executor = mitigate_executor(qiskit_executor, factory=fac)