@@ -377,56 +377,30 @@ pub fn qubit_relabel(
377
377
return Err ( Error :: RelabelingMismatch ( arg_span) ) ;
378
378
}
379
379
380
- let mut map = FxHashMap :: default ( ) ;
381
- map. reserve ( left. len ( ) ) ;
380
+ // Start with a mapping of each qubit to itself.
381
+ let mut mappings: FxHashMap < usize , usize > =
382
+ left. iter ( ) . copied ( ) . zip ( left. iter ( ) . copied ( ) ) . collect ( ) ;
382
383
for ( l, r) in left. into_iter ( ) . zip ( right. into_iter ( ) ) {
384
+ // Trivial case where the qubit is already mapped to itself in the relabel, which can be short circuited.
383
385
if l == r {
384
386
continue ;
385
387
}
386
- match ( map. contains_key ( & l) , map. contains_key ( & r) ) {
387
- ( false , false ) => {
388
- // Neither qubit has been relabeled yet.
389
- swap ( l, r) ;
390
- map. insert ( l, r) ;
391
- map. insert ( r, l) ;
392
- }
393
- ( false , true ) => {
394
- // The right qubit has been relabeled, so we need to swap the left qubit with the
395
- // new label for the right qubit.
396
- let label = * map
397
- . keys ( )
398
- . find ( |k| map[ * k] == r)
399
- . expect ( "mapped qubit should be present as both key and value" ) ;
400
- swap ( l, label) ;
401
- map. insert ( l, r) ;
402
- map. insert ( label, l) ;
403
- }
404
- ( true , false ) => {
405
- // The left qubit has been relabeled, so we swap the qubits as normal but
406
- // remember the new mapping of the right qubit.
407
- let mapped = * map. get ( & l) . expect ( "mapped qubit should be present" ) ;
408
- swap ( l, r) ;
409
- map. insert ( l, r) ;
410
- map. insert ( r, mapped) ;
411
- }
412
- ( true , true ) => {
413
- // Both qubits have been relabeled, so we need to swap new label for the right qubit with
414
- // the left qubit and remember the new mapping of both qubits.
415
- // This is effectively a combination of the second and third cases above.
416
- let label_r = * map
417
- . keys ( )
418
- . find ( |k| map[ * k] == r)
419
- . expect ( "mapped qubit should be present as both key and value" ) ;
420
- let mapped_l = * map. get ( & l) . expect ( "mapped qubit should be present" ) ;
421
- let mapped_r = * map. get ( & r) . expect ( "mapped qubit should be present" ) ;
422
388
423
- // This swap is only necessary if the labels don't already point to each other.
424
- if mapped_l != r && mapped_r != l {
425
- swap ( label_r, l) ;
426
- map. insert ( label_r, mapped_l) ;
427
- map. insert ( l, mapped_r) ;
428
- }
429
- }
389
+ // Check what each label currently maps to.
390
+ let mapped_l = * mappings. get ( & l) . expect ( "mapped qubit should be present" ) ;
391
+ let mapped_r = * mappings. get ( & r) . expect ( "mapped qubit should be present" ) ;
392
+
393
+ // We only need to swap if the label is not pointing to the correct qubit.
394
+ if mapped_l != r && mapped_r != l {
395
+ // Do a reverse lookup to find which label is currently mapped to the desired right qubit.
396
+ // This tells us which label to use in the swap, which we will use in the update of the mappings too.
397
+ let label_r = * mappings
398
+ . keys ( )
399
+ . find ( |k| mappings[ * k] == r)
400
+ . expect ( "mapped qubit should be present as both key and value" ) ;
401
+ swap ( l, label_r) ;
402
+ mappings. insert ( label_r, mapped_l) ;
403
+ mappings. insert ( l, mapped_r) ;
430
404
}
431
405
}
432
406
0 commit comments