@@ -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) ;
0 commit comments