From abece573a6575a632fd5e641cf73b2ebca4cad7b Mon Sep 17 00:00:00 2001 From: Adrian Lehmann Date: Tue, 5 Jul 2022 17:43:22 -0500 Subject: [PATCH 1/3] Add TableLookup function --- Standard/src/Canon/Utils/Multiplexer.qs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Standard/src/Canon/Utils/Multiplexer.qs b/Standard/src/Canon/Utils/Multiplexer.qs index 83e4ea97ea5..bbf4ec54d39 100644 --- a/Standard/src/Canon/Utils/Multiplexer.qs +++ b/Standard/src/Canon/Utils/Multiplexer.qs @@ -482,4 +482,24 @@ namespace Microsoft.Quantum.Canon { return (N, n); } + /// # Summary + /// Performs a table lookup operation + /// + /// # Description + /// A table lookup uses an address to return classical data from quantum registers + /// See more details on table lookup in Craig Gidney's paper https://arxiv.org/abs/1905.07682 + /// + /// # Input + /// ## data + /// The classical bit data that represents the table + /// ## address + /// The address used to lookup from the table + /// ## target + /// Qubits in which the result of the lookup will be stored + operation TableLookup(data : Bool[][], address : LittleEndian, target : Qubit[]) : Unit is Adj + Ctl { + let ApplyXFromBitString = ApplyPauliFromBitString(PauliX, true, _, _); // Applies X conditionally based on bitstring + let unitaries = Mapped(bitstring -> ApplyXFromBitString(bitstring, _), data); // Create unitaries based on data + MultiplexOperations(unitaries, address, target); // Multiplex over address onto target + } + } From 592b2fafc940905b1321b3933e965e7a05dc239e Mon Sep 17 00:00:00 2001 From: Adrian Lehmann Date: Mon, 18 Jul 2022 12:23:19 -0500 Subject: [PATCH 2/3] Improve TableLookup documentation Adds example, mathemetical definition, and improves referencing. --- Standard/src/Canon/Utils/Multiplexer.qs | 29 ++++++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/Standard/src/Canon/Utils/Multiplexer.qs b/Standard/src/Canon/Utils/Multiplexer.qs index bbf4ec54d39..d3ec02e99ee 100644 --- a/Standard/src/Canon/Utils/Multiplexer.qs +++ b/Standard/src/Canon/Utils/Multiplexer.qs @@ -483,19 +483,36 @@ namespace Microsoft.Quantum.Canon { } /// # Summary - /// Performs a table lookup operation + /// Performs a table lookup operation. /// /// # Description - /// A table lookup uses an address to return classical data from quantum registers - /// See more details on table lookup in Craig Gidney's paper https://arxiv.org/abs/1905.07682 + /// A table lookup uses an address to return classical data from quantum registers. + /// Computes the following map: + /// $$\sum_{j=0}^{L-1}\ket{j}\ket{0} \rightarrow \sum_{j=0}^{L-1}\ket{j}\ket{T_j}$$ + /// where L is the length of the table /// /// # Input /// ## data - /// The classical bit data that represents the table + /// The classical bit data that represents the table. + /// The length of data has to be in the interval [0, 2^(number of qubits in address)[. + /// Each element of data has to be of length equal to the number of qubits in target. /// ## address - /// The address used to lookup from the table + /// The address used to lookup from the table. /// ## target - /// Qubits in which the result of the lookup will be stored + /// Qubits in which the result of the lookup will be stored. + /// + /// # Example + /// ```qsharp + /// operation InvertTwoBitNumber(address : LittleEndian, target : Qubit[]) : Unit { + /// let data = [[true, true], [true, false], [false, true], [false, false]]; + /// TableLookup(data, address, target); + /// } + /// ``` + /// + /// # References + /// - Windowed quantum arithmetic + /// Craig Gidney + /// https://arxiv.org/abs/1905.07682 operation TableLookup(data : Bool[][], address : LittleEndian, target : Qubit[]) : Unit is Adj + Ctl { let ApplyXFromBitString = ApplyPauliFromBitString(PauliX, true, _, _); // Applies X conditionally based on bitstring let unitaries = Mapped(bitstring -> ApplyXFromBitString(bitstring, _), data); // Create unitaries based on data From fd12f49c900ecd7b5e9027968a2eb04fe6bc7e5a Mon Sep 17 00:00:00 2001 From: Adrian Lehmann Date: Tue, 19 Jul 2022 11:55:55 -0500 Subject: [PATCH 3/3] Documentation and name changes for ApplyTableLookup --- Standard/src/Canon/Utils/Multiplexer.qs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Standard/src/Canon/Utils/Multiplexer.qs b/Standard/src/Canon/Utils/Multiplexer.qs index d3ec02e99ee..cd0d8d08554 100644 --- a/Standard/src/Canon/Utils/Multiplexer.qs +++ b/Standard/src/Canon/Utils/Multiplexer.qs @@ -488,20 +488,21 @@ namespace Microsoft.Quantum.Canon { /// # Description /// A table lookup uses an address to return classical data from quantum registers. /// Computes the following map: - /// $$\sum_{j=0}^{L-1}\ket{j}\ket{0} \rightarrow \sum_{j=0}^{L-1}\ket{j}\ket{T_j}$$ - /// where L is the length of the table + /// $$\sum_{j=0}^{L-1}\ket{j}\ket{0} \rightarrow \sum_{j=0}^{L-1}\ket{j}\ket{data_j}$$ + /// where $L$ is the length of the table. /// /// # Input /// ## data /// The classical bit data that represents the table. - /// The length of data has to be in the interval [0, 2^(number of qubits in address)[. - /// Each element of data has to be of length equal to the number of qubits in target. + /// The length of data has to be in the interval [0, 2^(number of qubits in address) - 1. + /// The length of each element of `data` has to be equal to the number of qubits in `target`. /// ## address /// The address used to lookup from the table. /// ## target /// Qubits in which the result of the lookup will be stored. /// /// # Example + /// Below is an example that flips each bit in a two bit register /// ```qsharp /// operation InvertTwoBitNumber(address : LittleEndian, target : Qubit[]) : Unit { /// let data = [[true, true], [true, false], [false, true], [false, false]]; @@ -513,9 +514,10 @@ namespace Microsoft.Quantum.Canon { /// - Windowed quantum arithmetic /// Craig Gidney /// https://arxiv.org/abs/1905.07682 - operation TableLookup(data : Bool[][], address : LittleEndian, target : Qubit[]) : Unit is Adj + Ctl { - let ApplyXFromBitString = ApplyPauliFromBitString(PauliX, true, _, _); // Applies X conditionally based on bitstring - let unitaries = Mapped(bitstring -> ApplyXFromBitString(bitstring, _), data); // Create unitaries based on data + operation ApplyTableLookup(data : Bool[][], address : LittleEndian, target : Qubit[]) : Unit is Adj + Ctl { + let applyXFromBitString = ApplyPauliFromBitString(PauliX, true, _, _); // Applies X conditionally based on bitstring + // Create unitaries that encode elements of data as bit flips + let unitaries = Mapped(bitstring -> applyXFromBitString(bitstring, _), data); MultiplexOperations(unitaries, address, target); // Multiplex over address onto target }