From 99ee9ace8a4bbd735e2da5eda212e31c97617f8b Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Mon, 16 Sep 2019 10:34:17 -0700 Subject: [PATCH 01/21] XEB fidelity estimator for large circuits --- cirq/__init__.py | 1 + cirq/experiments/__init__.py | 3 + cirq/experiments/fidelity_estimation.py | 51 +++++++++++++++++ cirq/experiments/fidelity_estimation_test.py | 59 ++++++++++++++++++++ 4 files changed, 114 insertions(+) create mode 100644 cirq/experiments/fidelity_estimation.py create mode 100644 cirq/experiments/fidelity_estimation_test.py diff --git a/cirq/__init__.py b/cirq/__init__.py index 3963baaec5e..bfc9ce62b87 100644 --- a/cirq/__init__.py +++ b/cirq/__init__.py @@ -85,6 +85,7 @@ ) from cirq.experiments import ( + estimate_circuit_fidelity, generate_supremacy_circuit_google_v2, generate_supremacy_circuit_google_v2_bristlecone, generate_supremacy_circuit_google_v2_grid, diff --git a/cirq/experiments/__init__.py b/cirq/experiments/__init__.py index f0a21e259b5..27cf10d7978 100644 --- a/cirq/experiments/__init__.py +++ b/cirq/experiments/__init__.py @@ -16,3 +16,6 @@ build_entangling_layers, cross_entropy_benchmarking, ) + +from cirq.experiments.fidelity_estimation import ( + estimate_circuit_fidelity,) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py new file mode 100644 index 00000000000..d2366de9c8e --- /dev/null +++ b/cirq/experiments/fidelity_estimation.py @@ -0,0 +1,51 @@ +"""Estimate fidelity of large random quantum circuit from observed bitstrings. + +Fidelity estimator defined here is used in cross-entropy benchmarking and +works under the assumption that the evaluated circuit is sufficiently +random, see https://arxiv.org/abs/1608.00263. +""" + +from typing import cast, List, Sequence, Tuple + +import numpy as np + +from cirq.circuits import Circuit +from cirq.ops import Qid +from cirq.sim import Simulator, WaveFunctionTrialResult + + +def estimate_circuit_fidelity(circuit: Circuit, qubit_order: Sequence[Qid], + bitstrings: Sequence[int]) -> float: + """Computes fidelity estimate from one circuit using linear XEB estimator. + + Args: + circuit: Random quantum circuit which has been executed on quantum + processor under test + qubit_order: Qubit order used to construct bitstrings from measurements + bitstrings: Results of terminal all-qubit measurements performed after + each circuit execution + Returns: + Estimate of circuit fidelity. + Raises: + ValueError: Circuit is inconsistent with qubit order or one of the + bitstrings is inconsistent with the number of qubits. + """ + dim = 2**len(qubit_order) + + if set(qubit_order) != circuit.all_qubits(): + raise ValueError( + f'Inconsistent qubits: circuit has {circuit.all_qubits()}, ' + f'qubit order is {qubit_order}') + for bitstring in bitstrings: + if bitstring < 0 or dim <= bitstring: + raise ValueError( + f'Bitstring {bitstring} could not have been observed ' + f'on {len(qubit_order)} qubits.') + + simulator = Simulator() + result = cast(WaveFunctionTrialResult, + simulator.simulate(circuit, qubit_order=qubit_order)) + output_probabilities = np.abs(result.final_state)**2 + assert 1 - 1e-4 < np.sum(output_probabilities) < 1 + 1e-4 + fidelity_estimate = dim * np.mean(output_probabilities[bitstrings]) - 1 + return fidelity_estimate diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py new file mode 100644 index 00000000000..f134a5d38b9 --- /dev/null +++ b/cirq/experiments/fidelity_estimation_test.py @@ -0,0 +1,59 @@ +from typing import Sequence + +import numpy as np +import pytest + +import cirq + + +def make_bitstrings(samples: np.ndarray) -> Sequence[int]: + assert samples.shape[1] == 2 + return [2 * b1 + b0 for b1, b0 in samples] + + +def sample_noisy_bitstrings(circuit: cirq.Circuit, depolarization: float, + n_samples: int) -> Sequence[int]: + assert 0 <= depolarization <= 1 + n_incoherent = int(depolarization * n_samples) + n_coherent = n_samples - n_incoherent + incoherent_samples = np.random.randint(2, size=(n_incoherent, 2)) + if n_coherent > 0: + sim = cirq.Simulator() + r = sim.run(circuit, repetitions=n_coherent) + coherent_samples = r.measurements['0,1'] + all_samples = np.concatenate((coherent_samples, incoherent_samples)) + return make_bitstrings(all_samples) + return make_bitstrings(incoherent_samples) + + +@pytest.mark.parametrize('depolarization', (0, 0.25, 0.5, 0.75, 1.0)) +def test_estimate_circuit_fidelity(depolarization): + prng_state = np.random.get_state() + np.random.seed(0) + + q0, q1 = cirq.LineQubit.range(2) + circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), + cirq.measure(q0, q1)) + bitstrings = sample_noisy_bitstrings(circuit, depolarization, 10000) + f = cirq.estimate_circuit_fidelity(circuit, (q0, q1), bitstrings) + assert np.isclose(f, 1 - depolarization, atol=0.026) + + np.random.set_state(prng_state) + + +def test_estimate_circuit_fidelity_invalid_qubits(): + q0, q1, q2 = cirq.LineQubit.range(3) + circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), + cirq.measure(q0, q1)) + bitstrings = sample_noisy_bitstrings(circuit, 0.9, 10) + with pytest.raises(ValueError): + cirq.estimate_circuit_fidelity(circuit, (q0, q1, q2), bitstrings) + + +def test_estimate_circuit_fidelity_invalid_bitstrings(): + q0, q1 = cirq.LineQubit.range(2) + circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), + cirq.measure(q0, q1)) + bitstrings = [0, 1, 2, 3, 4] + with pytest.raises(ValueError): + cirq.estimate_circuit_fidelity(circuit, (q0, q1), bitstrings) From e77ac0b2b7c64ece3fb7d6ef53001a135b84a95a Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Tue, 17 Sep 2019 14:24:17 -0700 Subject: [PATCH 02/21] Rename s/estimate_circuit_fidelity/compute_linear_xeb_fidelity/ --- cirq/__init__.py | 2 +- cirq/experiments/__init__.py | 2 +- cirq/experiments/fidelity_estimation.py | 4 ++-- cirq/experiments/fidelity_estimation_test.py | 12 ++++++------ 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cirq/__init__.py b/cirq/__init__.py index bfc9ce62b87..ca43ecac410 100644 --- a/cirq/__init__.py +++ b/cirq/__init__.py @@ -85,7 +85,7 @@ ) from cirq.experiments import ( - estimate_circuit_fidelity, + compute_linear_xeb_fidelity, generate_supremacy_circuit_google_v2, generate_supremacy_circuit_google_v2_bristlecone, generate_supremacy_circuit_google_v2_grid, diff --git a/cirq/experiments/__init__.py b/cirq/experiments/__init__.py index 27cf10d7978..6ee8f091f3f 100644 --- a/cirq/experiments/__init__.py +++ b/cirq/experiments/__init__.py @@ -18,4 +18,4 @@ ) from cirq.experiments.fidelity_estimation import ( - estimate_circuit_fidelity,) + compute_linear_xeb_fidelity,) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index d2366de9c8e..be643c6a52b 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -14,8 +14,8 @@ from cirq.sim import Simulator, WaveFunctionTrialResult -def estimate_circuit_fidelity(circuit: Circuit, qubit_order: Sequence[Qid], - bitstrings: Sequence[int]) -> float: +def compute_linear_xeb_fidelity(circuit: Circuit, qubit_order: Sequence[Qid], + bitstrings: Sequence[int]) -> float: """Computes fidelity estimate from one circuit using linear XEB estimator. Args: diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index f134a5d38b9..54fab5c9b39 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -27,7 +27,7 @@ def sample_noisy_bitstrings(circuit: cirq.Circuit, depolarization: float, @pytest.mark.parametrize('depolarization', (0, 0.25, 0.5, 0.75, 1.0)) -def test_estimate_circuit_fidelity(depolarization): +def test_compute_linear_xeb_fidelity(depolarization): prng_state = np.random.get_state() np.random.seed(0) @@ -35,25 +35,25 @@ def test_estimate_circuit_fidelity(depolarization): circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), cirq.measure(q0, q1)) bitstrings = sample_noisy_bitstrings(circuit, depolarization, 10000) - f = cirq.estimate_circuit_fidelity(circuit, (q0, q1), bitstrings) + f = cirq.compute_linear_xeb_fidelity(circuit, (q0, q1), bitstrings) assert np.isclose(f, 1 - depolarization, atol=0.026) np.random.set_state(prng_state) -def test_estimate_circuit_fidelity_invalid_qubits(): +def test_compute_linear_xeb_fidelity_invalid_qubits(): q0, q1, q2 = cirq.LineQubit.range(3) circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), cirq.measure(q0, q1)) bitstrings = sample_noisy_bitstrings(circuit, 0.9, 10) with pytest.raises(ValueError): - cirq.estimate_circuit_fidelity(circuit, (q0, q1, q2), bitstrings) + cirq.compute_linear_xeb_fidelity(circuit, (q0, q1, q2), bitstrings) -def test_estimate_circuit_fidelity_invalid_bitstrings(): +def test_compute_linear_xeb_fidelity_invalid_bitstrings(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), cirq.measure(q0, q1)) bitstrings = [0, 1, 2, 3, 4] with pytest.raises(ValueError): - cirq.estimate_circuit_fidelity(circuit, (q0, q1), bitstrings) + cirq.compute_linear_xeb_fidelity(circuit, (q0, q1), bitstrings) From 10c37762a2fc104b24137a5a679ba9973fc90eba Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Tue, 17 Sep 2019 14:30:08 -0700 Subject: [PATCH 03/21] Default qubit order --- cirq/experiments/fidelity_estimation.py | 9 ++++++--- cirq/experiments/fidelity_estimation_test.py | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index be643c6a52b..2c6d3479e20 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -10,12 +10,15 @@ import numpy as np from cirq.circuits import Circuit -from cirq.ops import Qid +from cirq.ops import Qid, QubitOrder, QubitOrderOrList from cirq.sim import Simulator, WaveFunctionTrialResult -def compute_linear_xeb_fidelity(circuit: Circuit, qubit_order: Sequence[Qid], - bitstrings: Sequence[int]) -> float: +def compute_linear_xeb_fidelity( + circuit: Circuit, + bitstrings: Sequence[int], + qubit_order: QubitOrderOrList = QubitOrder.DEFAULT, +) -> float: """Computes fidelity estimate from one circuit using linear XEB estimator. Args: diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index 54fab5c9b39..c9fab4bd637 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -35,7 +35,7 @@ def test_compute_linear_xeb_fidelity(depolarization): circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), cirq.measure(q0, q1)) bitstrings = sample_noisy_bitstrings(circuit, depolarization, 10000) - f = cirq.compute_linear_xeb_fidelity(circuit, (q0, q1), bitstrings) + f = cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q1)) assert np.isclose(f, 1 - depolarization, atol=0.026) np.random.set_state(prng_state) @@ -47,7 +47,7 @@ def test_compute_linear_xeb_fidelity_invalid_qubits(): cirq.measure(q0, q1)) bitstrings = sample_noisy_bitstrings(circuit, 0.9, 10) with pytest.raises(ValueError): - cirq.compute_linear_xeb_fidelity(circuit, (q0, q1, q2), bitstrings) + cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q1, q2)) def test_compute_linear_xeb_fidelity_invalid_bitstrings(): @@ -56,4 +56,4 @@ def test_compute_linear_xeb_fidelity_invalid_bitstrings(): cirq.measure(q0, q1)) bitstrings = [0, 1, 2, 3, 4] with pytest.raises(ValueError): - cirq.compute_linear_xeb_fidelity(circuit, (q0, q1), bitstrings) + cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q1)) From b26aeba76ab8b2895e1375e90c794c44d7657e8f Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Tue, 17 Sep 2019 14:32:05 -0700 Subject: [PATCH 04/21] Qudits --- cirq/experiments/fidelity_estimation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index 2c6d3479e20..b97b43d300d 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -33,7 +33,7 @@ def compute_linear_xeb_fidelity( ValueError: Circuit is inconsistent with qubit order or one of the bitstrings is inconsistent with the number of qubits. """ - dim = 2**len(qubit_order) + dim = np.product(circuit.qid_shape()) if set(qubit_order) != circuit.all_qubits(): raise ValueError( From cbb3a99375b5b3fe72db37738b0c7502e3d3e0a5 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Tue, 17 Sep 2019 14:33:28 -0700 Subject: [PATCH 05/21] Idiomatic python --- cirq/experiments/fidelity_estimation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index b97b43d300d..c2edab719e5 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -40,7 +40,7 @@ def compute_linear_xeb_fidelity( f'Inconsistent qubits: circuit has {circuit.all_qubits()}, ' f'qubit order is {qubit_order}') for bitstring in bitstrings: - if bitstring < 0 or dim <= bitstring: + if not 0 <= bitstring < dim: raise ValueError( f'Bitstring {bitstring} could not have been observed ' f'on {len(qubit_order)} qubits.') From 745f244bf3f26c7f7cae5b458b0fcaecf8cf74e1 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Tue, 17 Sep 2019 14:38:25 -0700 Subject: [PATCH 06/21] final_wavefunction --- cirq/experiments/fidelity_estimation.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index c2edab719e5..1ff4a269f1d 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -11,7 +11,7 @@ from cirq.circuits import Circuit from cirq.ops import Qid, QubitOrder, QubitOrderOrList -from cirq.sim import Simulator, WaveFunctionTrialResult +from cirq.sim import final_wavefunction def compute_linear_xeb_fidelity( @@ -45,10 +45,8 @@ def compute_linear_xeb_fidelity( f'Bitstring {bitstring} could not have been observed ' f'on {len(qubit_order)} qubits.') - simulator = Simulator() - result = cast(WaveFunctionTrialResult, - simulator.simulate(circuit, qubit_order=qubit_order)) - output_probabilities = np.abs(result.final_state)**2 + output_state = final_wavefunction(circuit, qubit_order=qubit_order) + output_probabilities = np.abs(output_state)**2 assert 1 - 1e-4 < np.sum(output_probabilities) < 1 + 1e-4 fidelity_estimate = dim * np.mean(output_probabilities[bitstrings]) - 1 return fidelity_estimate From d27fe3f135c0c7cd78356d0dc5a443333692fc1c Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Tue, 17 Sep 2019 15:22:06 -0700 Subject: [PATCH 07/21] Use r.data --- cirq/experiments/fidelity_estimation.py | 4 ++-- cirq/experiments/fidelity_estimation_test.py | 23 +++++++++----------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index 1ff4a269f1d..864dac53b31 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -5,7 +5,7 @@ random, see https://arxiv.org/abs/1608.00263. """ -from typing import cast, List, Sequence, Tuple +from typing import cast, Iterable, Tuple, Set import numpy as np @@ -16,7 +16,7 @@ def compute_linear_xeb_fidelity( circuit: Circuit, - bitstrings: Sequence[int], + bitstrings: np.ndarray, qubit_order: QubitOrderOrList = QubitOrder.DEFAULT, ) -> float: """Computes fidelity estimate from one circuit using linear XEB estimator. diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index c9fab4bd637..9d27dd5e775 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -5,25 +5,22 @@ import cirq - -def make_bitstrings(samples: np.ndarray) -> Sequence[int]: - assert samples.shape[1] == 2 - return [2 * b1 + b0 for b1, b0 in samples] +MEASUREMENT_KEY = 'm' def sample_noisy_bitstrings(circuit: cirq.Circuit, depolarization: float, - n_samples: int) -> Sequence[int]: + n_samples: int) -> np.ndarray: assert 0 <= depolarization <= 1 + dim = np.product(circuit.qid_shape()) n_incoherent = int(depolarization * n_samples) n_coherent = n_samples - n_incoherent - incoherent_samples = np.random.randint(2, size=(n_incoherent, 2)) + incoherent_samples = np.random.randint(dim, size=n_incoherent) if n_coherent > 0: sim = cirq.Simulator() r = sim.run(circuit, repetitions=n_coherent) - coherent_samples = r.measurements['0,1'] - all_samples = np.concatenate((coherent_samples, incoherent_samples)) - return make_bitstrings(all_samples) - return make_bitstrings(incoherent_samples) + coherent_samples = r.data[MEASUREMENT_KEY].to_numpy() + return np.concatenate((coherent_samples, incoherent_samples)) + return incoherent_samples @pytest.mark.parametrize('depolarization', (0, 0.25, 0.5, 0.75, 1.0)) @@ -33,7 +30,7 @@ def test_compute_linear_xeb_fidelity(depolarization): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), - cirq.measure(q0, q1)) + cirq.measure(q0, q1, key=MEASUREMENT_KEY)) bitstrings = sample_noisy_bitstrings(circuit, depolarization, 10000) f = cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q1)) assert np.isclose(f, 1 - depolarization, atol=0.026) @@ -44,7 +41,7 @@ def test_compute_linear_xeb_fidelity(depolarization): def test_compute_linear_xeb_fidelity_invalid_qubits(): q0, q1, q2 = cirq.LineQubit.range(3) circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), - cirq.measure(q0, q1)) + cirq.measure(q0, q1, key=MEASUREMENT_KEY)) bitstrings = sample_noisy_bitstrings(circuit, 0.9, 10) with pytest.raises(ValueError): cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q1, q2)) @@ -53,7 +50,7 @@ def test_compute_linear_xeb_fidelity_invalid_qubits(): def test_compute_linear_xeb_fidelity_invalid_bitstrings(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), - cirq.measure(q0, q1)) + cirq.measure(q0, q1, key=MEASUREMENT_KEY)) bitstrings = [0, 1, 2, 3, 4] with pytest.raises(ValueError): cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q1)) From bb0623e170638ae5d2769163c11cf511317f6345 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Tue, 17 Sep 2019 15:24:11 -0700 Subject: [PATCH 08/21] Skip circuit vs qubit order check: simulator raises anyway --- cirq/experiments/fidelity_estimation.py | 4 ---- cirq/experiments/fidelity_estimation_test.py | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index 864dac53b31..3c392d5f365 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -35,10 +35,6 @@ def compute_linear_xeb_fidelity( """ dim = np.product(circuit.qid_shape()) - if set(qubit_order) != circuit.all_qubits(): - raise ValueError( - f'Inconsistent qubits: circuit has {circuit.all_qubits()}, ' - f'qubit order is {qubit_order}') for bitstring in bitstrings: if not 0 <= bitstring < dim: raise ValueError( diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index 9d27dd5e775..d25934a7abf 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -44,7 +44,7 @@ def test_compute_linear_xeb_fidelity_invalid_qubits(): cirq.measure(q0, q1, key=MEASUREMENT_KEY)) bitstrings = sample_noisy_bitstrings(circuit, 0.9, 10) with pytest.raises(ValueError): - cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q1, q2)) + cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q2)) def test_compute_linear_xeb_fidelity_invalid_bitstrings(): From e01d7b502516cef71365956a2eecaff9a0a853fd Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Tue, 17 Sep 2019 15:25:36 -0700 Subject: [PATCH 09/21] mypy --- cirq/experiments/fidelity_estimation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index 3c392d5f365..d01a25de2cb 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -39,7 +39,7 @@ def compute_linear_xeb_fidelity( if not 0 <= bitstring < dim: raise ValueError( f'Bitstring {bitstring} could not have been observed ' - f'on {len(qubit_order)} qubits.') + f'on {len(circuit.qid_shape())} qubits.') output_state = final_wavefunction(circuit, qubit_order=qubit_order) output_probabilities = np.abs(output_state)**2 From 4d3b857ec5a3d8b0d754babf09d786812be29ceb Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Tue, 17 Sep 2019 15:26:58 -0700 Subject: [PATCH 10/21] Remove assert --- cirq/experiments/fidelity_estimation.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index d01a25de2cb..d3b2e82e544 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -43,6 +43,4 @@ def compute_linear_xeb_fidelity( output_state = final_wavefunction(circuit, qubit_order=qubit_order) output_probabilities = np.abs(output_state)**2 - assert 1 - 1e-4 < np.sum(output_probabilities) < 1 + 1e-4 - fidelity_estimate = dim * np.mean(output_probabilities[bitstrings]) - 1 - return fidelity_estimate + return dim * np.mean(output_probabilities[bitstrings]) - 1 From 34b517157c892081e49c2ddb9efa9b6aa63de15a Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Tue, 17 Sep 2019 16:34:44 -0700 Subject: [PATCH 11/21] Improve comments --- cirq/experiments/fidelity_estimation.py | 36 +++++++++++++++++++------ 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index d3b2e82e544..b2f697129ca 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -1,9 +1,4 @@ -"""Estimate fidelity of large random quantum circuit from observed bitstrings. - -Fidelity estimator defined here is used in cross-entropy benchmarking and -works under the assumption that the evaluated circuit is sufficiently -random, see https://arxiv.org/abs/1608.00263. -""" +"""Estimation of fidelity associated with experimental circuit executions.""" from typing import cast, Iterable, Tuple, Set @@ -21,14 +16,39 @@ def compute_linear_xeb_fidelity( ) -> float: """Computes fidelity estimate from one circuit using linear XEB estimator. + Fidelity quantifies the similarity of two quantum states. Here, we estimate + the fidelity between the theoretically predicted output state of circuit and + the state producted in its experimental realization. Note that we don't know + the latter state. Nevertheless, we can estimate the fidelity between the two + states from the knowledge of the bitstrings observed in the experiment. + + This estimation procedure makes two assumptions. First, it assumes that the + circuit is sufficiently scrambling that its output probabilities follow the + Porter-Thomas distribution. This assumption holds for typical instances of + random quantum circuits of sufficient depth. Second, it assumes that the + circuit uses enough qubits so that the Porter-Thomas distribution can be + approximated with the exponential distribution. + + In practice the validity of these assumptions can be confirmed by plotting + a histogram of output probabilities and comparing it to the exponential + distribution. + + In order to make the estimate more robust one should average the estimates + over many random circuits. The API supports per-circuit fidelity estimation + to enable users to examine the properties of estimate distribution over + many circuits. + + See https://arxiv.org/abs/1608.00263 for more details. + Args: circuit: Random quantum circuit which has been executed on quantum processor under test - qubit_order: Qubit order used to construct bitstrings from measurements bitstrings: Results of terminal all-qubit measurements performed after each circuit execution + qubit_order: Qubit order used to construct bitstrings from measurements Returns: - Estimate of circuit fidelity. + Estimate of fidelity associated with an experimental realization of + circuit which yielded measurements in bitstrings. Raises: ValueError: Circuit is inconsistent with qubit order or one of the bitstrings is inconsistent with the number of qubits. From 0d6801b07912540559d0563b15732dffc722fd31 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Sun, 22 Sep 2019 18:00:06 -0700 Subject: [PATCH 12/21] Better tests with actual RQCs --- cirq/experiments/fidelity_estimation.py | 4 +- cirq/experiments/fidelity_estimation_test.py | 53 ++++++++++++++++---- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index b2f697129ca..3f7cab49eb1 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -1,11 +1,11 @@ """Estimation of fidelity associated with experimental circuit executions.""" -from typing import cast, Iterable, Tuple, Set +from typing import Iterable, Tuple, Set import numpy as np from cirq.circuits import Circuit -from cirq.ops import Qid, QubitOrder, QubitOrderOrList +from cirq.ops import QubitOrder, QubitOrderOrList from cirq.sim import final_wavefunction diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index d25934a7abf..ab9f90deccc 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -1,3 +1,5 @@ +import itertools + from typing import Sequence import numpy as np @@ -8,32 +10,63 @@ MEASUREMENT_KEY = 'm' -def sample_noisy_bitstrings(circuit: cirq.Circuit, depolarization: float, +def sample_noisy_bitstrings(circuit: cirq.Circuit, + qubit_order: Sequence[cirq.Qid], + depolarization: float, n_samples: int) -> np.ndarray: assert 0 <= depolarization <= 1 dim = np.product(circuit.qid_shape()) n_incoherent = int(depolarization * n_samples) n_coherent = n_samples - n_incoherent incoherent_samples = np.random.randint(dim, size=n_incoherent) + circuit_with_measurements = cirq.Circuit.from_ops( + circuit, cirq.measure(*qubit_order, key=MEASUREMENT_KEY)) if n_coherent > 0: sim = cirq.Simulator() - r = sim.run(circuit, repetitions=n_coherent) + r = sim.run(circuit_with_measurements, repetitions=n_coherent) coherent_samples = r.data[MEASUREMENT_KEY].to_numpy() return np.concatenate((coherent_samples, incoherent_samples)) return incoherent_samples -@pytest.mark.parametrize('depolarization', (0, 0.25, 0.5, 0.75, 1.0)) +def make_random_quantum_circuit(qubits: Sequence[cirq.Qid], + depth: int) -> cirq.Circuit: + SQ_GATES = [cirq.X**0.5, cirq.Y**0.5, cirq.T] + circuit = cirq.Circuit() + cz_start = 0 + for q in qubits: + circuit.append(cirq.H(q)) + for _ in range(depth): + for q in qubits: + random_gate = SQ_GATES[np.random.randint(len(SQ_GATES))] + circuit.append(random_gate(q)) + for q0, q1 in zip(itertools.islice(qubits, cz_start, None, 2), + itertools.islice(qubits, cz_start + 1, None, 2)): + circuit.append(cirq.CNOT(q0, q1)) + cz_start = 1 - cz_start + for q in qubits: + circuit.append(cirq.H(q)) + return circuit + + +@pytest.mark.parametrize('depolarization', (0.0, 0.2, 0.5, 0.7, 1.0)) def test_compute_linear_xeb_fidelity(depolarization): prng_state = np.random.get_state() np.random.seed(0) - q0, q1 = cirq.LineQubit.range(2) - circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), - cirq.measure(q0, q1, key=MEASUREMENT_KEY)) - bitstrings = sample_noisy_bitstrings(circuit, depolarization, 10000) - f = cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q1)) - assert np.isclose(f, 1 - depolarization, atol=0.026) + fs = [] + for _ in range(10): + qubits = cirq.LineQubit.range(5) + circuit = make_random_quantum_circuit(qubits, depth=12) + bitstrings = sample_noisy_bitstrings(circuit, + qubits, + depolarization, + n_samples=5000) + f = cirq.compute_linear_xeb_fidelity(circuit, bitstrings, qubits) + fs.append(f) + estimated_fidelity = np.mean(fs) + expected_fidelity = 1 - depolarization + assert np.isclose(estimated_fidelity, expected_fidelity, atol=0.09) np.random.set_state(prng_state) @@ -42,7 +75,7 @@ def test_compute_linear_xeb_fidelity_invalid_qubits(): q0, q1, q2 = cirq.LineQubit.range(3) circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), cirq.measure(q0, q1, key=MEASUREMENT_KEY)) - bitstrings = sample_noisy_bitstrings(circuit, 0.9, 10) + bitstrings = sample_noisy_bitstrings(circuit, (q0, q1, q2), 0.9, 10) with pytest.raises(ValueError): cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q2)) From 03b85ee0665a463996e5d751c1da8c1833897910 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Sun, 22 Sep 2019 18:10:05 -0700 Subject: [PATCH 13/21] Comment on endianness --- cirq/experiments/fidelity_estimation.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index 3f7cab49eb1..3f9c80ab765 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -44,8 +44,12 @@ def compute_linear_xeb_fidelity( circuit: Random quantum circuit which has been executed on quantum processor under test bitstrings: Results of terminal all-qubit measurements performed after - each circuit execution - qubit_order: Qubit order used to construct bitstrings from measurements + each circuit execution as integer array where each integer is + formed from measured qubit values according to qubit_order from + most to least significant qubit, i.e. in the order consistent with + cirq.final_wavefunction(). + qubit_order: Qubit order used to construct bitstrings enumerating + qubits starting with the most sigificant qubit Returns: Estimate of fidelity associated with an experimental realization of circuit which yielded measurements in bitstrings. From e1b297463d2dbf789503c1e4e5c0e5794104eef5 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Mon, 23 Sep 2019 14:08:22 -0700 Subject: [PATCH 14/21] Drop compute_, it's cleaner --- cirq/__init__.py | 2 +- cirq/experiments/__init__.py | 2 +- cirq/experiments/fidelity_estimation.py | 2 +- cirq/experiments/fidelity_estimation_test.py | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cirq/__init__.py b/cirq/__init__.py index e7570c4874b..9b75a34ecc2 100644 --- a/cirq/__init__.py +++ b/cirq/__init__.py @@ -85,7 +85,7 @@ ) from cirq.experiments import ( - compute_linear_xeb_fidelity, + linear_xeb_fidelity, generate_supremacy_circuit_google_v2, generate_supremacy_circuit_google_v2_bristlecone, generate_supremacy_circuit_google_v2_grid, diff --git a/cirq/experiments/__init__.py b/cirq/experiments/__init__.py index 6ee8f091f3f..2f7cf12bc56 100644 --- a/cirq/experiments/__init__.py +++ b/cirq/experiments/__init__.py @@ -18,4 +18,4 @@ ) from cirq.experiments.fidelity_estimation import ( - compute_linear_xeb_fidelity,) + linear_xeb_fidelity,) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index 3f9c80ab765..9a486e8a822 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -9,7 +9,7 @@ from cirq.sim import final_wavefunction -def compute_linear_xeb_fidelity( +def linear_xeb_fidelity( circuit: Circuit, bitstrings: np.ndarray, qubit_order: QubitOrderOrList = QubitOrder.DEFAULT, diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index ab9f90deccc..cbbfbdeedb2 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -50,7 +50,7 @@ def make_random_quantum_circuit(qubits: Sequence[cirq.Qid], @pytest.mark.parametrize('depolarization', (0.0, 0.2, 0.5, 0.7, 1.0)) -def test_compute_linear_xeb_fidelity(depolarization): +def test_linear_xeb_fidelity(depolarization): prng_state = np.random.get_state() np.random.seed(0) @@ -62,7 +62,7 @@ def test_compute_linear_xeb_fidelity(depolarization): qubits, depolarization, n_samples=5000) - f = cirq.compute_linear_xeb_fidelity(circuit, bitstrings, qubits) + f = cirq.linear_xeb_fidelity(circuit, bitstrings, qubits) fs.append(f) estimated_fidelity = np.mean(fs) expected_fidelity = 1 - depolarization @@ -71,19 +71,19 @@ def test_compute_linear_xeb_fidelity(depolarization): np.random.set_state(prng_state) -def test_compute_linear_xeb_fidelity_invalid_qubits(): +def test_linear_xeb_fidelity_invalid_qubits(): q0, q1, q2 = cirq.LineQubit.range(3) circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), cirq.measure(q0, q1, key=MEASUREMENT_KEY)) bitstrings = sample_noisy_bitstrings(circuit, (q0, q1, q2), 0.9, 10) with pytest.raises(ValueError): - cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q2)) + cirq.linear_xeb_fidelity(circuit, bitstrings, (q0, q2)) -def test_compute_linear_xeb_fidelity_invalid_bitstrings(): +def test_linear_xeb_fidelity_invalid_bitstrings(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), cirq.measure(q0, q1, key=MEASUREMENT_KEY)) bitstrings = [0, 1, 2, 3, 4] with pytest.raises(ValueError): - cirq.compute_linear_xeb_fidelity(circuit, bitstrings, (q0, q1)) + cirq.linear_xeb_fidelity(circuit, bitstrings, (q0, q1)) From e6b6b6df9e98a5e6f5e4c4fe09439dfa17e016d0 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Mon, 23 Sep 2019 14:14:12 -0700 Subject: [PATCH 15/21] Backticks --- cirq/experiments/fidelity_estimation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index 9a486e8a822..77eac60a807 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -45,9 +45,9 @@ def linear_xeb_fidelity( processor under test bitstrings: Results of terminal all-qubit measurements performed after each circuit execution as integer array where each integer is - formed from measured qubit values according to qubit_order from + formed from measured qubit values according to `qubit_order` from most to least significant qubit, i.e. in the order consistent with - cirq.final_wavefunction(). + `cirq.final_wavefunction`. qubit_order: Qubit order used to construct bitstrings enumerating qubits starting with the most sigificant qubit Returns: From c031aeb7549c3b6bb01aa6817305ccce042bfec6 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Mon, 23 Sep 2019 14:15:50 -0700 Subject: [PATCH 16/21] repetitions --- cirq/experiments/fidelity_estimation_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index cbbfbdeedb2..68ee728b168 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -13,11 +13,11 @@ def sample_noisy_bitstrings(circuit: cirq.Circuit, qubit_order: Sequence[cirq.Qid], depolarization: float, - n_samples: int) -> np.ndarray: + repetitions: int) -> np.ndarray: assert 0 <= depolarization <= 1 dim = np.product(circuit.qid_shape()) - n_incoherent = int(depolarization * n_samples) - n_coherent = n_samples - n_incoherent + n_incoherent = int(depolarization * repetitions) + n_coherent = repetitions - n_incoherent incoherent_samples = np.random.randint(dim, size=n_incoherent) circuit_with_measurements = cirq.Circuit.from_ops( circuit, cirq.measure(*qubit_order, key=MEASUREMENT_KEY)) @@ -61,7 +61,7 @@ def test_linear_xeb_fidelity(depolarization): bitstrings = sample_noisy_bitstrings(circuit, qubits, depolarization, - n_samples=5000) + repetitions=5000) f = cirq.linear_xeb_fidelity(circuit, bitstrings, qubits) fs.append(f) estimated_fidelity = np.mean(fs) From 3fa8047399f5bbf8a2bf12df2a273f95a8a1ab9c Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Mon, 23 Sep 2019 14:20:33 -0700 Subject: [PATCH 17/21] Remove duplicate measurements --- cirq/experiments/fidelity_estimation_test.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index 68ee728b168..0e1cc00aaa5 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -73,8 +73,7 @@ def test_linear_xeb_fidelity(depolarization): def test_linear_xeb_fidelity_invalid_qubits(): q0, q1, q2 = cirq.LineQubit.range(3) - circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), - cirq.measure(q0, q1, key=MEASUREMENT_KEY)) + circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1)) bitstrings = sample_noisy_bitstrings(circuit, (q0, q1, q2), 0.9, 10) with pytest.raises(ValueError): cirq.linear_xeb_fidelity(circuit, bitstrings, (q0, q2)) @@ -82,8 +81,7 @@ def test_linear_xeb_fidelity_invalid_qubits(): def test_linear_xeb_fidelity_invalid_bitstrings(): q0, q1 = cirq.LineQubit.range(2) - circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1), - cirq.measure(q0, q1, key=MEASUREMENT_KEY)) + circuit = cirq.Circuit.from_ops(cirq.H(q0), cirq.CNOT(q0, q1)) bitstrings = [0, 1, 2, 3, 4] with pytest.raises(ValueError): cirq.linear_xeb_fidelity(circuit, bitstrings, (q0, q1)) From 07585b5bbecbbad1a5fec2a84246ede34265f9f5 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Mon, 23 Sep 2019 14:23:58 -0700 Subject: [PATCH 18/21] cirq.sample --- cirq/experiments/fidelity_estimation_test.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index 0e1cc00aaa5..ed8b2466f1c 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -22,8 +22,7 @@ def sample_noisy_bitstrings(circuit: cirq.Circuit, circuit_with_measurements = cirq.Circuit.from_ops( circuit, cirq.measure(*qubit_order, key=MEASUREMENT_KEY)) if n_coherent > 0: - sim = cirq.Simulator() - r = sim.run(circuit_with_measurements, repetitions=n_coherent) + r = cirq.sample(circuit_with_measurements, repetitions=n_coherent) coherent_samples = r.data[MEASUREMENT_KEY].to_numpy() return np.concatenate((coherent_samples, incoherent_samples)) return incoherent_samples From d12a8fed5ac293feabe08244ce7b3b194403ed2c Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Mon, 23 Sep 2019 14:26:37 -0700 Subject: [PATCH 19/21] TODO to remove conditional --- cirq/experiments/fidelity_estimation_test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index ed8b2466f1c..bdc0e737ad3 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -21,6 +21,7 @@ def sample_noisy_bitstrings(circuit: cirq.Circuit, incoherent_samples = np.random.randint(dim, size=n_incoherent) circuit_with_measurements = cirq.Circuit.from_ops( circuit, cirq.measure(*qubit_order, key=MEASUREMENT_KEY)) + # TODO(viathor): Remove conditional after #2114. if n_coherent > 0: r = cirq.sample(circuit_with_measurements, repetitions=n_coherent) coherent_samples = r.data[MEASUREMENT_KEY].to_numpy() From 772f84fed324613df79458bea2ddc34937ecf964 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Mon, 23 Sep 2019 14:27:13 -0700 Subject: [PATCH 20/21] Inline measurement key --- cirq/experiments/fidelity_estimation_test.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cirq/experiments/fidelity_estimation_test.py b/cirq/experiments/fidelity_estimation_test.py index bdc0e737ad3..877984d7f8d 100644 --- a/cirq/experiments/fidelity_estimation_test.py +++ b/cirq/experiments/fidelity_estimation_test.py @@ -7,8 +7,6 @@ import cirq -MEASUREMENT_KEY = 'm' - def sample_noisy_bitstrings(circuit: cirq.Circuit, qubit_order: Sequence[cirq.Qid], @@ -20,11 +18,11 @@ def sample_noisy_bitstrings(circuit: cirq.Circuit, n_coherent = repetitions - n_incoherent incoherent_samples = np.random.randint(dim, size=n_incoherent) circuit_with_measurements = cirq.Circuit.from_ops( - circuit, cirq.measure(*qubit_order, key=MEASUREMENT_KEY)) + circuit, cirq.measure(*qubit_order, key='m')) # TODO(viathor): Remove conditional after #2114. if n_coherent > 0: r = cirq.sample(circuit_with_measurements, repetitions=n_coherent) - coherent_samples = r.data[MEASUREMENT_KEY].to_numpy() + coherent_samples = r.data['m'].to_numpy() return np.concatenate((coherent_samples, incoherent_samples)) return incoherent_samples From e7c94a14405ed5f933be8dbd941996cb03b11448 Mon Sep 17 00:00:00 2001 From: Adam Zalcman Date: Mon, 23 Sep 2019 14:49:02 -0700 Subject: [PATCH 21/21] Sequence[int] --- cirq/experiments/fidelity_estimation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cirq/experiments/fidelity_estimation.py b/cirq/experiments/fidelity_estimation.py index 77eac60a807..ace7bc96f79 100644 --- a/cirq/experiments/fidelity_estimation.py +++ b/cirq/experiments/fidelity_estimation.py @@ -1,6 +1,6 @@ """Estimation of fidelity associated with experimental circuit executions.""" -from typing import Iterable, Tuple, Set +from typing import Sequence import numpy as np @@ -11,7 +11,7 @@ def linear_xeb_fidelity( circuit: Circuit, - bitstrings: np.ndarray, + bitstrings: Sequence[int], qubit_order: QubitOrderOrList = QubitOrder.DEFAULT, ) -> float: """Computes fidelity estimate from one circuit using linear XEB estimator.