Skip to content

Commit

Permalink
Fix random_clifford (#13606) (#13710)
Browse files Browse the repository at this point in the history
* fix and tests

* Using a fixed rather than random clifford in one of the tests

* reno

* restoring previous docstring that was changed accidentally

* updating in-code comment

* also checking decompositions for random 3q cliffords

(cherry picked from commit 0d4ee23)

Co-authored-by: Alexander Ivrii <[email protected]>
  • Loading branch information
mergify[bot] and alexanderivrii authored Jan 21, 2025
1 parent 3e21326 commit 603d6cd
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 8 deletions.
8 changes: 3 additions & 5 deletions crates/accelerate/src/synthesis/clifford/random_clifford.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,15 @@ pub fn random_clifford_tableau_inner(num_qubits: usize, seed: Option<u64>) -> Ar

// Compute the full stabilizer tableau

// The code below is identical to the Python implementation, but is based on the original
// code in the paper.

// The code below is based on the original code in the referenced paper.
let mut table = Array2::from_elem((2 * num_qubits, 2 * num_qubits), false);

// Apply qubit permutation
for i in 0..num_qubits {
replace_row_inner(table.view_mut(), i, table2.slice(s![i, ..]));
replace_row_inner(table.view_mut(), i, table2.slice(s![perm[i], ..]));
replace_row_inner(
table.view_mut(),
perm[i] + num_qubits,
i + num_qubits,
table2.slice(s![perm[i] + num_qubits, ..]),
);
}
Expand Down
5 changes: 5 additions & 0 deletions releasenotes/notes/fix-random-clifford-c0394becbdd7db50.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
fixes:
- |
Fixed a bug in :func:`~qiskit.quantum_info.random_clifford` that stopped it
from sampling the full Clifford group.
11 changes: 8 additions & 3 deletions test/python/quantum_info/operators/symplectic/test_clifford.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,12 @@ def test_from_circuit_with_all_types(self):
# and even circuits with other clifford objects.
linear_function = LinearFunction([[0, 1], [1, 1]])
pauli_gate = PauliGate("YZ")
cliff = random_clifford(2, seed=777)

qc_cliff = QuantumCircuit(2)
qc_cliff.h(0)
qc_cliff.cx(0, 1)
cliff = Clifford(qc_cliff)

qc = QuantumCircuit(2)
qc.cx(0, 1)
qc.append(random_clifford(1, seed=999), [1])
Expand All @@ -493,8 +498,8 @@ def test_from_circuit_with_all_types(self):

# Additionally, make sure that it produces the correct clifford.
expected_clifford_dict = {
"stabilizer": ["-IZX", "+XXZ", "-YYZ"],
"destabilizer": ["-YYI", "-XZI", "-ZXY"],
"stabilizer": ["-IZX", "+ZYZ", "+XZI"],
"destabilizer": ["+XZZ", "-XII", "+IXY"],
}
expected_clifford = Clifford.from_dict(expected_clifford_dict)
self.assertEqual(combined_clifford, expected_clifford)
Expand Down
30 changes: 30 additions & 0 deletions test/python/quantum_info/operators/test_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,36 @@ def test_not_global_seed(self):
rng_after = np.random.randint(1000, size=test_cases)
self.assertFalse(np.all(rng_before == rng_after))

def test_cliffords_2q(self):
"""Test that we get all 2-qubit Cliffords (actually symplectic
matrices) with sufficiently many trials.
"""
seen = set()
for seed in range(10000):
cliff = random_clifford(2, seed)
seen.add(cliff.symplectic_matrix.tobytes())
self.assertEqual(len(seen), 720)

def test_clifford_2q_decompositions(self):
"""Test that we get all possible CX-counts for 2q-random cliffords
with sufficiently many trials.
"""
seen = set()
for seed in range(100):
cliff = random_clifford(2, seed)
seen.add(cliff.to_circuit().count_ops().get("cx", 0))
self.assertEqual(seen, {0, 1, 2, 3})

def test_clifford_3q_decompositions(self):
"""Test that we get all possible CX-counts for 3q-random cliffords
with sufficiently many trials.
"""
seen = set()
for seed in range(10000):
cliff = random_clifford(3, seed)
seen.add(cliff.to_circuit().count_ops().get("cx", 0))
self.assertEqual(seen, {0, 1, 2, 3, 4, 5, 6})


@ddt
class TestRandomPauliList(QiskitTestCase):
Expand Down

0 comments on commit 603d6cd

Please sign in to comment.