Skip to content

Commit a88fdbd

Browse files
authored
Fix Exp on qubit arrays larger than 2 with single PauliI (#2086)
This fixes a bug in the decomposition for `Exp` that would cause a runtime failure if an array of more than two qubits was used and a single `PauliI` was passed in the Pauli array. The decomposition ignores `PauliI` by calling the `RemovePauliI` helper function, but then incorrectly uses the original arrays when rather than the filtered arrays in the rest of the operation. This adds a test to confirm the fix (without the fix the test triggers a runtime failure in `MapPauli`).
1 parent 1a930f6 commit a88fdbd

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

library/src/tests/intrinsic.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,6 +3009,39 @@ fn test_exp() {
30093009
.assert_eq(&dump);
30103010
}
30113011

3012+
#[test]
3013+
fn test_exp_mixed_paulis() {
3014+
let dump = test_expression(
3015+
indoc! {r#"
3016+
{
3017+
open Std.Math;
3018+
open Std.Diagnostics;
3019+
use qs = Qubit[3];
3020+
for q in qs {
3021+
H(q);
3022+
}
3023+
Exp([PauliX, PauliI, PauliY], PI() / 7.0, qs);
3024+
DumpMachine();
3025+
ResetAll(qs);
3026+
}
3027+
"#},
3028+
&Value::unit(),
3029+
);
3030+
3031+
expect![[r#"
3032+
STATE:
3033+
|000⟩: 0.4719+0.0000𝑖
3034+
|001⟩: 0.1651+0.0000𝑖
3035+
|010⟩: 0.4719+0.0000𝑖
3036+
|011⟩: 0.1651+0.0000𝑖
3037+
|100⟩: 0.4719+0.0000𝑖
3038+
|101⟩: 0.1651+0.0000𝑖
3039+
|110⟩: 0.4719+0.0000𝑖
3040+
|111⟩: 0.1651+0.0000𝑖
3041+
"#]]
3042+
.assert_eq(&dump);
3043+
}
3044+
30123045
#[test]
30133046
fn test_apply_unitary_with_h_matrix() {
30143047
let dump = test_expression(

library/std/src/Std/Intrinsic.qs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,14 @@ operation CNOT(control : Qubit, target : Qubit) : Unit is Adj + Ctl {
143143
operation Exp(paulis : Pauli[], theta : Double, qubits : Qubit[]) : Unit is Adj + Ctl {
144144
body ... {
145145
Fact(Length(paulis) == Length(qubits), "Arrays 'pauli' and 'qubits' must have the same length");
146-
let (newPaulis, newQubits) = RemovePauliI(paulis, qubits);
146+
let (paulis, qubits) = RemovePauliI(paulis, qubits);
147147
let angle = -2.0 * theta;
148-
let len = Length(newPaulis);
148+
let len = Length(paulis);
149149

150150
if len == 0 {
151151
ApplyGlobalPhase(theta);
152152
} elif len == 1 {
153-
R(newPaulis[0], angle, qubits[0]);
153+
R(paulis[0], angle, qubits[0]);
154154
} elif len == 2 {
155155
within {
156156
MapPauli(qubits[1], paulis[0], paulis[1]);

0 commit comments

Comments
 (0)