From e5bd923049fd263798883333374b7f31f803271f Mon Sep 17 00:00:00 2001 From: Adrian Lehmann Date: Tue, 5 Jul 2022 17:33:10 -0500 Subject: [PATCH 1/7] Add ApplyWindowed operation Applies an operation windowing over input but with const target qubits --- Standard/src/Arrays/Windows.qs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Standard/src/Arrays/Windows.qs b/Standard/src/Arrays/Windows.qs index 34837baae6f..4fccc574d3d 100644 --- a/Standard/src/Arrays/Windows.qs +++ b/Standard/src/Arrays/Windows.qs @@ -73,4 +73,29 @@ namespace Microsoft.Quantum.Arrays { internal function Prefix<'T>(to : Int, array : 'T[]) : 'T[] { return array[0..to]; } + + /// # Summary + /// Applies an operation windowing over input but with constant target qubits. + /// + /// # Input + /// ## windowLen + /// The size of each window + /// ## op + /// An operation with three arguments, one arbitrary, controls, and target. When applied it will be supplied with a windowed component of the `qubits` parameter, the `target` qubits (constant) and an arbitary parameter stemming from the `argumentTransform` mapping supplied. + /// ## argumentTransform + /// Transforms an integer into the arbitary argument for op. This function will be provide with the indices of the windows. This means the function need to work correctly for $[0, n[$, where $n$ is the number of windows. + /// ## qubits + /// The qubits the operation windows over + /// ## target + /// The targer provided to each windowed operation + /// # Type Parameters + /// ## 'T + /// Any type that the operation can use as parametrization + operation ApplyWindowed<'T>(windowLen : Int, op : ('T, Qubit[], Qubit[]) => Unit, argumentTransform : Int -> 'T, qubits : Qubit[], target : Qubit[]) : Unit { + let windows = Windows(windowLen, qubits); // Create windows of non-target qubits + for (i, window) in Enumerated(windows) { + op(argumentTransform(i), window, target); + } + } + } From 3f87f06e4f1824dde88dea831dcb34e2c072cd71 Mon Sep 17 00:00:00 2001 From: Adrian Lehmann Date: Wed, 6 Jul 2022 15:36:16 -0500 Subject: [PATCH 2/7] Simplify ApplyWindowed --- Standard/src/Arrays/Windows.qs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Standard/src/Arrays/Windows.qs b/Standard/src/Arrays/Windows.qs index 4fccc574d3d..15e28a69f83 100644 --- a/Standard/src/Arrays/Windows.qs +++ b/Standard/src/Arrays/Windows.qs @@ -81,20 +81,15 @@ namespace Microsoft.Quantum.Arrays { /// ## windowLen /// The size of each window /// ## op - /// An operation with three arguments, one arbitrary, controls, and target. When applied it will be supplied with a windowed component of the `qubits` parameter, the `target` qubits (constant) and an arbitary parameter stemming from the `argumentTransform` mapping supplied. - /// ## argumentTransform - /// Transforms an integer into the arbitary argument for op. This function will be provide with the indices of the windows. This means the function need to work correctly for $[0, n[$, where $n$ is the number of windows. + /// An operation with three arguments, one index, controls, and target. When applied it will be supplied with a windowed component of the `qubits` parameter, the `target` qubits (constant) and an index of the current window /// ## qubits /// The qubits the operation windows over /// ## target - /// The targer provided to each windowed operation - /// # Type Parameters - /// ## 'T - /// Any type that the operation can use as parametrization - operation ApplyWindowed<'T>(windowLen : Int, op : ('T, Qubit[], Qubit[]) => Unit, argumentTransform : Int -> 'T, qubits : Qubit[], target : Qubit[]) : Unit { + /// The target provided to each windowed operation + operation ApplyWindowed(windowLen : Int, op : (Int, Qubit[], Qubit[]) => Unit, qubits : Qubit[], target : Qubit[]) : Unit { let windows = Windows(windowLen, qubits); // Create windows of non-target qubits for (i, window) in Enumerated(windows) { - op(argumentTransform(i), window, target); + op(i, window, target); } } From 0e6e244bb634522606e00a01f167e6f2dbadc04b Mon Sep 17 00:00:00 2001 From: Adrian Lehmann Date: Thu, 7 Jul 2022 15:47:58 -0500 Subject: [PATCH 3/7] Update ApplyWindowed to be more idiomatic See comment on #602 by @cgranade --- Standard/src/Arrays/Windows.qs | 75 +++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/Standard/src/Arrays/Windows.qs b/Standard/src/Arrays/Windows.qs index 15e28a69f83..8d5340828dc 100644 --- a/Standard/src/Arrays/Windows.qs +++ b/Standard/src/Arrays/Windows.qs @@ -2,6 +2,7 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Arrays { + open Microsoft.Quantum.Canon; /// # Summary /// Returns all consecutive subarrays of length `size`. @@ -75,22 +76,74 @@ namespace Microsoft.Quantum.Arrays { } /// # Summary - /// Applies an operation windowing over input but with constant target qubits. + /// Applies an operation windowing over input registers. /// /// # Input /// ## windowLen /// The size of each window /// ## op - /// An operation with three arguments, one index, controls, and target. When applied it will be supplied with a windowed component of the `qubits` parameter, the `target` qubits (constant) and an index of the current window - /// ## qubits - /// The qubits the operation windows over - /// ## target - /// The target provided to each windowed operation - operation ApplyWindowed(windowLen : Int, op : (Int, Qubit[], Qubit[]) => Unit, qubits : Qubit[], target : Qubit[]) : Unit { - let windows = Windows(windowLen, qubits); // Create windows of non-target qubits - for (i, window) in Enumerated(windows) { - op(i, window, target); - } + /// An operation on registers that will be provided with the current window and its index + /// ## registers + /// The registers the operation windows over + //// + /// # Type Parameters + /// ## 'T + /// The type of registers + operation ApplyWindowed<'T>(windowLen : Int, op : (Int, 'T[]) => Unit, register : 'T[]) : Unit { + ApplyToEach(op, Enumerated(Windows(windowLen, register))); + } + + /// # Summary + /// Applies an operation windowing over input registers. The modifier `A` indicates that the single-qubit operation is adjointable. + /// + /// # Input + /// ## windowLen + /// The size of each window + /// ## op + /// An operation on registers that will be provided with the current window and its index + /// ## registers + /// The registers the operation windows over + //// + /// # Type Parameters + /// ## 'T + /// The type of registers + operation ApplyWindowedA<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Adj, register : 'T[]) : Unit is Adj { + ApplyToEachA(op, Enumerated(Windows(windowLen, register))); + } + + /// # Summary + /// Applies an operation windowing over input registers. The modifier `C` indicates that the single-qubit operation is controllable. + /// + /// # Input + /// ## windowLen + /// The size of each window + /// ## op + /// An operation on registers that will be provided with the current window and its index + /// ## registers + /// The registers the operation windows over + //// + /// # Type Parameters + /// ## 'T + /// The type of registers + operation ApplyWindowedC<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Ctl, register : 'T[]) : Unit is Ctl { + ApplyToEachC(op, Enumerated(Windows(windowLen, register))); } + /// # Summary + /// Applies an operation windowing over input registers. The modifier `CA` indicates that the single-qubit operation is controllable and adjointable. + /// + /// # Input + /// ## windowLen + /// The size of each window + /// ## op + /// An operation on registers that will be provided with the current window and its index + /// ## registers + /// The registers the operation windows over + //// + /// # Type Parameters + /// ## 'T + /// The type of registers + operation ApplyWindowedCA<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Adj + Ctl, register : 'T[]) : Unit is Adj + Ctl { + ApplyToEachCA(op, Enumerated(Windows(windowLen, register))); + } } From 1b4026823b86d865a772258c90ba1fd31a93bcdb Mon Sep 17 00:00:00 2001 From: Adrian Lehmann Date: Mon, 18 Jul 2022 12:29:29 -0500 Subject: [PATCH 4/7] Fix documentation style issues for ApplyWindowed --- Standard/src/Arrays/Windows.qs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Standard/src/Arrays/Windows.qs b/Standard/src/Arrays/Windows.qs index 8d5340828dc..327c225d1d2 100644 --- a/Standard/src/Arrays/Windows.qs +++ b/Standard/src/Arrays/Windows.qs @@ -80,15 +80,15 @@ namespace Microsoft.Quantum.Arrays { /// /// # Input /// ## windowLen - /// The size of each window + /// The size of each window. /// ## op - /// An operation on registers that will be provided with the current window and its index + /// An operation on registers that will be provided with the current window and its index. /// ## registers - /// The registers the operation windows over + /// The registers the operation windows over. //// /// # Type Parameters /// ## 'T - /// The type of registers + /// The type of registers. operation ApplyWindowed<'T>(windowLen : Int, op : (Int, 'T[]) => Unit, register : 'T[]) : Unit { ApplyToEach(op, Enumerated(Windows(windowLen, register))); } @@ -98,15 +98,15 @@ namespace Microsoft.Quantum.Arrays { /// /// # Input /// ## windowLen - /// The size of each window + /// The size of each window. /// ## op - /// An operation on registers that will be provided with the current window and its index + /// An operation on registers that will be provided with the current window and its index. /// ## registers - /// The registers the operation windows over + /// The registers the operation windows over. //// /// # Type Parameters /// ## 'T - /// The type of registers + /// The type of registers. operation ApplyWindowedA<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Adj, register : 'T[]) : Unit is Adj { ApplyToEachA(op, Enumerated(Windows(windowLen, register))); } @@ -116,15 +116,15 @@ namespace Microsoft.Quantum.Arrays { /// /// # Input /// ## windowLen - /// The size of each window + /// The size of each window. /// ## op - /// An operation on registers that will be provided with the current window and its index + /// An operation on registers that will be provided with the current window and its index. /// ## registers - /// The registers the operation windows over + /// The registers the operation windows over. //// /// # Type Parameters /// ## 'T - /// The type of registers + /// The type of registers. operation ApplyWindowedC<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Ctl, register : 'T[]) : Unit is Ctl { ApplyToEachC(op, Enumerated(Windows(windowLen, register))); } @@ -134,15 +134,15 @@ namespace Microsoft.Quantum.Arrays { /// /// # Input /// ## windowLen - /// The size of each window + /// The size of each window. /// ## op - /// An operation on registers that will be provided with the current window and its index + /// An operation on registers that will be provided with the current window and its index. /// ## registers - /// The registers the operation windows over + /// The registers the operation windows over. //// /// # Type Parameters /// ## 'T - /// The type of registers + /// The type of registers. operation ApplyWindowedCA<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Adj + Ctl, register : 'T[]) : Unit is Adj + Ctl { ApplyToEachCA(op, Enumerated(Windows(windowLen, register))); } From 8a2189633113817b9647a2ed188b6dfe189d4ef8 Mon Sep 17 00:00:00 2001 From: Adrian Lehmann Date: Tue, 19 Jul 2022 12:34:26 -0500 Subject: [PATCH 5/7] Improve ApplyWindowed documentation and add example --- Standard/src/Arrays/Windows.qs | 57 +++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/Standard/src/Arrays/Windows.qs b/Standard/src/Arrays/Windows.qs index 327c225d1d2..6107e008dfe 100644 --- a/Standard/src/Arrays/Windows.qs +++ b/Standard/src/Arrays/Windows.qs @@ -76,73 +76,88 @@ namespace Microsoft.Quantum.Arrays { } /// # Summary - /// Applies an operation windowing over input registers. + /// Applies an operation windowing over an input register. /// /// # Input /// ## windowLen /// The size of each window. /// ## op - /// An operation on registers that will be provided with the current window and its index. - /// ## registers - /// The registers the operation windows over. - //// + /// An operation on a register that will be provided with the current window and its index. + /// ## register + /// The register the operation windows over. + /// + /// # Example + /// The example below shows how to use `ApplyWindowed` to construct a parity function + /// operation Parity(qubits : Qubit[], target : Qubit) : Unit { + /// ApplyWindowed(1, (_, q) => CNOT(q[0], target), qubits); + /// } + /// /// # Type Parameters /// ## 'T - /// The type of registers. + /// The type of register elements. operation ApplyWindowed<'T>(windowLen : Int, op : (Int, 'T[]) => Unit, register : 'T[]) : Unit { ApplyToEach(op, Enumerated(Windows(windowLen, register))); } /// # Summary - /// Applies an operation windowing over input registers. The modifier `A` indicates that the single-qubit operation is adjointable. + /// Applies an operation windowing over an input register. The modifier `A` indicates that the single-qubit operation is adjointable. /// /// # Input /// ## windowLen /// The size of each window. /// ## op - /// An operation on registers that will be provided with the current window and its index. - /// ## registers - /// The registers the operation windows over. + /// An operation on a register that will be provided with the current window and its index. + /// ## register + /// The register the operation windows over. //// /// # Type Parameters /// ## 'T - /// The type of registers. + /// The type of register elements. + /// + /// # See Also + /// - Microsoft.Quantum.Arrays.ApplyWindowed operation ApplyWindowedA<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Adj, register : 'T[]) : Unit is Adj { ApplyToEachA(op, Enumerated(Windows(windowLen, register))); } /// # Summary - /// Applies an operation windowing over input registers. The modifier `C` indicates that the single-qubit operation is controllable. + /// Applies an operation windowing over an input register. The modifier `C` indicates that the single-qubit operation is controllable. /// /// # Input /// ## windowLen /// The size of each window. /// ## op - /// An operation on registers that will be provided with the current window and its index. - /// ## registers - /// The registers the operation windows over. + /// An operation on a register that will be provided with the current window and its index. + /// ## register + /// The register the operation windows over. //// /// # Type Parameters /// ## 'T - /// The type of registers. + /// The type of register elements. + /// + /// # See Also + /// - Microsoft.Quantum.Arrays.ApplyWindowed operation ApplyWindowedC<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Ctl, register : 'T[]) : Unit is Ctl { ApplyToEachC(op, Enumerated(Windows(windowLen, register))); } /// # Summary - /// Applies an operation windowing over input registers. The modifier `CA` indicates that the single-qubit operation is controllable and adjointable. + /// Applies an operation windowing over an input register. The modifier `CA` indicates that the single-qubit operation is controllable and adjointable. /// /// # Input /// ## windowLen /// The size of each window. /// ## op - /// An operation on registers that will be provided with the current window and its index. - /// ## registers - /// The registers the operation windows over. + /// An operation on a register that will be provided with the current window and its index. + /// ## register + /// The register the operation windows over. //// /// # Type Parameters /// ## 'T - /// The type of registers. + /// The type of register elements. + /// + /// # See Also + /// - Microsoft.Quantum.Arrays.ApplyWindowed operation ApplyWindowedCA<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Adj + Ctl, register : 'T[]) : Unit is Adj + Ctl { ApplyToEachCA(op, Enumerated(Windows(windowLen, register))); } From 09331a9c13b91658909600e92f811e444fbb347f Mon Sep 17 00:00:00 2001 From: Adrian Lehmann Date: Tue, 19 Jul 2022 14:02:21 -0500 Subject: [PATCH 6/7] Change name of ApplyWindowed to ApplyToEachWindow --- Standard/src/Arrays/Windows.qs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Standard/src/Arrays/Windows.qs b/Standard/src/Arrays/Windows.qs index 6107e008dfe..0d0d01ed3b3 100644 --- a/Standard/src/Arrays/Windows.qs +++ b/Standard/src/Arrays/Windows.qs @@ -87,15 +87,15 @@ namespace Microsoft.Quantum.Arrays { /// The register the operation windows over. /// /// # Example - /// The example below shows how to use `ApplyWindowed` to construct a parity function + /// The example below shows how to use `ApplyToEachWindow` to construct a parity function /// operation Parity(qubits : Qubit[], target : Qubit) : Unit { - /// ApplyWindowed(1, (_, q) => CNOT(q[0], target), qubits); + /// ApplyToEachWindow(1, (_, q) => CNOT(q[0], target), qubits); /// } /// /// # Type Parameters /// ## 'T /// The type of register elements. - operation ApplyWindowed<'T>(windowLen : Int, op : (Int, 'T[]) => Unit, register : 'T[]) : Unit { + operation ApplyToEachWindow<'T>(windowLen : Int, op : (Int, 'T[]) => Unit, register : 'T[]) : Unit { ApplyToEach(op, Enumerated(Windows(windowLen, register))); } @@ -115,8 +115,8 @@ namespace Microsoft.Quantum.Arrays { /// The type of register elements. /// /// # See Also - /// - Microsoft.Quantum.Arrays.ApplyWindowed - operation ApplyWindowedA<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Adj, register : 'T[]) : Unit is Adj { + /// - Microsoft.Quantum.Arrays.ApplyToEachWindow + operation ApplyToEachWindowA<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Adj, register : 'T[]) : Unit is Adj { ApplyToEachA(op, Enumerated(Windows(windowLen, register))); } @@ -136,8 +136,8 @@ namespace Microsoft.Quantum.Arrays { /// The type of register elements. /// /// # See Also - /// - Microsoft.Quantum.Arrays.ApplyWindowed - operation ApplyWindowedC<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Ctl, register : 'T[]) : Unit is Ctl { + /// - Microsoft.Quantum.Arrays.ApplyToEachWindow + operation ApplyToEachWindowC<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Ctl, register : 'T[]) : Unit is Ctl { ApplyToEachC(op, Enumerated(Windows(windowLen, register))); } @@ -157,8 +157,8 @@ namespace Microsoft.Quantum.Arrays { /// The type of register elements. /// /// # See Also - /// - Microsoft.Quantum.Arrays.ApplyWindowed - operation ApplyWindowedCA<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Adj + Ctl, register : 'T[]) : Unit is Adj + Ctl { + /// - Microsoft.Quantum.Arrays.ApplyToEachWindow + operation ApplyToEachWindowCA<'T>(windowLen : Int, op : (Int, 'T[]) => Unit is Adj + Ctl, register : 'T[]) : Unit is Adj + Ctl { ApplyToEachCA(op, Enumerated(Windows(windowLen, register))); } } From 4e7885667fd0dc2d2b58650a13625e4bd1e8404c Mon Sep 17 00:00:00 2001 From: Adrian Lehmann <26521502+adrianleh@users.noreply.github.com> Date: Tue, 19 Jul 2022 14:27:35 -0500 Subject: [PATCH 7/7] Fix example being in code block Co-authored-by: Mariia Mykhailova --- Standard/src/Arrays/Windows.qs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Standard/src/Arrays/Windows.qs b/Standard/src/Arrays/Windows.qs index 0d0d01ed3b3..2c696ad9f4e 100644 --- a/Standard/src/Arrays/Windows.qs +++ b/Standard/src/Arrays/Windows.qs @@ -88,9 +88,11 @@ namespace Microsoft.Quantum.Arrays { /// /// # Example /// The example below shows how to use `ApplyToEachWindow` to construct a parity function + /// ```qsharp /// operation Parity(qubits : Qubit[], target : Qubit) : Unit { /// ApplyToEachWindow(1, (_, q) => CNOT(q[0], target), qubits); /// } + /// ``` /// /// # Type Parameters /// ## 'T