Skip to content

Commit 087362f

Browse files
faster method based on comparing two sorted vectors
1 parent de13108 commit 087362f

3 files changed

Lines changed: 36 additions & 8 deletions

File tree

crates/transpiler/src/commutation_checker.rs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ impl CommutationChecker {
342342
max_num_qubits,
343343
matrix_max_num_qubits,
344344
approximation_degree,
345+
false,
345346
)?)
346347
}
347348

@@ -374,6 +375,7 @@ impl CommutationChecker {
374375
max_num_qubits,
375376
matrix_max_num_qubits,
376377
approximation_degree,
378+
false,
377379
)?)
378380
}
379381

@@ -466,6 +468,7 @@ impl CommutationChecker {
466468
max_num_qubits: Option<u32>,
467469
matrix_max_num_qubits: u32,
468470
approximation_degree: f64,
471+
assume_sorted_pp: bool, // true if qubits in PPRs and PPMs cab be assumed to be sorted
469472
) -> Result<bool, CommutationError> {
470473
// If the average gate infidelity is below this tolerance, they commute. The tolerance
471474
// is set to max(1e-12, 1 - approximation_degree), to account for roundoffs and for
@@ -534,15 +537,38 @@ impl CommutationChecker {
534537
if let (Some((z1, x1)), Some((z2, x2))) =
535538
(try_pauli_generator(op1), try_pauli_generator(op2))
536539
{
537-
let max_q1 = qargs1.iter().map(|q| q.index()).max().unwrap_or(0);
538-
let mut in_q1 = vec![usize::MAX; max_q1 + 1];
539-
for (i, &q) in qargs1.iter().enumerate() {
540-
in_q1[q.index()] = i;
541-
}
542540
let mut parity = false;
543-
for (j, &q) in qargs2.iter().enumerate() {
544-
if let Some(&i) = in_q1.get(q.index()).filter(|&&i| i != usize::MAX) {
545-
parity ^= (x1[i] && z2[j]) ^ (z1[i] && x2[j]);
541+
let mut adjust_parity = |i1: usize, i2: usize| {
542+
parity ^= (x1[i1] && z2[i2]) ^ (z1[i1] && x2[i2]);
543+
};
544+
545+
if assume_sorted_pp {
546+
// The qubits in PPRs and PPMs are known to be sorted by qubit index.
547+
let (n1, n2) = (qargs1.len(), qargs2.len());
548+
let (mut i1, mut i2) = (0, 0);
549+
550+
while i1 < n1 && i2 < n2 {
551+
match qargs1[i1].cmp(&qargs2[i2]) {
552+
std::cmp::Ordering::Less => i1 += 1,
553+
std::cmp::Ordering::Greater => i2 += 1,
554+
std::cmp::Ordering::Equal => {
555+
adjust_parity(i1, i2);
556+
i1 += 1;
557+
i2 += 1;
558+
}
559+
}
560+
}
561+
} else {
562+
// The qubits in PPRs and PPMs are not known to be sorted by qubit index.
563+
let max_q1 = qargs1.iter().map(|q| q.index()).max().unwrap_or(0);
564+
let mut in_q1 = vec![usize::MAX; max_q1 + 1];
565+
for (i, &q) in qargs1.iter().enumerate() {
566+
in_q1[q.index()] = i;
567+
}
568+
for (i2, &q) in qargs2.iter().enumerate() {
569+
if let Some(&i1) = in_q1.get(q.index()).filter(|&&i1| i1 != usize::MAX) {
570+
adjust_parity(i1, i2);
571+
}
546572
}
547573
}
548574
return Ok(!parity);

crates/transpiler/src/passes/commutation_analysis.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ pub fn analyze_commutations(
109109
None,
110110
MAX_NUM_QUBITS,
111111
approximation_degree,
112+
false,
112113
)?;
113114
if !all_commute {
114115
break;

crates/transpiler/src/passes/commutative_optimization.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ fn commute(
301301
None,
302302
matrix_max_num_qubits,
303303
approximation_degree,
304+
true, // PPRs and PPMs are sorted in canonicalize
304305
)?)
305306
}
306307

0 commit comments

Comments
 (0)