Skip to content

Commit 0f3b65c

Browse files
DmitryVasilevskyDmitry Vasilevsky
andauthored
Improved adjoint Select implementation (#2729)
This check-in improves implementation of adjoin variant of Select operation (Unlookup operation). Previously it was based on May [2019 paper by Craig Gidney](https://arxiv.org/abs/1905.07682), and this proposed implementation is based on [2025 paper by Craig Gidney](https://arxiv.org/abs/2505.15917). The implementation of Unlookup is measurement-based with phase correction via Phase Lookup operation described in the aforementioned paper. Phase Lookup is implemented by splitting address register and computing power products for both halves. Then the necessary phase corrections are applied and power products are uncomputed. This implementation uses fast Boolean Mobius transform instead of matrix multiplication as in the paper to convert classical data from truth table representation to coefficients of an algebraic normal form over GF(2) field. This results in simpler code. A test is added to check that address register remains in correct state after uncomputation. This implementation may reduce required resources to uncompute lookup operation. As one example, the circuit to uncompute **one particular case** with previous and proposed approaches. This is a highly dynamic algorithm that uses results of measurements to apply gates conditionally; actual execution trace and actual savings may vary. Before: <img width="1456" height="476" alt="Unlookup" src="https://github.com/user-attachments/assets/0e2a28f0-0298-4ef8-be51-fc02ccd85b02" /> After: <img width="822" height="640" alt="Phaseup" src="https://github.com/user-attachments/assets/96305720-ae1f-4dad-bc40-dcd990bcb125" /> --------- Co-authored-by: Dmitry Vasilevsky <[email protected]>
1 parent 95a6a6a commit 0f3b65c

File tree

3 files changed

+361
-98
lines changed

3 files changed

+361
-98
lines changed

library/src/tests/resources/src/select.qs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,38 @@ namespace Test {
2828
}
2929
}
3030

31+
internal operation TestSelectPhase() : Unit {
32+
use addressRegister = Qubit[3];
33+
use targetRegister = Qubit[4];
34+
35+
// Could be random, but fixed for reproducibility
36+
let data = [
37+
[false, false, false, false],
38+
[false, false, true, false],
39+
[true, true, false, false],
40+
[false, true, false, false],
41+
[true, true, true, true],
42+
[true, false, false, false],
43+
[true, true, true, false],
44+
[true, false, true, false],
45+
];
46+
47+
// Select followed by unselect. This should be equivalent to identity.
48+
let selunsel = (addr) => {
49+
within {
50+
Select(data, addr, targetRegister);
51+
} apply {
52+
// Do nothing.
53+
}
54+
};
55+
56+
// This test checks that the implementation of unselect
57+
// doesn't change address register phases and returns target register to |0⟩ state.
58+
let equal = CheckOperationsAreEqual(3, selunsel, (addr) => {});
59+
Fact(CheckAllZero(targetRegister), "Target register must be in |0⟩ state after unlookup.");
60+
Fact(equal, "Select+Unselect should be equivalent to identity up to global phase.");
61+
}
62+
3163
internal operation TestSelectFuzz(rounds : Int) : Unit {
3264
for _ in 1..rounds {
3365
let addressBits = DrawRandomInt(2, 6);

library/src/tests/table_lookup.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,12 @@ fn check_select_fuzz() {
6161
&Value::Tuple(vec![].into(), None),
6262
);
6363
}
64+
65+
#[test]
66+
fn check_select_phase() {
67+
test_expression_with_lib(
68+
"Test.TestSelectPhase()",
69+
SELECT_TEST_LIB,
70+
&Value::Tuple(vec![].into(), None),
71+
);
72+
}

0 commit comments

Comments
 (0)