Repository: qir-alliance/qir-runner (language: python)

Issue:
Include global phase of -i for Rx/Ry of Pi
This fixes the shortcut used to optimize Rx/Ry of Pi, where we offload to X/Y, by ensuring the expected global phase of i is included. This also includes new matrix-based unit tests that verify the expected behavior is mathematically correct.

Fixes #162


Discussion / hints:

Fix patch:
diff --git a/sparsesim/src/lib.rs b/sparsesim/src/lib.rs
index 378f90db..a945e7c9 100644
--- a/sparsesim/src/lib.rs
+++ b/sparsesim/src/lib.rs
@@ -982,7 +982,17 @@ impl QuantumSim {
                         accum
                     });
         } else if m01.is_nearly_zero() {
-            // This is just identity, so we can no-op.
+            // This is just identity, so we can effectively no-op and just add a phase of -1.
+            let (_, ctls) = self.resolve_and_check_qubits(target, ctls);
+            self.state =
+                self.state
+                    .drain()
+                    .fold(SparseState::default(), |mut accum, (index, value)| {
+                        if ctls.iter().all(|c| index.bit(*c)) {
+                            accum.insert(index, value * -Complex64::one());
+                        }
+                        accum
+                    });
         } else {
             let (target, ctls) = self.resolve_and_check_qubits(target, ctls);
             let mut new_state = SparseState::default();


Test patch:
diff --git a/sparsesim/src/matrix_testing.rs b/sparsesim/src/matrix_testing.rs
index ffb05165..2828817f 100644
--- a/sparsesim/src/matrix_testing.rs
+++ b/sparsesim/src/matrix_testing.rs
@@ -590,6 +590,19 @@ mod tests {
         );
     }
 
+    #[test]
+    fn test_rx_2pi() {
+        assert_operation_equal_referenced(
+            |sim, qs| {
+                sim.rx(2.0 * PI, qs[0]);
+            },
+            |sim, qs| {
+                sim.apply(&adjoint(&rx(2.0 * PI)), &[qs[0]], None);
+            },
+            1,
+        );
+    }
+
     #[test]
     fn test_ry() {
         assert_operation_equal_referenced(
@@ -616,6 +629,19 @@ mod tests {
         );
     }
 
+    #[test]
+    fn test_ry_2pi() {
+        assert_operation_equal_referenced(
+            |sim, qs| {
+                sim.ry(2.0 * PI, qs[0]);
+            },
+            |sim, qs| {
+                sim.apply(&adjoint(&ry(2.0 * PI)), &[qs[0]], None);
+            },
+            1,
+        );
+    }
+
     #[test]
     fn test_mcri() {
         assert_operation_equal_referenced(