From 6920eee3474f03fae331e9ac32dff34d88139d50 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 7 Jan 2020 17:17:24 -0800 Subject: [PATCH 01/27] Improve code quality with experimental linter. --- Standard/src/Arrays/Arrays.qs | 4 +- Standard/src/Arrays/Map.qs | 4 +- Standard/src/Canon/Combinators/ApplyIf.qs | 16 +-- Standard/src/Canon/Combinators/Bind.qs | 135 +++++++----------- Standard/src/Canon/Combinators/Compose.qs | 27 ++-- Standard/src/Canon/Combinators/Curry.qs | 105 ++++++-------- .../src/Canon/Combinators/OperationPow.qs | 91 ++++++------ Standard/src/Canon/Combinators/With.qs | 2 +- Standard/src/Canon/CommonGates.qs | 8 +- Standard/src/Canon/Deprecated.qs | 8 ++ Standard/src/Canon/Enumeration/Trotter.qs | 43 +++--- .../Canon/IterateThroughCartesianProduct.qs | 106 ++++++++++---- Standard/src/Canon/Parity.qs | 44 +++--- Standard/src/Characterization/Deprecated.qs | 14 ++ .../PhaseEstimation/Iterative.qs | 43 +++--- .../src/Characterization/ProcessTomography.qs | 16 --- Standard/src/Convert/Deprecated.qs | 2 +- Standard/src/Measurement/Registers.qs | 17 +++ Standard/src/Oracles/Convert.qs | 38 +++-- 19 files changed, 343 insertions(+), 380 deletions(-) create mode 100644 Standard/src/Characterization/Deprecated.qs diff --git a/Standard/src/Arrays/Arrays.qs b/Standard/src/Arrays/Arrays.qs index 740b4f195b4..c252056149f 100644 --- a/Standard/src/Arrays/Arrays.qs +++ b/Standard/src/Arrays/Arrays.qs @@ -63,7 +63,7 @@ namespace Microsoft.Quantum.Arrays { return array[0 .. Length(array) - 2]; } - function LookupImpl<'T> (array : 'T[], index : Int) : 'T { + function _Lookup<'T> (array : 'T[], index : Int) : 'T { return array[index]; } @@ -90,7 +90,7 @@ namespace Microsoft.Quantum.Arrays { /// where functions are used to avoid the need to record an entire array /// in memory. function LookupFunction<'T> (array : 'T[]) : (Int -> 'T) { - return LookupImpl(array, _); + return _Lookup(array, _); } /// # Summary diff --git a/Standard/src/Arrays/Map.qs b/Standard/src/Arrays/Map.qs index 4e28ccea7ad..dc80ee861ef 100644 --- a/Standard/src/Arrays/Map.qs +++ b/Standard/src/Arrays/Map.qs @@ -103,8 +103,8 @@ namespace Microsoft.Quantum.Arrays { /// The result type of the `action` operation. /// /// # Input - /// ## mapper - /// A function from `'T` to `'U` that is used to map elements. + /// ## action + /// A operation from `'T` to `'U` that is applied to each element. /// ## array /// An array of elements over `'T`. /// diff --git a/Standard/src/Canon/Combinators/ApplyIf.qs b/Standard/src/Canon/Combinators/ApplyIf.qs index 93662de16d4..d48c9fb5aa6 100644 --- a/Standard/src/Canon/Combinators/ApplyIf.qs +++ b/Standard/src/Canon/Combinators/ApplyIf.qs @@ -593,8 +593,8 @@ namespace Microsoft.Quantum.Canon { /// when `bit` is `false`. /// /// # Input - /// ## result - /// The measurement result used to determine if `trueOp` or `falseOp` is + /// ## bit + /// The boolean value used to determine if `trueOp` or `falseOp` is /// applied. /// ## trueOp /// The operation to be applied when `bit` is `true`. @@ -635,8 +635,8 @@ namespace Microsoft.Quantum.Canon { /// when `bit` is `false`. /// /// # Input - /// ## result - /// The measurement result used to determine if `trueOp` or `falseOp` is + /// ## bit + /// The boolean value used to determine if `trueOp` or `falseOp` is /// applied. /// ## trueOp /// The controllable operation to be applied when `bit` is `true`. @@ -677,8 +677,8 @@ namespace Microsoft.Quantum.Canon { /// when `bit` is `false`. /// /// # Input - /// ## result - /// The measurement result used to determine if `trueOp` or `falseOp` is + /// ## bit + /// The boolean value used to determine if `trueOp` or `falseOp` is /// applied. /// ## trueOp /// The adjointable operation to be applied when `bit` is `true`. @@ -719,8 +719,8 @@ namespace Microsoft.Quantum.Canon { /// when `bit` is `false`. /// /// # Input - /// ## result - /// The measurement result used to determine if `trueOp` or `falseOp` is + /// ## bit + /// The boolean value used to determine if `trueOp` or `falseOp` is /// applied. /// ## trueOp /// The unitary operation to be applied when `bit` is `true`. diff --git a/Standard/src/Canon/Combinators/Bind.qs b/Standard/src/Canon/Combinators/Bind.qs index 5d295731230..c617d0f769a 100644 --- a/Standard/src/Canon/Combinators/Bind.qs +++ b/Standard/src/Canon/Combinators/Bind.qs @@ -6,16 +6,12 @@ namespace Microsoft.Quantum.Canon { /// # See Also /// - Microsoft.Quantum.Canon.Bound - operation BindImpl<'T> (operations : ('T => Unit)[], target : 'T) : Unit - { - for (idxOperation in IndexRange(operations)) - { - let op = operations[idxOperation]; + operation _Bound<'T> (operations : ('T => Unit)[], target : 'T) : Unit { + for (op in operations) { op(target); } } - - + /// # Summary /// Given an array of operations acting on a single input, /// produces a new operation that @@ -49,37 +45,30 @@ namespace Microsoft.Quantum.Canon { /// - Microsoft.Quantum.Canon.BoundC /// - Microsoft.Quantum.Canon.BoundA /// - Microsoft.Quantum.Canon.BoundCA - function Bound<'T> (operations : ('T => Unit)[]) : ('T => Unit) - { - return BindImpl(operations, _); + function Bound<'T> (operations : ('T => Unit)[]) : ('T => Unit) { + return _Bound(operations, _); } - - + + /// # See Also /// - Microsoft.Quantum.Canon.BoundA - operation BindAImpl<'T> (operations : ('T => Unit is Adj)[], target : 'T) : Unit - { - body (...) - { - for (idxOperation in IndexRange(operations)) - { - let op = operations[idxOperation]; + operation _BoundA<'T> (operations : ('T => Unit is Adj)[], target : 'T) : Unit { + body (...) { + for (op in operations) { op(target); } } - + adjoint (...) { // TODO: replace with an implementation based on Reversed : 'T[] -> 'T[] // and AdjointAll : ('T => () is Adj)[] -> ('T => () is Adj). - for (idxOperation in Length(operations) - 1 .. -1 .. 0) - { - let op = Adjoint operations[idxOperation]; - op(target); + for (op in Reversed(operations)) { + Adjoint op(target); } } } - - + + /// # Summary /// Given an array of operations acting on a single input, /// produces a new operation that @@ -114,34 +103,27 @@ namespace Microsoft.Quantum.Canon { /// - Microsoft.Quantum.Canon.Bound function BoundA<'T> (operations : ('T => Unit is Adj)[]) : ('T => Unit is Adj) { - return BindAImpl(operations, _); + return _BoundA(operations, _); } - - + + /// # See Also /// - Microsoft.Quantum.Canon.BoundC - operation BindCImpl<'T> (operations : ('T => Unit is Ctl)[], target : 'T) : Unit - { - body (...) - { - for (idxOperation in IndexRange(operations)) - { - let op = operations[idxOperation]; + operation _BoundC<'T> (operations : ('T => Unit is Ctl)[], target : 'T) : Unit { + body (...) { + for (op in operations) { op(target); } } - - controlled (controls, ...) - { - for (idxOperation in IndexRange(operations)) - { - let op = Controlled operations[idxOperation]; - op(controls, target); + + controlled (controls, ...) { + for (op in operations) { + Controlled op(controls, target); } } } - - + + /// # Summary /// Given an array of operations acting on a single input, /// produces a new operation that @@ -174,54 +156,40 @@ namespace Microsoft.Quantum.Canon { /// /// # See Also /// - Microsoft.Quantum.Canon.Bound - function BoundC<'T> (operations : ('T => Unit is Ctl)[]) : ('T => Unit is Ctl) - { - return BindCImpl(operations, _); + function BoundC<'T> (operations : ('T => Unit is Ctl)[]) : ('T => Unit is Ctl) { + return _BoundC(operations, _); } - - + + /// # See Also /// - Microsoft.Quantum.Canon.BoundCA - operation BindCAImpl<'T> (operations : ('T => Unit is Adj + Ctl)[], target : 'T) : Unit - { - body (...) - { - for (idxOperation in IndexRange(operations)) - { - let op = operations[idxOperation]; + operation _BoundCA<'T> (operations : ('T => Unit is Adj + Ctl)[], target : 'T) : Unit { + body (...) { + for (idxOperation in operations) { op(target); } } - - adjoint (...) - { - for (idxOperation in Length(operations) - 1 .. -1 .. 0) - { - let op = Adjoint operations[idxOperation]; - op(target); + + adjoint (...) { + for (op in Reversed(operations)) { + Adjoint op(target); } } - - controlled (controls, ...) - { - for (idxOperation in IndexRange(operations)) - { - let op = Controlled operations[idxOperation]; - op(controls, target); + + controlled (controls, ...) { + for (op in operations) { + Controlled op(controls, target); } } - - controlled adjoint (controls, ...) - { - for (idxOperation in Length(operations) - 1 .. -1 .. 0) - { - let op = Controlled (Adjoint operations[idxOperation]); - op(controls, target); + + controlled adjoint (controls, ...) { + for (op in Reversed(operations)) { + Controlled Adjoint op(controls, target); } } } - - + + /// # Summary /// Given an array of operations acting on a single input, /// produces a new operation that @@ -255,11 +223,10 @@ namespace Microsoft.Quantum.Canon { /// /// # See Also /// - Microsoft.Quantum.Canon.Bound - function BoundCA<'T> (operations : ('T => Unit is Adj + Ctl)[]) : ('T => Unit is Adj + Ctl) - { - return BindCAImpl(operations, _); + function BoundCA<'T> (operations : ('T => Unit is Adj + Ctl)[]) : ('T => Unit is Adj + Ctl) { + return _BoundCA(operations, _); } - + } diff --git a/Standard/src/Canon/Combinators/Compose.qs b/Standard/src/Canon/Combinators/Compose.qs index 89d2ce40e94..517c769ac33 100644 --- a/Standard/src/Canon/Combinators/Compose.qs +++ b/Standard/src/Canon/Combinators/Compose.qs @@ -1,19 +1,17 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -namespace Microsoft.Quantum.Canon -{ - - function ComposeImpl<'T, 'U, 'V> (outer : ('U -> 'V), inner : ('T -> 'U), target : 'T) : 'V - { +namespace Microsoft.Quantum.Canon { + + function _Compose<'T, 'U, 'V> (outer : ('U -> 'V), inner : ('T -> 'U), target : 'T) : 'V { return outer(inner(target)); } - - + /// # Summary - /// Generates the composition of two functions. - /// - /// That is, given two functions $f$ and $g$, returns a new function representing + /// Returns the composition of two functions. + /// + /// # Description + /// Given two functions $f$ and $g$, returns a new function representing /// $f \circ g$. /// /// # Input @@ -33,11 +31,8 @@ namespace Microsoft.Quantum.Canon /// of the second function to be applied. /// ## 'V /// The output type of the second function to be applied. - function Compose<'T, 'U, 'V> (outer : ('U -> 'V), inner : ('T -> 'U)) : ('T -> 'V) - { - return ComposeImpl(outer, inner, _); + function Compose<'T, 'U, 'V> (outer : ('U -> 'V), inner : ('T -> 'U)) : ('T -> 'V) { + return _Compose(outer, inner, _); } - -} - +} diff --git a/Standard/src/Canon/Combinators/Curry.qs b/Standard/src/Canon/Combinators/Curry.qs index 18d365c72f6..fc6f2af45bf 100644 --- a/Standard/src/Canon/Combinators/Curry.qs +++ b/Standard/src/Canon/Combinators/Curry.qs @@ -3,15 +3,14 @@ namespace Microsoft.Quantum.Canon { - function CurryOpImpl<'T, 'U> (op : (('T, 'U) => Unit), arg1 : 'T) : ('U => Unit) - { + function _CurriedOp<'T, 'U> (op : (('T, 'U) => Unit), arg1 : 'T) : ('U => Unit) { return op(arg1, _); } - - + + /// # Summary /// Returns a curried version of an operation on two inputs. - /// + /// /// That is, given an operation with two inputs, this function applies Curry's isomorphism /// $f(x, y) \equiv f(x)(y)$ to return an operation of one input which /// returns an operation of one input. @@ -40,19 +39,16 @@ namespace Microsoft.Quantum.Canon { /// let partial = curried(x); /// partial(y); /// ``` - function CurriedOp<'T, 'U> (op : (('T, 'U) => Unit)) : ('T -> ('U => Unit)) - { - return CurryOpImpl(op, _); + function CurriedOp<'T, 'U> (op : (('T, 'U) => Unit)) : ('T -> ('U => Unit)) { + return _CurriedOp(op, _); } - - - operation UncurryOpImpl<'T, 'U> (curriedOp : ('T -> ('U => Unit)), first : 'T, second : 'U) : Unit - { + + operation _UncurryOp<'T, 'U> (curriedOp : ('T -> ('U => Unit)), first : 'T, second : 'U) : Unit { let innerOp = curriedOp(first); innerOp(second); } - - + + /// # Summary /// Given a function which returns operations, /// returns a new operation which takes both inputs @@ -77,22 +73,17 @@ namespace Microsoft.Quantum.Canon { /// - @"microsoft.quantum.canon.uncurryopca" function UncurriedOp<'T, 'U> (curriedOp : ('T -> ('U => Unit))) : (('T, 'U) => Unit) { - return UncurryOpImpl(curriedOp, _, _); + return _UncurryOp(curriedOp, _, _); } - - - operation UncurryOpCImpl<'T, 'U> (curriedOp : ('T -> ('U => Unit is Ctl)), first : 'T, second : 'U) : Unit - { - body (...) - { - let innerOp = curriedOp(first); - innerOp(second); - } - - controlled distribute; + + + operation _UncurriedOpC<'T, 'U>(curriedOp : ('T -> ('U => Unit is Ctl)), first : 'T, second : 'U) + : Unit is Ctl { + let innerOp = curriedOp(first); + innerOp(second); } - - + + /// # Summary /// Given a function which returns operations, /// returns a new operation which takes both inputs @@ -117,22 +108,17 @@ namespace Microsoft.Quantum.Canon { /// - @"microsoft.quantum.canon.uncurryop" function UncurriedOpC<'T, 'U> (curriedOp : ('T -> ('U => Unit is Ctl))) : (('T, 'U) => Unit is Ctl) { - return UncurryOpCImpl(curriedOp, _, _); + return _UncurriedOpC(curriedOp, _, _); } - - - operation UncurryOpAImpl<'T, 'U> (curriedOp : ('T -> ('U => Unit is Adj)), first : 'T, second : 'U) : Unit - { - body (...) - { - let innerOp = curriedOp(first); - innerOp(second); - } - - adjoint invert; + + + operation _UncurriedOpA<'T, 'U> (curriedOp : ('T -> ('U => Unit is Adj)), first : 'T, second : 'U) + : Unit is Adj { + let innerOp = curriedOp(first); + innerOp(second); } - - + + /// # Summary /// Given a function which returns operations, /// returns a new operation which takes both inputs @@ -155,26 +141,18 @@ namespace Microsoft.Quantum.Canon { /// /// # See Also /// - @"microsoft.quantum.canon.uncurryop" - function UncurriedOpA<'T, 'U> (curriedOp : ('T -> ('U => Unit is Adj))) : (('T, 'U) => Unit is Adj) - { - return UncurryOpAImpl(curriedOp, _, _); + function UncurriedOpA<'T, 'U> (curriedOp : ('T -> ('U => Unit is Adj))) : (('T, 'U) => Unit is Adj) { + return _UncurriedOpA(curriedOp, _, _); } - - - operation UncurryOpCAImpl<'T, 'U> (curriedOp : ('T -> ('U => Unit is Ctl + Adj)), first : 'T, second : 'U) : Unit - { - body (...) - { - let innerOp = curriedOp(first); - innerOp(second); - } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; + + + operation _UncurriedOpCA<'T, 'U> (curriedOp : ('T -> ('U => Unit is Ctl + Adj)), first : 'T, second : 'U) + : Unit is Adj + Ctl { + let innerOp = curriedOp(first); + innerOp(second); } - - + + /// # Summary /// Given a function which returns operations, /// returns a new operation which takes both inputs @@ -197,11 +175,10 @@ namespace Microsoft.Quantum.Canon { /// /// # See Also /// - @"microsoft.quantum.canon.uncurryop" - function UncurriedOpCA<'T, 'U> (curriedOp : ('T -> ('U => Unit is Ctl + Adj))) : (('T, 'U) => Unit is Ctl + Adj) - { - return UncurryOpCAImpl(curriedOp, _, _); + function UncurriedOpCA<'T, 'U> (curriedOp : ('T -> ('U => Unit is Ctl + Adj))) : (('T, 'U) => Unit is Ctl + Adj) { + return _UncurriedOpCA(curriedOp, _, _); } - + } diff --git a/Standard/src/Canon/Combinators/OperationPow.qs b/Standard/src/Canon/Combinators/OperationPow.qs index fbd8c8a0b14..091cc9e2806 100644 --- a/Standard/src/Canon/Combinators/OperationPow.qs +++ b/Standard/src/Canon/Combinators/OperationPow.qs @@ -1,46 +1,43 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -namespace Microsoft.Quantum.Canon -{ - - operation OperationPowImpl<'T> (oracle : ('T => Unit), power : Int, target : 'T) : Unit { - for (idxApplication in 0 .. power - 1) - { +namespace Microsoft.Quantum.Canon { + + operation _OperationPow<'T> (oracle : ('T => Unit), power : Int, target : 'T) + : Unit { + for (idxApplication in 0 .. power - 1) { oracle(target); } } - - - operation OperationPowImplC<'T> (oracle : ('T => Unit is Ctl), power : Int, target : 'T) : Unit is Ctl { - for (idxApplication in 0 .. power - 1) - { + + + operation _OperationPowC<'T> (oracle : ('T => Unit is Ctl), power : Int, target : 'T) + : Unit is Ctl { + for (idxApplication in 0 .. power - 1) { oracle(target); } } - - - operation OperationPowImplA<'T> (oracle : ('T => Unit is Adj), power : Int, target : 'T) : Unit is Adj - { - for (idxApplication in 0 .. power - 1) - { + + + operation _OperationPowA<'T> (oracle : ('T => Unit is Adj), power : Int, target : 'T) + : Unit is Adj { + for (idxApplication in 0 .. power - 1) { oracle(target); } } - - - operation OperationPowImplCA<'T> (oracle : ('T => Unit is Adj + Ctl), power : Int, target : 'T) : Unit is Adj + Ctl - { - for (idxApplication in 0 .. power - 1) - { + + + operation _OperationPowCA<'T> (oracle : ('T => Unit is Adj + Ctl), power : Int, target : 'T) + : Unit is Adj + Ctl { + for (idxApplication in 0 .. power - 1) { oracle(target); } } - - + + /// # Summary /// Raises an operation to a power. - /// + /// /// That is, given an operation representing a gate $U$, returns a new operation /// $U^m$ for a power $m$. /// @@ -61,16 +58,15 @@ namespace Microsoft.Quantum.Canon /// - @"microsoft.quantum.canon.operationpowc" /// - @"microsoft.quantum.canon.operationpowa" /// - @"microsoft.quantum.canon.operationpowca" - function OperationPow<'T> (oracle : ('T => Unit), power : Int) : ('T => Unit) - { - return OperationPowImpl(oracle, power, _); + function OperationPow<'T> (oracle : ('T => Unit), power : Int) : ('T => Unit) { + return _OperationPow(oracle, power, _); } - - + + /// # Summary /// Raises an operation to a power. /// The modifier `C` indicates that the operation is controllable. - /// + /// /// That is, given an operation representing a gate $U$, returns a new operation /// $U^m$ for a power $m$. /// @@ -89,16 +85,15 @@ namespace Microsoft.Quantum.Canon /// /// # See Also /// - @"microsoft.quantum.canon.operationpow" - function OperationPowC<'T> (oracle : ('T => Unit is Ctl), power : Int) : ('T => Unit is Ctl) - { - return OperationPowImplC(oracle, power, _); + function OperationPowC<'T> (oracle : ('T => Unit is Ctl), power : Int) : ('T => Unit is Ctl) { + return _OperationPowC(oracle, power, _); } - - + + /// # Summary /// Raises an operation to a power. /// The modifier `A` indicates that the operation is adjointable. - /// + /// /// That is, given an operation representing a gate $U$, returns a new operation /// $U^m$ for a power $m$. /// @@ -117,16 +112,15 @@ namespace Microsoft.Quantum.Canon /// /// # See Also /// - @"microsoft.quantum.canon.operationpow" - function OperationPowA<'T> (oracle : ('T => Unit is Adj), power : Int) : ('T => Unit is Adj) - { - return OperationPowImplA(oracle, power, _); + function OperationPowA<'T> (oracle : ('T => Unit is Adj), power : Int) : ('T => Unit is Adj) { + return _OperationPowA(oracle, power, _); } - - + + /// # Summary /// Raises an operation to a power. /// The modifier `A` indicates that the operation is controllable and adjointable. - /// + /// /// That is, given an operation representing a gate $U$, returns a new operation /// $U^m$ for a power $m$. /// @@ -145,11 +139,8 @@ namespace Microsoft.Quantum.Canon /// /// # See Also /// - @"microsoft.quantum.canon.operationpow" - function OperationPowCA<'T> (oracle : ('T => Unit is Ctl + Adj), power : Int) : ('T => Unit is Ctl + Adj) - { - return OperationPowImplCA(oracle, power, _); + function OperationPowCA<'T> (oracle : ('T => Unit is Ctl + Adj), power : Int) : ('T => Unit is Ctl + Adj) { + return _OperationPowCA(oracle, power, _); } - -} - +} diff --git a/Standard/src/Canon/Combinators/With.qs b/Standard/src/Canon/Combinators/With.qs index a01f482f428..08908862352 100644 --- a/Standard/src/Canon/Combinators/With.qs +++ b/Standard/src/Canon/Combinators/With.qs @@ -153,7 +153,7 @@ namespace Microsoft.Quantum.Canon { return ApplyWithA(outerOperation, innerOperation, _); } - // # Summary + /// # Summary /// Given two operations, applies one as conjugated with the other. /// /// # Description diff --git a/Standard/src/Canon/CommonGates.qs b/Standard/src/Canon/CommonGates.qs index fafc2dcd31f..4d5feb63975 100644 --- a/Standard/src/Canon/CommonGates.qs +++ b/Standard/src/Canon/CommonGates.qs @@ -219,14 +219,12 @@ namespace Microsoft.Quantum.Canon { /// \end{align} /// /// # Input - /// ## qubit + /// ## target /// Qubit to which the gate should be applied. /// /// # See Also - operation HY (target : Qubit) : Unit - { - body (...) - { + operation HY (target : Qubit) : Unit { + body (...) { H(target); S(target); } diff --git a/Standard/src/Canon/Deprecated.qs b/Standard/src/Canon/Deprecated.qs index 65602fd4116..79e30a15744 100644 --- a/Standard/src/Canon/Deprecated.qs +++ b/Standard/src/Canon/Deprecated.qs @@ -3,6 +3,7 @@ namespace Microsoft.Quantum.Canon { open Microsoft.Quantum.Arithmetic; + open Microsoft.Quantum.Logical; /// # Deprecated /// This operation has been removed. @@ -18,4 +19,11 @@ namespace Microsoft.Quantum.Canon { ApplyQuantumFourierTransform(qs); } + /// # Deprecated + /// Please use @"microsoft.quantum.logical.xor". + @Deprecated("Microsoft.Quantum.Logical.Xor") + function XOR(bit1 : Bool, bit2 : Bool) : Bool { + return Xor(bit1, bit2); + } + } diff --git a/Standard/src/Canon/Enumeration/Trotter.qs b/Standard/src/Canon/Enumeration/Trotter.qs index b8229e14ff7..66ee3020f2b 100644 --- a/Standard/src/Canon/Enumeration/Trotter.qs +++ b/Standard/src/Canon/Enumeration/Trotter.qs @@ -108,30 +108,23 @@ namespace Microsoft.Quantum.Canon { /// Multiplier on size of each step of the simulation. /// ## target /// A quantum register on which the operations act. - operation _TrotterArbitraryImplCA<'T> (order:Int, (nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)), stepSize : Double, target : 'T) : Unit - { - body (...) - { - if(order > 2){ - let stepSizeOuter = _TrotterStepSize(order); - let stepSizeInner = 1.0 - 4.0 * stepSizeOuter; - _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); - _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); - _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeInner * stepSize, target); - _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); - _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); - } - elif(order == 2){ - _Trotter2ImplCA((nSteps, op), stepSize, target); - } - else{ - _Trotter1ImplCA((nSteps, op), stepSize, target); - } + operation _TrotterArbitraryImplCA<'T> (order:Int, (nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)), stepSize : Double, target : 'T) + : Unit is Adj + Ctl { + if(order > 2){ + let stepSizeOuter = _TrotterStepSize(order); + let stepSizeInner = 1.0 - 4.0 * stepSizeOuter; + _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); + _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); + _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeInner * stepSize, target); + _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); + _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); + } + elif(order == 2){ + _Trotter2ImplCA((nSteps, op), stepSize, target); + } + else{ + _Trotter1ImplCA((nSteps, op), stepSize, target); } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; } /// # Summary @@ -152,9 +145,9 @@ namespace Microsoft.Quantum.Canon { /// `Qubit[]` or `Qubit`. /// /// # Input - /// ### nSteps + /// ## nSteps /// The number of operations to be decomposed into time steps. - /// ### op + /// ## op /// An operation which accepts an index input (type `Int`) and a time /// input (type `Double`) for decomposition. /// ## trotterOrder diff --git a/Standard/src/Canon/IterateThroughCartesianProduct.qs b/Standard/src/Canon/IterateThroughCartesianProduct.qs index 4773ad77e0d..6d00bec54b7 100644 --- a/Standard/src/Canon/IterateThroughCartesianProduct.qs +++ b/Standard/src/Canon/IterateThroughCartesianProduct.qs @@ -3,54 +3,102 @@ namespace Microsoft.Quantum.Canon { open Microsoft.Quantum.Arrays; - + /// # Summary - /// Iterates a variable, say `arr`, through a Cartesian product - /// [ 0, bounds[0]-1 ] × [ 0, bounds[1]-1 ] × [ 0, bounds[Length(bounds)-1]-1 ] - /// and calls op(arr) for every element of the Cartesian product - operation IterateThroughCartesianProduct (bounds : Int[], op : (Int[] => Unit)) : Unit - { + /// Applies an operation for each index in the Cartesian product of several + /// ranges. + /// + /// # Description + /// Iteratively applies an operation for each element of the Cartesian product + /// of `0..(bounds[0] - 1)`, `0..(bounds[1] - 1)`, ..., `0..(bounds[Length(bounds) - 1] - 1)` + /// + /// # Input + /// ## bounds + /// An array specifying the ranges to be iterated over, with each range + /// being specified as an integer length. + /// ## op + /// An operation to be called for each element of the given Cartesian product. + /// + /// # Example + /// Given an operation `op`, the following two snippets are equivalent: + /// ```Q# + /// IterateThroughCartesianProduct([3, 4, 5], op); + /// ``` + /// ```Q# + /// op([0, 0, 0]); + /// op([1, 0, 0]); + /// op([2, 0, 0]); + /// op([0, 1, 0]); + /// // ... + /// op([0, 3, 0]); + /// op([0, 0, 1]); + /// // + /// op([2, 3, 4]); + /// ``` + /// + /// # See Also + /// - Microsoft.Quantum.Canon.IterateThroughCartesianPower + operation IterateThroughCartesianProduct(bounds : Int[], op : (Int[] => Unit)) : Unit { mutable arr = new Int[Length(bounds)]; mutable finished = false; - - repeat - { - if (not finished) - { + + repeat { + if (not finished) { op(arr); } } until (finished) - fixup - { + fixup { //computes the next element in the Cartesian product set arr w/= 0 <- arr[0] + 1; - - for (i in 0 .. Length(arr) - 2) - { - if (arr[i] == bounds[i]) - { + + for (i in 0 .. Length(arr) - 2) { + if (arr[i] == bounds[i]) { set arr w/= i + 1 <- arr[i + 1] + 1; set arr w/= i <- 0; } } - - if (arr[Length(arr) - 1] == bounds[Length(arr) - 1]) - { + + if (arr[Length(arr) - 1] == bounds[Length(arr) - 1]) { set finished = true; } } } - - + + /// # Summary - /// Iterates a variable, say arr, through Cartesian product - /// [ 0, bound - 1 ] × [ 0, bound - 1 ] × [ 0, bound - 1 ] - /// and calls op(arr) for every element of the Cartesian product + /// Applies an operation for each index in the Cartesian power of an + /// integer range. + /// + /// # Description + /// Iteratively applies an operation for each element of a Cartesian power + /// of the range `0..(bound - 1)`. + /// + /// # Input + /// ## bound + /// A specification of the range to be iterated over, given as the length + /// of the range. + /// ## op + /// An operation to be called for each element of the given Cartesian power. + /// + /// # Example + /// Given an operation `op`, the following two snippets are equivalent: + /// ```Q# + /// IterateThroughCartesianPower(2, 3, op); + /// ``` + /// ```Q# + /// op([0, 0]); + /// op([1, 0]); + /// op([2, 0]); + /// op([0, 1]); + /// // .. + /// op([2, 2]); + /// ``` + /// + /// # See Also + /// - Microsoft.Quantum.Canon.IterateThroughCartesianProduct operation IterateThroughCartesianPower (power : Int, bound : Int, op : (Int[] => Unit)) : Unit { IterateThroughCartesianProduct(ConstantArray(power, bound), op); } - -} - +} diff --git a/Standard/src/Canon/Parity.qs b/Standard/src/Canon/Parity.qs index 46f96714d1d..874a5829035 100644 --- a/Standard/src/Canon/Parity.qs +++ b/Standard/src/Canon/Parity.qs @@ -5,29 +5,29 @@ namespace Microsoft.Quantum.Canon { open Microsoft.Quantum.Intrinsic; /// # Summary - /// Computes the parity of an array of qubits in-place. + /// Computes the parity of a register of qubits in-place. /// - /// It follows the pattern - /// $\ket{q_0} \ket{q_0 \oplus q_1} \ket{q_0 \oplus q_1 \oplus q_2} \cdots$. + /// # Description + /// This operation transforms the state of its input as + /// $$ + /// \begin{align} + /// \ket{q_0} \ket{q_1} \cdots \ket{q_{n - 1}} & \mapsto + /// \ket{q_0} \ket{q_0 \oplus q_1} \ket{q_0 \oplus q_1 \oplus q_2} \cdots + /// \ket{q_0 \oplus \cdots \oplus q_{n - 1}}. + /// \end{align} + /// $$ /// /// # Input /// ## qubits - /// Array of qubits on which parity is computed - /// and stored. - operation CNOTChain(qubits: Qubit[]) : Unit { - body (...) { - for (idxQubit in 0..Length(qubits) - 2){ - CNOT(qubits[idxQubit], qubits[idxQubit + 1]); - } - } - adjoint auto; - controlled auto; - adjoint controlled auto; + /// Array of qubits whose parity is to be computed and stored. + operation CNOTChain(qubits : Qubit[]) : Unit is Adj + Ctl { + ApplyToEachCA(CNOT, Zip(Most(qubits), Rest(qubits))); } /// # Summary /// Computes the parity of an array of qubits into a target qubit. /// + /// # Description /// If the array is initially in the state /// $\ket{q_0} \ket{q_1} \cdots \ket{q_{\text{target}}}$, /// the final state is given by @@ -48,20 +48,8 @@ namespace Microsoft.Quantum.Canon { /// ```qsharp /// CNOTChain(qs); /// ``` - operation CNOTChainTarget(qubits: Qubit[], targetQubit: Qubit) : Unit { - body (...) { - let allQubits = qubits + [targetQubit]; - CNOTChain(allQubits); - } - adjoint auto; - controlled auto; - adjoint controlled auto; - } - - /// # Summary - /// This computes the exclusive-OR of two bits. - function XOR(bit1: Bool, bit2: Bool) : Bool { - return (bit1 or bit2) and (not bit1 or not bit2); + operation CNOTChainTarget(qubits : Qubit[], targetQubit : Qubit) : Unit { + CNOTChain(qubits + [targetQubit]); } } diff --git a/Standard/src/Characterization/Deprecated.qs b/Standard/src/Characterization/Deprecated.qs new file mode 100644 index 00000000000..c173160853b --- /dev/null +++ b/Standard/src/Characterization/Deprecated.qs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Characterization { + open Microsoft.Quantum.Measurement as Meas; + + /// # Deprecated + /// Please use @"microsoft.quantum.measurement.measureAllZ". + @Deprecated("Microsoft.Quantum.Measurement.MeasureAllZ") + operation MeasureAllZ(register : Qubit[]) : Result { + return Meas.MeasureAllZ(register); + } + +} diff --git a/Standard/src/Characterization/PhaseEstimation/Iterative.qs b/Standard/src/Characterization/PhaseEstimation/Iterative.qs index 48823f2952b..93e351b2674 100644 --- a/Standard/src/Characterization/PhaseEstimation/Iterative.qs +++ b/Standard/src/Characterization/PhaseEstimation/Iterative.qs @@ -18,17 +18,17 @@ namespace Microsoft.Quantum.Characterization { // let DiscreteOracle = OracleToDiscrete(U); // DiscretePhaseEstimationIteration(oracle, pow, theta, targetState, control); // let datum = M(control); - + // This design then enables providing more efficient implementations of U^m // to be provided by the user for specific U, while providing a sensible // "default" for operations which cannot be fast-forwarded by taking advantage // of their definitions. - + // Finally, we also ensure that quantum arguments are placed last to follow // standard conventions for partial application. In particular, this allows for // the discrete and continuous phase estimation iterations to be used in // an allocate-op-measure pattern; we may soon want to abstract that away. - + /// # Summary /// Performs a single iteration of an iterative (classically-controlled) phase /// estimation algorithm using integer powers of a unitary oracle. @@ -46,7 +46,9 @@ namespace Microsoft.Quantum.Characterization { /// acting on the target state. /// ## targetState /// Register of state acted upon by the given unitary oracle. - operation DiscretePhaseEstimationIteration (oracle : DiscreteOracle, power : Int, theta : Double, targetState : Qubit[], controlQubit : Qubit) : Unit + /// ## controlQubit + /// An auxillary qubit used to control the application of the given oracle. + operation DiscretePhaseEstimationIteration(oracle : DiscreteOracle, power : Int, theta : Double, targetState : Qubit[], controlQubit : Qubit) : Unit { // NB: We accept the control qubit as input so that we can allow for this operation // to subject to the adjoint and control modifiers (that is, such that we do not need @@ -56,22 +58,22 @@ namespace Microsoft.Quantum.Characterization { // Find the actual inversion angle by rescaling with the power of the // oracle. let inversionAngle = -theta * IntAsDouble(power); - + // Prepare the control qubit. H(controlQubit); Rz(inversionAngle, controlQubit); Controlled oracle!([controlQubit], (power, targetState)); - + // Return the control qubit to the appropriate measurement basis. H(controlQubit); } - + adjoint invert; controlled distribute; controlled adjoint distribute; } - - + + /// # Summary /// Performs a single iteration of an iterative (classically-controlled) phase /// estimation algorithm using arbitrary real powers of a unitary oracle. @@ -94,35 +96,22 @@ namespace Microsoft.Quantum.Characterization { body (...) { let inversionAngle = -(theta * time); - + // Prepare the control qubit. H(controlQubit); Rz(inversionAngle, controlQubit); Controlled oracle!([controlQubit], (time, targetState)); - + // Return the control qubit to the appropriate measurement basis. H(controlQubit); } - + adjoint invert; controlled distribute; controlled adjoint distribute; } - - - operation PrepAndMeasurePhaseEstImpl (wInv : Double, t : Double, op : ((Double, Double, Qubit) => Unit)) : Result - { - mutable datum = Zero; - - using (register = Qubit[1]) - { - op(t, wInv, register[0]); - set datum = MResetZ(register[0]); - } - - return datum; - } - + + } diff --git a/Standard/src/Characterization/ProcessTomography.qs b/Standard/src/Characterization/ProcessTomography.qs index 739de791934..dc027054c0f 100644 --- a/Standard/src/Characterization/ProcessTomography.qs +++ b/Standard/src/Characterization/ProcessTomography.qs @@ -8,22 +8,6 @@ namespace Microsoft.Quantum.Characterization { open Microsoft.Quantum.Preparation; open Microsoft.Quantum.Arrays; - /// # Summary - /// Jointly measures a register of qubits in the Pauli Z basis. - /// - /// In other words, measures the operation $Z \otimes Z \otimes \cdots \otimes Z$ on - /// a given register. - /// - /// # Input - /// ## register - /// The register to be measured. - /// - /// # Output - /// The result of measuring $Z \otimes Z \otimes \cdots \otimes Z$. - operation MeasureAllZ (register : Qubit[]) : Result { - return Measure(ConstantArray(Length(register), PauliZ), register); - } - /// # Summary /// Measures the identity operator on a register /// of qubits. diff --git a/Standard/src/Convert/Deprecated.qs b/Standard/src/Convert/Deprecated.qs index 56ff2280951..e1b7f3ed0e2 100644 --- a/Standard/src/Convert/Deprecated.qs +++ b/Standard/src/Convert/Deprecated.qs @@ -6,8 +6,8 @@ namespace Microsoft.Quantum.Canon { /// # Deprecated /// This function has been removed. + @Deprecated("") function AsQubitArray (arr : Qubit[]) : Qubit[] { - // TODO: add call to _Removed. return arr; } diff --git a/Standard/src/Measurement/Registers.qs b/Standard/src/Measurement/Registers.qs index e3b3e515af9..f5052180bf9 100644 --- a/Standard/src/Measurement/Registers.qs +++ b/Standard/src/Measurement/Registers.qs @@ -72,4 +72,21 @@ namespace Microsoft.Quantum.Measurement { return ForEach(M, targets); } + /// # Summary + /// Jointly measures a register of qubits in the Pauli Z basis. + /// + /// # Description + /// Measures a register of qubits in the $Z \otimes Z \otimes \cdots \otimes Z$ + /// basis, representing the parity of the entire register. + /// + /// # Input + /// ## register + /// The register to be measured. + /// + /// # Output + /// The result of measuring $Z \otimes Z \otimes \cdots \otimes Z$. + operation MeasureAllZ (register : Qubit[]) : Result { + return Measure(ConstantArray(Length(register), PauliZ), register); + } + } diff --git a/Standard/src/Oracles/Convert.qs b/Standard/src/Oracles/Convert.qs index 3b804227e36..6eaf4a64a0f 100644 --- a/Standard/src/Oracles/Convert.qs +++ b/Standard/src/Oracles/Convert.qs @@ -104,40 +104,34 @@ namespace Microsoft.Quantum.Oracles { /// # Summary /// Implementation of . - operation ReflectionOracleFromDeterministicStateOracleImpl (phase : Double, oracle : DeterministicStateOracle, systemRegister : Qubit[]) : Unit - { - body (...) - { - ApplyWithCA(Adjoint oracle!, RAll0(phase, _), systemRegister); - } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; + operation _ReflectionOracleFromDeterministicStateOracle(phase : Double, oracle : DeterministicStateOracle, systemRegister : Qubit[]) + : Unit is Adj + Ctl { + ApplyWithCA(Adjoint oracle!, RAll0(phase, _), systemRegister); } - /// # Summary /// Constructs reflection about a given state from an oracle. /// - /// Given the oracle $O$ of type - /// , - /// the result of this function is a reflection around the state $\ket{\psi}$ - /// where $O\ket{0} = \ket{\psi}$. + /// # Description + /// Given a determinstic state preparation oracle represented by a unitary + /// matrix $O$, + /// the result of this function is an oracle that applies a reflection + /// around the state $\ket{\psi}$ prepared by the oracle $O$; that is, + /// the state $\ket{\psi}$ such that $O\ket{0} = \ket{\psi}$. /// /// # Input /// ## oracle - /// Oracle of type "DeterministicStateOracle" + /// An oracle that prepares copies of the state $\ket{\psi}$. /// /// # Output - /// A `ReflectionOracle` that reflects about the state $\ket{\psi}$. + /// An oracle that reflects about the state $\ket{\psi}$. /// /// # See Also - /// - DeterministicStateOracle - /// - ReflectionOracle - function ReflectionOracleFromDeterministicStateOracle (oracle : DeterministicStateOracle) : ReflectionOracle - { - return ReflectionOracle(ReflectionOracleFromDeterministicStateOracleImpl(_, oracle, _)); + /// - Microsoft.Quantum.Oracles.DeterministicStateOracle + /// - Microsoft.Quantum.Oracles.ReflectionOracle + function ReflectionOracleFromDeterministicStateOracle(oracle : DeterministicStateOracle) + : ReflectionOracle { + return ReflectionOracle(_ReflectionOracleFromDeterministicStateOracle(_, oracle, _)); } /// # Summary From ac426589eea83262278420b2963f7a70b1600210 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 7 Jan 2020 17:20:36 -0800 Subject: [PATCH 02/27] Fixed a couple mistakes in previous cleanup. --- Standard/src/Canon/Combinators/Bind.qs | 2 +- Standard/src/Canon/Parity.qs | 1 + Standard/src/Oracles/Convert.qs | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Standard/src/Canon/Combinators/Bind.qs b/Standard/src/Canon/Combinators/Bind.qs index c617d0f769a..0d65c7f9449 100644 --- a/Standard/src/Canon/Combinators/Bind.qs +++ b/Standard/src/Canon/Combinators/Bind.qs @@ -165,7 +165,7 @@ namespace Microsoft.Quantum.Canon { /// - Microsoft.Quantum.Canon.BoundCA operation _BoundCA<'T> (operations : ('T => Unit is Adj + Ctl)[], target : 'T) : Unit { body (...) { - for (idxOperation in operations) { + for (op in operations) { op(target); } } diff --git a/Standard/src/Canon/Parity.qs b/Standard/src/Canon/Parity.qs index 874a5829035..284622fe4e6 100644 --- a/Standard/src/Canon/Parity.qs +++ b/Standard/src/Canon/Parity.qs @@ -3,6 +3,7 @@ namespace Microsoft.Quantum.Canon { open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Arrays; /// # Summary /// Computes the parity of a register of qubits in-place. diff --git a/Standard/src/Oracles/Convert.qs b/Standard/src/Oracles/Convert.qs index 6eaf4a64a0f..25484cba36a 100644 --- a/Standard/src/Oracles/Convert.qs +++ b/Standard/src/Oracles/Convert.qs @@ -149,7 +149,7 @@ namespace Microsoft.Quantum.Oracles { /// ## Example /// `OracleToDiscrete(U)(3, target)` is equivalent to `U(target)` repeated three times. function OracleToDiscrete (blackBoxOracle : (Qubit[] => Unit is Adj + Ctl)) : DiscreteOracle { - return DiscreteOracle(OperationPowImplCA(blackBoxOracle, _, _)); + return DiscreteOracle(_OperationPowCA(blackBoxOracle, _, _)); } } From 5e9794482df26e8f13f54bfbd4b55f297cc0dd63 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 8 Jan 2020 13:10:14 -0800 Subject: [PATCH 03/27] More fixes to resolve linting issues. --- Standard/src/Arithmetic/Arithmetic.qs | 44 ++-- Standard/src/Arithmetic/Asserts.qs | 1 + Standard/src/Arithmetic/Comparators.qs | 16 +- Standard/src/Arithmetic/Deprecated.qs | 17 +- Standard/src/Arithmetic/Integer.qs | 221 ++++++++---------- .../Canon/Combinators/ApplyMultiControlled.qs | 33 +-- Standard/src/Canon/Deprecated.qs | 7 + .../Canon/IterateThroughCartesianProduct.qs | 3 + Standard/src/Canon/Parity.qs | 2 +- Standard/src/Simulation/BlockEncoding.qs | 114 +++++---- .../QubitizationPauliEvolutionSet.qs | 62 +++-- 11 files changed, 254 insertions(+), 266 deletions(-) diff --git a/Standard/src/Arithmetic/Arithmetic.qs b/Standard/src/Arithmetic/Arithmetic.qs index 1e159d11862..0427e251379 100644 --- a/Standard/src/Arithmetic/Arithmetic.qs +++ b/Standard/src/Arithmetic/Arithmetic.qs @@ -8,7 +8,12 @@ namespace Microsoft.Quantum.Arithmetic { open Microsoft.Quantum.Arrays; /// # Summary - /// Applies `X` operations to qubits in a little-endian register based on 1 bits in an integer. + /// Applies a bitwise-XOR operation between a classical integer and an + /// integer represented by a register of qubits. + /// + /// # Description + /// Applies `X` operations to qubits in a little-endian register based on + /// 1 bits in an integer. /// /// Let us denote `value` by a and let y be an unsigned integer encoded in `target`, /// then `InPlaceXorLE` performs an operation given by the following map: @@ -19,20 +24,19 @@ namespace Microsoft.Quantum.Arithmetic { /// An integer which is assumed to be non-negative. /// ## target /// A quantum register which is used to store `value` in little-endian encoding. - operation ApplyXorInPlace(value : Int, target : LittleEndian) : Unit { - body (...) { - ApplyToEachCA( - CControlledCA(X), - Zip(IntAsBoolArray(value, Length(target!)), target!) - ); - } - - adjoint auto; - controlled auto; - controlled adjoint auto; + operation ApplyXorInPlace(value : Int, target : LittleEndian) + : Unit is Adj + Ctl { + ApplyToEachCA( + CControlledCA(X), + Zip(IntAsBoolArray(value, Length(target!)), target!) + ); } /// # Summary + /// Applies the three-qubit majority operation in-place on a register of + /// qubits. + /// + /// # Description /// This computes the Majority function in-place on 3 qubits. /// /// If we denote output qubit as $z$ and input qubits as $x$ and $y$, @@ -45,17 +49,13 @@ namespace Microsoft.Quantum.Arithmetic { /// and stored in this qubit. /// ## input /// Second and third input qubits. - operation InPlaceMajority(output: Qubit, input: Qubit[]) : Unit { - body (...) { - if (Length(input) == 2) { - MAJ(input[0], input[1], output); - } else { - fail $"The in-place majority operation on {Length(input)} is qubits not yet implemented."; - } + operation ApplyMajorityInPlace(output: Qubit, input: Qubit[]) + : Unit is Adj + Ctl { + if (Length(input) == 2) { + MAJ(input[0], input[1], output); + } else { + fail $"The in-place majority operation on {Length(input)} is qubits not yet implemented."; } - adjoint auto; - controlled auto; - adjoint controlled auto; } /// # Summary diff --git a/Standard/src/Arithmetic/Asserts.qs b/Standard/src/Arithmetic/Asserts.qs index 41cf8e722b6..48d8cbec875 100644 --- a/Standard/src/Arithmetic/Asserts.qs +++ b/Standard/src/Arithmetic/Asserts.qs @@ -12,6 +12,7 @@ namespace Microsoft.Quantum.Arithmetic { /// Asserts that the probability of a specific state of a quantum register has the /// expected value. /// + /// # Description /// Given an $n$-qubit quantum state $\ket{\psi}=\sum^{2^n-1}_{j=0}\alpha_j \ket{j}$, /// asserts that the probability $|\alpha_j|^2$ of the state $\ket{j}$ indexed by $j$ /// has the expected value. diff --git a/Standard/src/Arithmetic/Comparators.qs b/Standard/src/Arithmetic/Comparators.qs index 3f1d5d3cc10..c6898baa6f6 100644 --- a/Standard/src/Arithmetic/Comparators.qs +++ b/Standard/src/Arithmetic/Comparators.qs @@ -7,16 +7,20 @@ namespace Microsoft.Quantum.Arithmetic { open Microsoft.Quantum.Arrays; /// # Summary - /// This unitary tests if two integers `x` and `y` stored in equal-size qubit registers - /// satisfy `x > y`. If true, 1 is XORed into an output - /// qubit. Otherwise, 0 is XORed into an output qubit. + /// This operation tests if an integer represented by a register of qubits + /// is greater than another integer, applying an XOR of the result onto an + /// output qubit. /// - /// In other words, this unitary $U$ satisfies: + /// # Description + /// Given two integers `x` and `y` stored in equal-size qubit registers, + /// this operation checks if they satisfy `x > y`. If true, 1 is + /// XORed into an output qubit. Otherwise, 0 is XORed into an output qubit. + /// In other words, this operation can be represented by the unitary /// $$ /// \begin{align} - /// U\ket{x}\ket{y}\ket{z}=\ket{x}\ket{y}\ket{z\oplus (x>y)}. + /// U\ket{x}\ket{y}\ket{z} = \ket{x}\ket{y}\ket{z\oplus (x>y)}. /// \end{align} - /// $$. + /// $$ /// /// # Input /// ## x diff --git a/Standard/src/Arithmetic/Deprecated.qs b/Standard/src/Arithmetic/Deprecated.qs index b7d27b407b1..062338ce41a 100644 --- a/Standard/src/Arithmetic/Deprecated.qs +++ b/Standard/src/Arithmetic/Deprecated.qs @@ -46,7 +46,7 @@ namespace Microsoft.Quantum.Canon { operation ApplyReversedOpBigEndianA(op : (BigEndian => Unit is Adj), register : LittleEndian) : Unit is Adj { ApplyReversedOpBEA(op, register); } - + /// # Deprecated /// Please use @"Microsoft.Quantum.Arithmetic.ApplyReversedOpBEC". @Deprecated("Microsoft.Quantum.Arithmetic.ApplyReversedOpBEC") @@ -193,4 +193,19 @@ namespace Microsoft.Quantum.Canon { CopyMostSignificantBit(from, target); } + /// # Deprecated + /// Please use @"microsoft.quantum.canon.applycnotchain". + @Deprecated("Microsoft.Quantum.Canon.ApplyCNOTChain") + operation CascadeCNOT (register : Qubit[]) : Unit { + Microsoft.Quantum.Canon.ApplyCNOTChain(register); + } + + /// # Deprecated + /// Please use @"microsoft.quantum.arithmetic.applymajorityinplace". + @Deprecated("Microsoft.Quantum.Arithmetic.ApplyMajorityInPlace") + operation InPlaceMajority(output: Qubit, input: Qubit[]) + : Unit is Adj + Ctl { + ApplyMajorityInPlace(output, input); + } + } diff --git a/Standard/src/Arithmetic/Integer.qs b/Standard/src/Arithmetic/Integer.qs index 89ef34fd08a..1b2bfffa353 100644 --- a/Standard/src/Arithmetic/Integer.qs +++ b/Standard/src/Arithmetic/Integer.qs @@ -23,7 +23,8 @@ namespace Microsoft.Quantum.Arithmetic { /// `summand1` and `summand2`. /// ## carryOut /// Carry-out qubit, will be xored with the higher bit of the sum. - operation Carry (carryIn: Qubit, summand1: Qubit, summand2: Qubit, carryOut: Qubit) : Unit is Adj + Ctl { + operation Carry(carryIn: Qubit, summand1: Qubit, summand2: Qubit, carryOut: Qubit) + : Unit is Adj + Ctl { CCNOT (summand1, summand2, carryOut); CNOT (summand1, summand2); CCNOT (carryIn, summand2, carryOut); @@ -46,43 +47,14 @@ namespace Microsoft.Quantum.Arithmetic { /// /// # Remarks /// In contrast to the `Carry` operation, this does not compute the carry-out bit. - operation Sum (carryIn: Qubit, summand1: Qubit, summand2: Qubit) : Unit - { - body (...) { - CNOT (summand1, summand2); - CNOT (carryIn, summand2); - } - adjoint auto; - controlled auto; - adjoint controlled auto; - } - - /// # Summary - /// Implements a cascade of CNOT gates on neighboring qubits in a given qubit - /// register, starting from the qubit at position 0 as control to the qubit at - /// position 1 as the target, then from the qubit at position 1 as the control to - /// the qubit at position 2 as the target, etc., ending with the qubit in position - /// `Length(register)-1` as the target. - /// - /// # Input - /// ## register - /// Qubit register. - operation CascadeCNOT (register : Qubit[]) : Unit - { - body (...) { - let nQubits = Length(register); - - for ( idx in 0..(nQubits-2) ) { - CNOT(register[idx], register[idx+1]); - } - } - adjoint auto; - controlled auto; - adjoint controlled auto; + operation Sum (carryIn: Qubit, summand1: Qubit, summand2: Qubit) + : Unit is Adj + Ctl { + CNOT (summand1, summand2); + CNOT (carryIn, summand2); } /// # Summary - /// Implements a cascade of CCNOT gates controlled on corresponding bits of two + /// Implements a cascade of CCNOT gates controlled on corresponding bits of two /// qubit registers, acting on the next qubit of one of the registers. /// Starting from the qubits at position 0 in both registers as controls, CCNOT is /// applied to the qubit at position 1 of the target register, then controlled by @@ -97,37 +69,32 @@ namespace Microsoft.Quantum.Arithmetic { /// /// # Remarks /// The target qubit register must have one qubit more than the other register. - operation CascadeCCNOT (register : Qubit[], targets : Qubit[]) : Unit - { - body (...) { - let nQubits = Length(targets); + operation CascadeCCNOT (register : Qubit[], targets : Qubit[]) + : Unit is Adj + Ctl { + let nQubits = Length(targets); - EqualityFactB( - nQubits == Length(register)+1, true, - "Target register must have one more qubit." ); + EqualityFactB( + nQubits == Length(register)+1, true, + "Target register must have one more qubit." ); - for ( idx in 0..(nQubits-2) ) { - CCNOT(register[idx], targets[idx], targets[idx+1]); - } + for ( idx in 0..(nQubits-2) ) { + CCNOT(register[idx], targets[idx], targets[idx+1]); } - adjoint auto; - controlled auto; - adjoint controlled auto; } /// # Summary - /// Reversible, in-place ripple-carry addition of two integers. + /// Reversible, in-place ripple-carry addition of two integers. /// Given two $n$-bit integers encoded in LittleEndian registers `xs` and `ys`, - /// and a qubit carry, the operation computes the sum of the two integers - /// where the $n$ least significant bits of the result are held in `ys` and - /// the carry out bit is xored to the qubit `carry`. + /// and a qubit carry, the operation computes the sum of the two integers + /// where the $n$ least significant bits of the result are held in `ys` and + /// the carry out bit is xored to the qubit `carry`. /// /// # Input /// ## xs /// LittleEndian qubit register encoding the first integer summand. /// ## ys - /// LittleEndian qubit register encoding the second integer summand, is + /// LittleEndian qubit register encoding the second integer summand, is /// modified to hold the $n$ least significant bits of the sum. /// ## carry /// Carry qubit, is xored with the most significant bit of the sum. @@ -135,17 +102,16 @@ namespace Microsoft.Quantum.Arithmetic { /// # References /// - Thomas G. Draper: "Addition on a Quantum Computer", 2000. /// https://arxiv.org/abs/quant-ph/0008033 - /// - /// # Remarks - /// The specified controlled operation makes use of symmetry and mutual + /// + /// # Remarks + /// The specified controlled operation makes use of symmetry and mutual /// cancellation of operations to improve on the default implementation /// that adds a control to every operation. - operation RippleCarryAdderD (xs : LittleEndian, ys : LittleEndian, carry : Qubit) : Unit - { + operation RippleCarryAdderD (xs : LittleEndian, ys : LittleEndian, carry : Qubit) + : Unit is Adj + Ctl { body (...) { (Controlled RippleCarryAdderD) (new Qubit[0], (xs, ys, carry)); } - adjoint auto; controlled ( controls, ... ) { let nQubits = Length(xs!); @@ -167,15 +133,14 @@ namespace Microsoft.Quantum.Arithmetic { } } } - adjoint controlled auto; } - + /// # Summary - /// Reversible, in-place ripple-carry operation that is used in the - /// integer addition operation RippleCarryAdderCDKM below. + /// Reversible, in-place ripple-carry operation that is used in the + /// integer addition operation RippleCarryAdderCDKM below. /// Given two qubit registers `xs` and `ys` of the same length, the operation /// applies a ripple carry sequence of CNOT and CCNOT gates with qubits - /// in `xs` and `ys` as the controls and qubits in `xs` as the targets. + /// in `xs` and `ys` as the controls and qubits in `xs` as the targets. /// /// # Input /// ## xs @@ -186,7 +151,7 @@ namespace Microsoft.Quantum.Arithmetic { /// The ancilla qubit used in RippleCarryAdderCDKM passed to this operation. /// /// # References - /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David + /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David /// Petrie Moulton: "A new quantum ripple-carry addition circuit", 2004. /// https://arxiv.org/abs/quant-ph/0410184v1 operation _RippleCDKM (xs : LittleEndian, ys : LittleEndian, ancilla : Qubit) : Unit @@ -217,8 +182,8 @@ namespace Microsoft.Quantum.Arithmetic { } /// # Summary - /// The core operation in the RippleCarryAdderCDKM, used with the above - /// _RippleCDKM operation, i.e. conjugated with this operation to obtain + /// The core operation in the RippleCarryAdderCDKM, used with the above + /// _RippleCDKM operation, i.e. conjugated with this operation to obtain /// the inner operation of the RippleCarryAdderCDKM. This operation computes /// the carry out qubit and applies a sequence of NOT gates on part of the input `ys`. /// @@ -233,7 +198,7 @@ namespace Microsoft.Quantum.Arithmetic { /// Carry out qubit in the RippleCarryAdderCDKM operation. /// /// # References - /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David + /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David /// Petrie Moulton: "A new quantum ripple-carry addition circuit", 2004. /// https://arxiv.org/abs/quant-ph/0410184v1 operation _CarryOutCoreCDKM (xs : LittleEndian, ys : LittleEndian, @@ -258,8 +223,8 @@ namespace Microsoft.Quantum.Arithmetic { } /// # Summary - /// Outer operation in the RippleCarryAdderCDKM for use with _InnerCDKM in ApplyWithCA to - /// construct RippleCarryAdderCDKM. + /// Outer operation in the RippleCarryAdderCDKM for use with _InnerCDKM in ApplyWithCA to + /// construct RippleCarryAdderCDKM. /// /// # Input /// ## xs @@ -270,7 +235,7 @@ namespace Microsoft.Quantum.Arithmetic { /// The ancilla qubit used in RippleCarryAdderCDKM. /// /// # References - /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David + /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David /// Petrie Moulton: "A new quantum ripple-carry addition circuit", 2004. /// https://arxiv.org/abs/quant-ph/0410184v1 operation _OuterCDKM (xs : LittleEndian, ys : LittleEndian, ancilla : Qubit) : Unit @@ -292,8 +257,8 @@ namespace Microsoft.Quantum.Arithmetic { } /// # Summary - /// Inner operation in the RippleCarryAdderCDKM for use with _OuterCDKM in ApplyWithCA to - /// construct RippleCarryAdderCDKM. + /// Inner operation in the RippleCarryAdderCDKM for use with _OuterCDKM in ApplyWithCA to + /// construct RippleCarryAdderCDKM. /// /// # Input /// ## xs @@ -306,7 +271,7 @@ namespace Microsoft.Quantum.Arithmetic { /// The ancilla qubit used in RippleCarryAdderCDKM. /// /// # References - /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David + /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David /// Petrie Moulton: "A new quantum ripple-carry addition circuit", 2004. /// https://arxiv.org/abs/quant-ph/0410184v1 operation _InnerCDKM (xs : LittleEndian, ys : LittleEndian, carry : Qubit, @@ -329,28 +294,28 @@ namespace Microsoft.Quantum.Arithmetic { } /// # Summary - /// Reversible, in-place ripple-carry addition of two integers. + /// Reversible, in-place ripple-carry addition of two integers. /// Given two $n$-bit integers encoded in LittleEndian registers `xs` and `ys`, - /// and a qubit carry, the operation computes the sum of the two integers - /// where the $n$ least significant bits of the result are held in `ys` and - /// the carry out bit is xored to the qubit `carry`. + /// and a qubit carry, the operation computes the sum of the two integers + /// where the $n$ least significant bits of the result are held in `ys` and + /// the carry out bit is xored to the qubit `carry`. /// /// # Input /// ## xs /// LittleEndian qubit register encoding the first integer summand. /// ## ys - /// LittleEndian qubit register encoding the second integer summand, is + /// LittleEndian qubit register encoding the second integer summand, is /// modified to hold the n least significant bits of the sum. /// ## carry /// Carry qubit, is xored with the most significant bit of the sum. /// /// # References - /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David + /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David /// Petrie Moulton: "A new quantum ripple-carry addition circuit", 2004. /// https://arxiv.org/abs/quant-ph/0410184v1 /// - /// # Remarks - /// This operation has the same functionality as RippleCarryAdderD, but + /// # Remarks + /// This operation has the same functionality as RippleCarryAdderD, but /// only uses one ancilla qubit instead of $n$. operation RippleCarryAdderCDKM (xs : LittleEndian, ys : LittleEndian, carry : Qubit) : Unit { @@ -372,28 +337,28 @@ namespace Microsoft.Quantum.Arithmetic { } /// # Summary - /// Implements the inner addition function for the operation + /// Implements the inner addition function for the operation /// RippleCarryAdderTTK. This is the inner operation that is conjugated /// with the outer operation to construct the full adder. /// /// # Input /// ## xs - /// LittleEndian qubit register encoding the first integer summand + /// LittleEndian qubit register encoding the first integer summand /// input to RippleCarryAdderTTK. /// ## ys - /// LittleEndian qubit register encoding the second integer summand + /// LittleEndian qubit register encoding the second integer summand /// input to RippleCarryAdderTTK. /// ## carry /// Carry qubit, is xored with the most significant bit of the sum. /// /// # References - /// - Yasuhiro Takahashi, Seiichiro Tani, Noboru Kunihiro: "Quantum + /// - Yasuhiro Takahashi, Seiichiro Tani, Noboru Kunihiro: "Quantum /// Addition Circuits and Unbounded Fan-Out", Quantum Information and /// Computation, Vol. 10, 2010. - /// https://arxiv.org/abs/0910.2530 + /// https://arxiv.org/abs/0910.2530 /// /// # Remarks - /// The specified controlled operation makes use of symmetry and mutual + /// The specified controlled operation makes use of symmetry and mutual /// cancellation of operations to improve on the default implementation /// that adds a control to every operation. operation _InnerAddTTK (xs : LittleEndian, ys : LittleEndian, carry : Qubit) : Unit @@ -427,17 +392,17 @@ namespace Microsoft.Quantum.Arithmetic { /// /// # Input /// ## xs - /// LittleEndian qubit register encoding the first integer summand + /// LittleEndian qubit register encoding the first integer summand /// input to RippleCarryAdderTTK. /// ## ys - /// LittleEndian qubit register encoding the second integer summand + /// LittleEndian qubit register encoding the second integer summand /// input to RippleCarryAdderTTK. /// /// # References - /// - Yasuhiro Takahashi, Seiichiro Tani, Noboru Kunihiro: "Quantum + /// - Yasuhiro Takahashi, Seiichiro Tani, Noboru Kunihiro: "Quantum /// Addition Circuits and Unbounded Fan-Out", Quantum Information and /// Computation, Vol. 10, 2010. - /// https://arxiv.org/abs/0910.2530 + /// https://arxiv.org/abs/0910.2530 operation _OuterTTK (xs : LittleEndian, ys : LittleEndian) : Unit { body (...) { @@ -456,28 +421,28 @@ namespace Microsoft.Quantum.Arithmetic { } /// # Summary - /// Reversible, in-place ripple-carry addition of two integers. + /// Reversible, in-place ripple-carry addition of two integers. /// Given two $n$-bit integers encoded in LittleEndian registers `xs` and `ys`, - /// and a qubit carry, the operation computes the sum of the two integers - /// where the $n$ least significant bits of the result are held in `ys` and - /// the carry out bit is xored to the qubit `carry`. + /// and a qubit carry, the operation computes the sum of the two integers + /// where the $n$ least significant bits of the result are held in `ys` and + /// the carry out bit is xored to the qubit `carry`. /// /// # Input /// ## xs /// LittleEndian qubit register encoding the first integer summand. /// ## ys - /// LittleEndian qubit register encoding the second integer summand, is + /// LittleEndian qubit register encoding the second integer summand, is /// modified to hold the $n$ least significant bits of the sum. /// ## carry /// Carry qubit, is xored with the most significant bit of the sum. /// /// # References - /// - Yasuhiro Takahashi, Seiichiro Tani, Noboru Kunihiro: "Quantum + /// - Yasuhiro Takahashi, Seiichiro Tani, Noboru Kunihiro: "Quantum /// Addition Circuits and Unbounded Fan-Out", Quantum Information and /// Computation, Vol. 10, 2010. - /// https://arxiv.org/abs/0910.2530 + /// https://arxiv.org/abs/0910.2530 /// - /// # Remarks + /// # Remarks /// This operation has the same functionality as RippleCarryAdderD and, /// RippleCarryAdderCDKM but does not use any ancilla qubits. operation RippleCarryAdderTTK (xs : LittleEndian, ys : LittleEndian, carry : Qubit) : Unit @@ -504,26 +469,26 @@ namespace Microsoft.Quantum.Arithmetic { } /// # Summary - /// Implements the inner addition function for the operation + /// Implements the inner addition function for the operation /// RippleCarryAdderNoCarryTTK. This is the inner operation that is conjugated /// with the outer operation to construct the full adder. /// /// # Input /// ## xs - /// LittleEndian qubit register encoding the first integer summand + /// LittleEndian qubit register encoding the first integer summand /// input to RippleCarryAdderNoCarryTTK. /// ## ys - /// LittleEndian qubit register encoding the second integer summand + /// LittleEndian qubit register encoding the second integer summand /// input to RippleCarryAdderNoCarryTTK. /// /// # References - /// - Yasuhiro Takahashi, Seiichiro Tani, Noboru Kunihiro: "Quantum + /// - Yasuhiro Takahashi, Seiichiro Tani, Noboru Kunihiro: "Quantum /// Addition Circuits and Unbounded Fan-Out", Quantum Information and /// Computation, Vol. 10, 2010. - /// https://arxiv.org/abs/0910.2530 + /// https://arxiv.org/abs/0910.2530 /// /// # Remarks - /// The specified controlled operation makes use of symmetry and mutual + /// The specified controlled operation makes use of symmetry and mutual /// cancellation of operations to improve on the default implementation /// that adds a control to every operation. operation _InnerAddNoCarryTTK (xs : LittleEndian, ys : LittleEndian) : Unit @@ -551,26 +516,28 @@ namespace Microsoft.Quantum.Arithmetic { } /// # Summary - /// Reversible, in-place ripple-carry addition of two integers without carry out. + /// + /// # Description + /// Reversible, in-place ripple-carry addition of two integers without carry out. /// Given two $n$-bit integers encoded in LittleEndian registers `xs` and `ys`, /// the operation computes the sum of the two integers modulo $2^n$, - /// where $n$ is the bit size of the inputs `xs` and `ys`. It does not compute - /// the carry out bit. + /// where $n$ is the bit size of the inputs `xs` and `ys`. It does not compute + /// the carry out bit. /// /// # Input /// ## xs /// LittleEndian qubit register encoding the first integer summand. /// ## ys - /// LittleEndian qubit register encoding the second integer summand, is + /// LittleEndian qubit register encoding the second integer summand, is /// modified to hold the $n$ least significant bits of the sum. /// /// # References - /// - Yasuhiro Takahashi, Seiichiro Tani, Noboru Kunihiro: "Quantum + /// - Yasuhiro Takahashi, Seiichiro Tani, Noboru Kunihiro: "Quantum /// Addition Circuits and Unbounded Fan-Out", Quantum Information and /// Computation, Vol. 10, 2010. - /// https://arxiv.org/abs/0910.2530 + /// https://arxiv.org/abs/0910.2530 /// - /// # Remarks + /// # Remarks /// This operation has the same functionality as RippleCarryAdderTTK but does /// not return the carry bit. operation RippleCarryAdderNoCarryTTK (xs : LittleEndian, ys : LittleEndian) : Unit @@ -593,9 +560,14 @@ namespace Microsoft.Quantum.Arithmetic { } /// # Summary + /// Applies a greater-than comparison between two integers encoded into + /// qubit registers, flipping a target qubit based on the result of the + /// comparison. + /// + /// # Description /// Carries out a strictly greater than comparison of two integers $x$ and $y$, encoded - /// in qubit registers xs and ys. If $x > y$, then the result qubit will be flipped, - /// otherwise retain its state. + /// in qubit registers xs and ys. If $x > y$, then the result qubit will be flipped, + /// otherwise the result qubit will retain its state. /// /// # Input /// ## xs @@ -604,9 +576,9 @@ namespace Microsoft.Quantum.Arithmetic { /// LittleEndian qubit register encoding the second integer $y$. /// ## result /// Single qubit that will be flipped if $x > y$. - /// + /// /// # References - /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David + /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David /// Petrie Moulton: "A new quantum ripple-carry addition circuit", 2004. /// https://arxiv.org/abs/quant-ph/0410184v1 /// @@ -615,19 +587,19 @@ namespace Microsoft.Quantum.Arithmetic { /// https://arxiv.org/abs/1611.07995 /// /// # Remarks - /// Uses the trick that $x-y = (x'+y)'$, where ' denotes the one's complement. - operation GreaterThan (xs : LittleEndian, ys : LittleEndian, result : Qubit) : Unit - { + /// Uses the trick that $x - y = (x'+y)'$, where ' denotes the one's complement. + operation GreaterThan(xs : LittleEndian, ys : LittleEndian, result : Qubit) + : Unit is Adj + Ctl { body (...) { (Controlled GreaterThan) (new Qubit[0], (xs, ys, result)); } - adjoint auto; controlled (controls, ...) { let nQubits = Length(xs!); - EqualityFactB( - nQubits == Length(ys!), true, - "Input registers must have the same number of qubits." ); + EqualityFactI( + nQubits, Length(ys!), + "Input registers must have the same number of qubits." + ); if (nQubits == 1) { X(ys![0]); @@ -647,7 +619,6 @@ namespace Microsoft.Quantum.Arithmetic { ApplyToEachCA(X, ys!); } } - adjoint controlled auto; } } diff --git a/Standard/src/Canon/Combinators/ApplyMultiControlled.qs b/Standard/src/Canon/Combinators/ApplyMultiControlled.qs index ab207594dff..30df72adf15 100644 --- a/Standard/src/Canon/Combinators/ApplyMultiControlled.qs +++ b/Standard/src/Canon/Combinators/ApplyMultiControlled.qs @@ -4,16 +4,16 @@ namespace Microsoft.Quantum.Canon { open Microsoft.Quantum.Diagnostics; open Microsoft.Quantum.Arrays; - + /////////////////////////////////////////////////////////////////////////////////////////////// // Combinators for constructing multiply controlled versions of operations /////////////////////////////////////////////////////////////////////////////////////////////// - + /// # Summary /// The signature type of CCNOT gate. newtype CCNOTop = (Apply : ((Qubit, Qubit, Qubit) => Unit is Adj)); - - + + /// # Summary /// Applies a multiply controlled version of a singly controlled /// operation. @@ -50,7 +50,7 @@ namespace Microsoft.Quantum.Canon { body (...) { EqualityFactB(Length(controls) >= 1, true, $"Length of controls must be at least 1"); - + if (Length(controls) == 1) { singlyControlledOp(controls + targets); @@ -65,14 +65,14 @@ namespace Microsoft.Quantum.Canon { } } } - + controlled (extraControls, ...) { ApplyMultiControlledC(singlyControlledOp, ccnot, extraControls + controls, targets); } } - - + + /// # Summary /// Applies a multiply controlled version of a singly controlled /// operation. @@ -119,21 +119,22 @@ namespace Microsoft.Quantum.Canon { } } } - + adjoint invert; - + controlled (extraControls, ...) { ApplyMultiControlledCA(singlyControlledOp, ccnot, extraControls + controls, targets); } - + controlled adjoint invert; } - - + /// # Summary - /// Performs a controlled 'AND ladder' on the target qubits. - /// - /// This applies a unitary given by the following map on computational basis vectors: + /// Performs a controlled "AND ladder" on a register of target qubits. + /// + /// # Description + /// This operation applies a transformation described by the following + /// mapping of the computational basis, /// $$ /// \begin{align} /// \ket{x\_1, \dots, x\_n} \ket{y\_1, \dots, y\_{n - 1}} \mapsto diff --git a/Standard/src/Canon/Deprecated.qs b/Standard/src/Canon/Deprecated.qs index 79e30a15744..0d685c82649 100644 --- a/Standard/src/Canon/Deprecated.qs +++ b/Standard/src/Canon/Deprecated.qs @@ -26,4 +26,11 @@ namespace Microsoft.Quantum.Canon { return Xor(bit1, bit2); } + /// # Deprecated + /// Please use @"microsoft.quantum.canon.applycnotchain". + @Deprecated("Microsoft.Quantum.Canon.ApplyCNOTChain") + operation CNOTChain(qubits : Qubit[]) : Unit is Adj + Ctl { + ApplyCNOTChain(qubits); + } + } diff --git a/Standard/src/Canon/IterateThroughCartesianProduct.qs b/Standard/src/Canon/IterateThroughCartesianProduct.qs index 6d00bec54b7..7966b0027c0 100644 --- a/Standard/src/Canon/IterateThroughCartesianProduct.qs +++ b/Standard/src/Canon/IterateThroughCartesianProduct.qs @@ -75,6 +75,9 @@ namespace Microsoft.Quantum.Canon { /// of the range `0..(bound - 1)`. /// /// # Input + /// ## power + /// The Cartesian power to which the range `0..(bound - 1)` should be + /// raised. /// ## bound /// A specification of the range to be iterated over, given as the length /// of the range. diff --git a/Standard/src/Canon/Parity.qs b/Standard/src/Canon/Parity.qs index 284622fe4e6..c32808ca1c2 100644 --- a/Standard/src/Canon/Parity.qs +++ b/Standard/src/Canon/Parity.qs @@ -21,7 +21,7 @@ namespace Microsoft.Quantum.Canon { /// # Input /// ## qubits /// Array of qubits whose parity is to be computed and stored. - operation CNOTChain(qubits : Qubit[]) : Unit is Adj + Ctl { + operation ApplyCNOTChain(qubits : Qubit[]) : Unit is Adj + Ctl { ApplyToEachCA(CNOT, Zip(Most(qubits), Rest(qubits))); } diff --git a/Standard/src/Simulation/BlockEncoding.qs b/Standard/src/Simulation/BlockEncoding.qs index 25059c970bd..c8c0d291d73 100644 --- a/Standard/src/Simulation/BlockEncoding.qs +++ b/Standard/src/Simulation/BlockEncoding.qs @@ -14,10 +14,10 @@ namespace Microsoft.Quantum.Simulation { // block-encoding. /// # Summary - /// Represents a unitary where an arbitrary operator of + /// Represents a unitary where an arbitrary operator of /// interest is encoded in the top-left block. /// - /// That is, a `BlockEncoding` is a unitary $U$ where an arbitrary operator $H$ of + /// That is, a `BlockEncoding` is a unitary $U$ where an arbitrary operator $H$ of /// interest that acts on the system register `s` is encoded in the top- /// left block corresponding to auxiliary state $\ket{0}_a$. That is, /// @@ -59,9 +59,9 @@ namespace Microsoft.Quantum.Simulation { /// # Summary /// Represents a `BlockEncoding` that is controlled by a clock register. - /// - /// That is, a `TimeDependentBlockEncoding` is a unitary $U$ controlled by a state - /// $\ket{k}_d$ in clock register `d` such that an arbitrary operator $H_k$ of + /// + /// That is, a `TimeDependentBlockEncoding` is a unitary $U$ controlled by a state + /// $\ket{k}_d$ in clock register `d` such that an arbitrary operator $H_k$ of /// interest that acts on the system register `s` is encoded in the top- /// left block corresponding to auxiliary state $\ket{0}_a$. That is, /// @@ -87,10 +87,10 @@ namespace Microsoft.Quantum.Simulation { /// # Summary /// Converts a `BlockEncoding` into an equivalent `BLockEncodingReflection`. - /// + /// /// That is, given a `BlockEncoding` unitary $U$ that encodes some /// operator $H$ of interest, converts it into a `BlockEncodingReflection` $U'$ that - /// encodes the same operator, but also satisfies $U'^\dagger = U'$. + /// encodes the same operator, but also satisfies $U'^\dagger = U'$. /// This increases the size of the auxiliary register of $U$ by one qubit. /// /// # Input @@ -102,7 +102,7 @@ namespace Microsoft.Quantum.Simulation { /// encodes $H$, and satisfies $U'^\dagger = U'$. /// /// # Remarks - /// This increases the size of the auxiliary register of $U$ by one qubit. + /// This increases the size of the auxiliary register of $U$ by one qubit. /// /// # References /// - Hamiltonian Simulation by Qubitization @@ -112,32 +112,29 @@ namespace Microsoft.Quantum.Simulation { /// # See Also /// - Microsoft.Quantum.Canon.BlockEncoding /// - Microsoft.Quantum.Canon.BlockEncodingReflection - function BlockEncodingToReflection(blockEncoding: BlockEncoding) : BlockEncodingReflection - { - return BlockEncodingReflection(BlockEncoding(BlockEncodingToReflection_(blockEncoding, _, _))); + function BlockEncodingToReflection(blockEncoding: BlockEncoding) + : BlockEncodingReflection { + return BlockEncodingReflection(BlockEncoding(_BlockEncodingToReflection(blockEncoding, _, _))); } - + /// # Summary /// Implementation of `BlockEncodingToReflection`. - operation BlockEncodingToReflection_(blockEncoding: BlockEncoding, auxiliary: Qubit[], system: Qubit[]) : Unit { - body (...) { - let prep = auxiliary[0]; - let blockEncodingAncilla = Rest(auxiliary); - let op1 = Controlled blockEncoding!(_, (blockEncodingAncilla, system)); - let op0 = ApplyToEachCA(H,_); - ApplyWithCA(op0, ApplyWithCA(op1, ApplyToEachCA(X,_), _), [prep]); - } - adjoint auto; - controlled auto; - adjoint controlled auto; + operation _BlockEncodingToReflection(blockEncoding: BlockEncoding, auxiliary: Qubit[], system: Qubit[]) + : Unit is Adj + Ctl { + let prep = auxiliary[0]; + let blockEncodingAux = Rest(auxiliary); + let op1 = Controlled blockEncoding!(_, (blockEncodingAux, system)); + let op0 = ApplyToEachCA(H,_); + ApplyWithCA(op0, ApplyWithCA(op1, ApplyToEachCA(X,_), _), [prep]); } /// # Summary - /// Converts a `BlockEncodingReflection` into a quantum walk. - /// - /// That is, given a `BlockEncodingReflection` unitary $U$ - /// that encodes some operator $H$ of interest, converts it into a quantum walk - /// $W$ containing the spectrum of $\pm e^{\pm i\sin^{-1}(H)}$. + /// Converts a block-encoding reflection into a quantum walk. + /// + /// # Description + /// Given a `BlockEncodingReflection` represented by a unitary $U$ + /// that encodes some operator $H$ of interest, converts it into a quantum + /// walk $W$ containing the spectrum of $\pm e^{\pm i\sin^{-1}(H)}$. /// /// # Input /// ## blockEncodingReflection @@ -156,27 +153,24 @@ namespace Microsoft.Quantum.Simulation { /// # See Also /// - Microsoft.Quantum.Canon.BlockEncoding /// - Microsoft.Quantum.Canon.BlockEncodingReflection - function QuantumWalkByQubitization(blockEncoding: BlockEncodingReflection) : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) { - return QuantumWalkByQubitization_(blockEncoding, _, _); + function QuantumWalkByQubitization(blockEncoding: BlockEncodingReflection) + : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) { + return _QuantumWalkByQubitization(blockEncoding, _, _); } /// # Summary /// Implementation of `Qubitization`. - operation QuantumWalkByQubitization_(blockEncoding: BlockEncodingReflection, auxiliary: Qubit[], system: Qubit[]) : Unit { - body (...){ - Exp([PauliI], -0.5 * PI(), [system[0]]); - RAll0(PI(), auxiliary); - // NB: We unwrap twice here, since BlockEncodingReflection wraps BlockEncoding. - blockEncoding!!(auxiliary, system); - } - adjoint auto; - controlled auto; - adjoint controlled auto; + operation _QuantumWalkByQubitization(blockEncoding: BlockEncodingReflection, auxiliary: Qubit[], system: Qubit[]) + : Unit is Adj + Ctl { + Exp([PauliI], -0.5 * PI(), [Head(system)]); + RAll0(PI(), auxiliary); + // NB: We unwrap twice here, since BlockEncodingReflection wraps BlockEncoding. + blockEncoding!!(auxiliary, system); } /// # Summary /// Encodes an operator of interest into a `BlockEncoding`. - /// + /// /// This constructs a `BlockEncoding` unitary $U=P\cdot V\cdot P^\dagger$ that encodes some /// operator $H=\sum_{j}|\alpha_j|U_j$ of interest that is a linear combination of /// unitaries. Typically, $P$ is a state preparation unitary such that @@ -194,26 +188,26 @@ namespace Microsoft.Quantum.Simulation { /// encodes $H$, and satisfies $U^\dagger = U$. /// /// # Remarks - /// This `BlockEncoding` implementation gives it the properties of a + /// This `BlockEncoding` implementation gives it the properties of a /// `BlockEncodingReflection`. /// /// # See Also /// - Microsoft.Quantum.Canon.BlockEncoding /// - Microsoft.Quantum.Canon.BlockEncodingReflection function BlockEncodingByLCU<'T,'S>( - statePreparation: ('T => Unit is Adj + Ctl), + statePreparation: ('T => Unit is Adj + Ctl), selector: (('T, 'S) => Unit is Adj + Ctl)) : (('T, 'S) => Unit is Adj + Ctl) { return BlockEncodingByLCU_(statePreparation, selector, _, _); - } + } /// # Summary /// Implementation of `BlockEncodingByLCU`. operation BlockEncodingByLCU_<'T,'S>( - statePreparation: ('T => Unit is Adj + Ctl), + statePreparation: ('T => Unit is Adj + Ctl), selector: (('T, 'S) => Unit is Adj + Ctl), - auxiliary: 'T, - system: 'S) + auxiliary: 'T, + system: 'S) : Unit { body (...){ ApplyWithCA(statePreparation, selector(_, system), auxiliary); @@ -225,7 +219,7 @@ namespace Microsoft.Quantum.Simulation { /// # Summary /// Encodes an operator of interest into a `BlockEncodingReflection`. - /// + /// /// This constructs a `BlockEncodingReflection` unitary $U=P\cdot V\cdot P^\dagger$ that encodes some /// operator $H=\sum_{j}|\alpha_j|U_j$ of interest that is a linear combination of /// unitaries. Typically, $P$ is a state preparation unitary such that @@ -243,14 +237,14 @@ namespace Microsoft.Quantum.Simulation { /// encodes $H$, and satisfies $U'^{-1} = U$. /// /// # Remarks - /// This `BlockEncoding` implementation gives it the properties of a + /// This `BlockEncoding` implementation gives it the properties of a /// `BlockEncodingReflection`. /// /// # See Also /// - Microsoft.Quantum.Canon.BlockEncoding /// - Microsoft.Quantum.Canon.BlockEncodingReflection function BlockEncodingReflectionByLCU( - statePreparation: (Qubit[] => Unit is Adj + Ctl), + statePreparation: (Qubit[] => Unit is Adj + Ctl), selector: ((Qubit[], Qubit[]) => Unit is Adj + Ctl) ) : BlockEncodingReflection { return BlockEncodingToReflection(BlockEncoding(BlockEncodingByLCU(statePreparation, selector))); @@ -259,17 +253,13 @@ namespace Microsoft.Quantum.Simulation { /// # Summary /// Conversion of ((LittleEndian, Qubit[]) => () is Adj + Ctl) to BlockEncoding - operation BlockEncodingFromBEandQubit_( - op: ((LittleEndian, Qubit[]) => Unit is Adj + Ctl), - auxiliary: Qubit[], - system: Qubit[]) : Unit - { - body (...) { - op(LittleEndian(auxiliary), system); - } - adjoint auto; - controlled auto; - adjoint controlled auto; + operation _BlockEncodingFromBEandQubit( + op: ((LittleEndian, Qubit[]) => Unit is Adj + Ctl), + auxiliary: Qubit[], + system: Qubit[] + ) + : Unit is Adj + Ctl { + op(LittleEndian(auxiliary), system); } - + } diff --git a/Standard/src/Simulation/QubitizationPauliEvolutionSet.qs b/Standard/src/Simulation/QubitizationPauliEvolutionSet.qs index a133fe1c0ef..805cce4a9d3 100644 --- a/Standard/src/Simulation/QubitizationPauliEvolutionSet.qs +++ b/Standard/src/Simulation/QubitizationPauliEvolutionSet.qs @@ -42,8 +42,8 @@ namespace Microsoft.Quantum.Simulation { /// # Summary /// Creates a block-encoding unitary for a Hamiltonian. - /// - /// The Hamiltonian $H=\sum_{j}\alpha_j P_j$ is described by a + /// + /// The Hamiltonian $H=\sum_{j}\alpha_j P_j$ is described by a /// sum of Pauli terms $P_j$, each with real coefficient $\alpha_j$. /// /// # Input @@ -54,25 +54,25 @@ namespace Microsoft.Quantum.Simulation { /// ## First parameter /// The one-norm of coefficients $\alpha=\sum_{j}|\alpha_j|$. /// ## Second parameter - /// A `BlockEncodingReflection` unitary $U$ of the Hamiltonian $H$. As this unitary + /// A `BlockEncodingReflection` unitary $U$ of the Hamiltonian $H$. As this unitary /// satisfies $U^2 = I$, it is also a reflection. /// /// # Remarks /// This is obtained by preparing and unpreparing the state $\sum_{j}\sqrt{\alpha_j/\alpha}\ket{j}$, - /// and constructing a multiply-controlled unitary + /// and constructing a multiply-controlled unitary /// and /// . function PauliBlockEncoding(generatorSystem: GeneratorSystem) : (Double, BlockEncodingReflection) { let statePrepUnitary = StatePreparationPositiveCoefficients; - let multiplexer = MultiplexerFromGenerator; - return PauliBlockEncodingImpl(generatorSystem, statePrepUnitary, multiplexer); - + let multiplexer = MultiplexerFromGenerator; + return _PauliBlockEncoding(generatorSystem, statePrepUnitary, multiplexer); + } /// # Summary /// Creates a block-encoding unitary for a Hamiltonian. - /// - /// The Hamiltonian $H=\sum_{j}\alpha_j P_j$ is described by a + /// + /// The Hamiltonian $H=\sum_{j}\alpha_j P_j$ is described by a /// sum of Pauli terms $P_j$, each with real coefficient $\alpha_j$. /// /// # Input @@ -89,7 +89,7 @@ namespace Microsoft.Quantum.Simulation { /// ## First parameter /// The one-norm of coefficients $\alpha=\sum_{j}|\alpha_j|$. /// ## Second parameter - /// A `BlockEncodingReflection` unitary $U$ of the Hamiltonian $U$. As this unitary + /// A `BlockEncodingReflection` unitary $U$ of the Hamiltonian $U$. As this unitary /// satisfies $U^2 = I$, it is also a reflection. /// /// # Remarks @@ -97,18 +97,18 @@ namespace Microsoft.Quantum.Simulation { /// and construct a multiply-controlled unitary are /// and /// . - function PauliBlockEncodingImpl( + function _PauliBlockEncoding( generatorSystem: GeneratorSystem, - statePrepUnitary: (Double[] -> (LittleEndian => Unit is Adj + Ctl)), + statePrepUnitary: (Double[] -> (LittleEndian => Unit is Adj + Ctl)), multiplexer: ((Int, (Int -> (Qubit[] => Unit is Adj + Ctl))) -> ((LittleEndian, Qubit[]) => Unit is Adj + Ctl))) : (Double, BlockEncodingReflection) { let (nTerms, intToGenIdx) = generatorSystem!; - let op = IdxToCoeff_(_, intToGenIdx, PauliCoefficientFromGenIdx); + let op = _IdxToCoeff(_, intToGenIdx, PauliCoefficientFromGenIdx); let coefficients = Mapped(op, RangeAsIntArray(0..nTerms-1)); let oneNorm = PowD(PNorm(2.0, coefficients),2.0); - let unitaryGenerator = (nTerms, IdxToUnitary_(_, intToGenIdx, PauliLCUUnitary_)); + let unitaryGenerator = (nTerms, _IdxToUnitary(_, intToGenIdx, _PauliLCUUnitary)); let statePreparation = statePrepUnitary(coefficients); - let selector = multiplexer(unitaryGenerator); - let blockEncoding = BlockEncodingReflection(BlockEncoding(BlockEncodingFromBEandQubit_(BlockEncodingByLCU(statePreparation, selector),_,_))); + let selector = multiplexer(unitaryGenerator); + let blockEncoding = BlockEncodingReflection(BlockEncoding(_BlockEncodingFromBEandQubit(BlockEncodingByLCU(statePreparation, selector),_,_))); return (oneNorm, blockEncoding); } @@ -116,7 +116,7 @@ namespace Microsoft.Quantum.Simulation { /// Used in implementation of `PauliBlockEncoding` /// # See Also /// - Microsoft.Quantum.Canon.PauliBlockEncoding - function IdxToCoeff_(idx: Int, genFun: (Int -> GeneratorIndex), genIdxToCoeff: (GeneratorIndex -> Double)) : Double { + function _IdxToCoeff(idx: Int, genFun: (Int -> GeneratorIndex), genIdxToCoeff: (GeneratorIndex -> Double)) : Double { return Sqrt(AbsD(genIdxToCoeff(genFun(idx)))); } @@ -124,7 +124,7 @@ namespace Microsoft.Quantum.Simulation { /// Used in implementation of `PauliBlockEncoding` /// # See Also /// - Microsoft.Quantum.Canon.PauliBlockEncoding - function IdxToUnitary_(idx: Int, genFun: (Int -> GeneratorIndex), genIdxToUnitary: (GeneratorIndex -> (Qubit[] => Unit is Adj + Ctl))) : (Qubit[] => Unit is Adj + Ctl) { + function _IdxToUnitary(idx: Int, genFun: (Int -> GeneratorIndex), genIdxToUnitary: (GeneratorIndex -> (Qubit[] => Unit is Adj + Ctl))) : (Qubit[] => Unit is Adj + Ctl) { return genIdxToUnitary(genFun(idx)); } @@ -133,30 +133,26 @@ namespace Microsoft.Quantum.Simulation { /// Used in implementation of `PauliBlockEncoding` /// # See Also /// - Microsoft.Quantum.Canon.PauliBlockEncoding - function PauliLCUUnitary_(generatorIndex: GeneratorIndex) : (Qubit[] => Unit is Adj + Ctl) { - return ApplyPauliLCUUnitary_(generatorIndex,_); + function _PauliLCUUnitary(generatorIndex: GeneratorIndex) : (Qubit[] => Unit is Adj + Ctl) { + return _ApplyPauliLCUUnitary(generatorIndex,_); } /// # Summary /// Used in implementation of `PauliBlockEncoding` /// # See Also /// - Microsoft.Quantum.Canon.PauliBlockEncoding - operation ApplyPauliLCUUnitary_(generatorIndex: GeneratorIndex, qubits: Qubit[]) : Unit { - body (...) { - let ((idxPaulis, coeff), idxQubits) = generatorIndex!; - let pauliString = IntsToPaulis(idxPaulis); - let pauliQubits = Subarray(idxQubits, qubits); + operation _ApplyPauliLCUUnitary(generatorIndex: GeneratorIndex, qubits: Qubit[]) + : Unit is Adj + Ctl { + let ((idxPaulis, coeff), idxQubits) = generatorIndex!; + let pauliString = IntsToPaulis(idxPaulis); + let pauliQubits = Subarray(idxQubits, qubits); - ApplyPauli(pauliString, pauliQubits); + ApplyPauli(pauliString, pauliQubits); - if (coeff[0] < 0.0) { - // -1 phase - Exp([PauliI], PI(), [pauliQubits[0]]); - } + if (coeff[0] < 0.0) { + // -1 phase + Exp([PauliI], PI(), [Head(pauliQubits)]); } - adjoint auto; - controlled auto; - adjoint controlled auto; } } From b2f7de1e82227a7b8a3abd91b6794040fde4ad12 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 8 Jan 2020 13:32:44 -0800 Subject: [PATCH 04/27] Remove extraneous comment. --- Standard/src/AmplitudeAmplification/StandardAlgorithms.qs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs b/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs index 9bedaeee3d8..6df9d1d5a4f 100644 --- a/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs +++ b/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs @@ -28,11 +28,6 @@ namespace Microsoft.Quantum.AmplitudeAmplification { return ReflectionPhases(startPhases, targetPhases); } - // We use the phases in "Fixed-Point Amplitude Amplification with an - // Optimal Number of Queires" [YoderLowChuang2014] - // See also "Methodology of composite quantum gates" [LowYoderChuang2016] - // for phases in the `RotationPhases` format - /// # Summary /// Computes partial reflection phases for fixed-point amplitude /// amplification. From 829c6800843591262257a515f96bbea64f3eb230 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 8 Jan 2020 13:34:18 -0800 Subject: [PATCH 05/27] Applied feedback from #198. --- Standard/src/Canon/And.qs | 4 ++-- Standard/src/Characterization/Distinguishability.qs | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Standard/src/Canon/And.qs b/Standard/src/Canon/And.qs index c1c3eec25d2..dc786cca0e7 100644 --- a/Standard/src/Canon/And.qs +++ b/Standard/src/Canon/And.qs @@ -220,7 +220,7 @@ namespace Microsoft.Quantum.Canon { /// # Summary /// Implements a multiple-controlled Toffoli gate, assuming that target /// qubit is initialized 0. The adjoint operation assumes that the target - /// qubit will be released to 0. + /// qubit will be reset to 0. /// /// # Input /// ## controls @@ -292,7 +292,7 @@ namespace Microsoft.Quantum.Canon { /// # Summary /// Implements a multiple-controlled Toffoli gate, assuming that target /// qubit is initialized 0. The adjoint operation assumes that the target - /// qubit will be released to 0. Requires a Rz depth of 1, while the number + /// qubit will be reset to 0. Requires a Rz depth of 1, while the number /// of helper qubits are exponential in the number of qubits. /// /// # Input diff --git a/Standard/src/Characterization/Distinguishability.qs b/Standard/src/Characterization/Distinguishability.qs index 483cdbed803..b4b98d74b4d 100644 --- a/Standard/src/Characterization/Distinguishability.qs +++ b/Standard/src/Characterization/Distinguishability.qs @@ -164,8 +164,12 @@ namespace Microsoft.Quantum.Characterization { } apply { commonPreparation(target); Controlled preparation1([control], target); - within { X(control); } - apply { Controlled preparation2([control], target); } + within { + X(control); + } + apply { + Controlled preparation2([control], target); + } (phaseShift ? S | I)(control); } From c0f5580c32e0c44232d732efd10d8956898d0a98 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 8 Jan 2020 13:56:56 -0800 Subject: [PATCH 06/27] Applying more documentation fixes suggested by linter. --- Standard/src/Arithmetic/ApplyDual.qs | 132 +++++++++++------ Standard/src/Arithmetic/Integer.qs | 144 ++++++++----------- Standard/src/Arithmetic/Modular.qs | 65 +++++---- Standard/src/ErrorCorrection/BitFlipCode.qs | 35 ++--- Standard/src/ErrorCorrection/KnillDistill.qs | 97 ++++++------- 5 files changed, 244 insertions(+), 229 deletions(-) diff --git a/Standard/src/Arithmetic/ApplyDual.qs b/Standard/src/Arithmetic/ApplyDual.qs index 5f7433d0cbe..cf2cd277131 100644 --- a/Standard/src/Arithmetic/ApplyDual.qs +++ b/Standard/src/Arithmetic/ApplyDual.qs @@ -47,11 +47,11 @@ namespace Microsoft.Quantum.Arithmetic { op(phaseLE); Adjoint QFTLE(target); } - + adjoint invert; } - - + + /// # See Also /// - @"microsoft.quantum.canon.applyphaseleoperationonle" operation ApplyPhaseLEOperationOnLEC (op : (PhaseLittleEndian => Unit is Ctl), target : LittleEndian) : Unit @@ -63,7 +63,7 @@ namespace Microsoft.Quantum.Arithmetic { op(phaseLE); Adjoint QFTLE(target); } - + controlled (controls, ...) { QFTLE(target); @@ -72,8 +72,8 @@ namespace Microsoft.Quantum.Arithmetic { Adjoint QFTLE(target); } } - - + + /// # See Also /// - @"microsoft.quantum.canon.applyphaseleoperationonle" operation ApplyPhaseLEOperationOnLECA (op : (PhaseLittleEndian => Unit is Adj + Ctl), target : LittleEndian) : Unit @@ -85,9 +85,9 @@ namespace Microsoft.Quantum.Arithmetic { op(phaseLE); Adjoint QFTLE(target); } - + adjoint invert; - + controlled (controls, ...) { QFTLE(target); @@ -95,11 +95,11 @@ namespace Microsoft.Quantum.Arithmetic { Controlled op(controls, phaseLE); Adjoint QFTLE(target); } - + controlled adjoint invert; } - - + + /// # Summary /// Applies an operation that takes a /// register as input @@ -118,56 +118,94 @@ namespace Microsoft.Quantum.Arithmetic { /// /// # See Also /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLEA - /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLEA + /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLEC /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLECA operation ApplyLEOperationOnPhaseLE (op : (LittleEndian => Unit), target : PhaseLittleEndian) : Unit { let targetLE = LittleEndian(target!); ApplyWith(Adjoint QFTLE, op, targetLE); } - - + + + + /// # Summary + /// Applies an operation that takes a + /// register as input + /// on a target register of type . + /// + /// # Input + /// ## op + /// The operation to be applied. + /// ## target + /// The register to which the operation is applied. + /// + /// # Remarks + /// The register is transformed to `LittleEndian` by the use of + /// and is then returned to + /// its original representation after application of `op`. + /// /// # See Also /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLE - operation ApplyLEOperationOnPhaseLEA (op : (LittleEndian => Unit is Adj), target : PhaseLittleEndian) : Unit - { - body (...) - { - let targetLE = LittleEndian(target!); - ApplyWithA(Adjoint QFTLE, op, targetLE); - } - - adjoint invert; + /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLEC + /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLECA + operation ApplyLEOperationOnPhaseLEA (op : (LittleEndian => Unit is Adj), target : PhaseLittleEndian) + : Unit is Adj { + let targetLE = LittleEndian(target!); + ApplyWithA(Adjoint QFTLE, op, targetLE); } - - + + + /// # Summary + /// Applies an operation that takes a + /// register as input + /// on a target register of type . + /// + /// # Input + /// ## op + /// The operation to be applied. + /// ## target + /// The register to which the operation is applied. + /// + /// # Remarks + /// The register is transformed to `LittleEndian` by the use of + /// and is then returned to + /// its original representation after application of `op`. + /// /// # See Also /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLE - operation ApplyLEOperationOnPhaseLEC (op : (LittleEndian => Unit is Ctl), target : PhaseLittleEndian) : Unit - { - body (...) - { - let targetLE = LittleEndian(target!); - ApplyWithC(Adjoint QFTLE, op, targetLE); - } - - controlled distribute; + /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLEA + /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLECA + operation ApplyLEOperationOnPhaseLEC (op : (LittleEndian => Unit is Ctl), target : PhaseLittleEndian) + : Unit is Ctl { + let targetLE = LittleEndian(target!); + ApplyWithC(Adjoint QFTLE, op, targetLE); } - - + + + /// # Summary + /// Applies an operation that takes a + /// register as input + /// on a target register of type . + /// + /// # Input + /// ## op + /// The operation to be applied. + /// ## target + /// The register to which the operation is applied. + /// + /// # Remarks + /// The register is transformed to `LittleEndian` by the use of + /// and is then returned to + /// its original representation after application of `op`. + /// /// # See Also /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLE - operation ApplyLEOperationOnPhaseLECA (op : (LittleEndian => Unit is Adj + Ctl), target : PhaseLittleEndian) : Unit - { - body (...) - { - let targetLE = LittleEndian(target!); - ApplyWithCA(Adjoint QFTLE, op, targetLE); - } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; + /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLEA + /// - Microsoft.Quantum.Canon.ApplyLEOperationonPhaseLEC + operation ApplyLEOperationOnPhaseLECA(op : (LittleEndian => Unit is Adj + Ctl), target : PhaseLittleEndian) + : Unit is Adj + Ctl { + let targetLE = LittleEndian(target!); + ApplyWithCA(Adjoint QFTLE, op, targetLE); } } diff --git a/Standard/src/Arithmetic/Integer.qs b/Standard/src/Arithmetic/Integer.qs index 1b2bfffa353..23c96f2c848 100644 --- a/Standard/src/Arithmetic/Integer.qs +++ b/Standard/src/Arithmetic/Integer.qs @@ -64,7 +64,7 @@ namespace Microsoft.Quantum.Arithmetic { /// # Input /// ## register /// Qubit register, only used for controls. - /// ## target + /// ## targets /// Qubit register, used for controls and as target. /// /// # Remarks @@ -274,27 +274,25 @@ namespace Microsoft.Quantum.Arithmetic { /// - Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David /// Petrie Moulton: "A new quantum ripple-carry addition circuit", 2004. /// https://arxiv.org/abs/quant-ph/0410184v1 - operation _InnerCDKM (xs : LittleEndian, ys : LittleEndian, carry : Qubit, - ancilla : Qubit) : Unit - { - body (...) { - let nQubits = Length(xs!); + operation _InnerCDKM(xs : LittleEndian, ys : LittleEndian, carry : Qubit, + ancilla : Qubit) + : Unit is Adj + Ctl { + let nQubits = Length(xs!); - EqualityFactB( - nQubits == Length(ys!), true, - "Input registers must have the same number of qubits." ); + EqualityFactI( + nQubits, Length(ys!), + "Input registers must have the same number of qubits." + ); - ApplyWithCA(_RippleCDKM, - _CarryOutCoreCDKM(_, _, _, carry), (xs, ys, ancilla)); - ApplyToEachCA (X, Most(Rest(ys!))); // X on ys[1..(nQubits-2)] - } - adjoint auto; - controlled auto; - adjoint controlled auto; + ApplyWithCA(_RippleCDKM, + _CarryOutCoreCDKM(_, _, _, carry), (xs, ys, ancilla)); + ApplyToEachCA (X, Most(Rest(ys!))); // X on ys[1..(nQubits-2)] } /// # Summary /// Reversible, in-place ripple-carry addition of two integers. + /// + /// # Description /// Given two $n$-bit integers encoded in LittleEndian registers `xs` and `ys`, /// and a qubit carry, the operation computes the sum of the two integers /// where the $n$ least significant bits of the result are held in `ys` and @@ -317,23 +315,19 @@ namespace Microsoft.Quantum.Arithmetic { /// # Remarks /// This operation has the same functionality as RippleCarryAdderD, but /// only uses one ancilla qubit instead of $n$. - operation RippleCarryAdderCDKM (xs : LittleEndian, ys : LittleEndian, carry : Qubit) : Unit - { - body (...) { - let nQubits = Length(xs!); + operation RippleCarryAdderCDKM (xs : LittleEndian, ys : LittleEndian, carry : Qubit) + : Unit { + let nQubits = Length(xs!); - EqualityFactB( - nQubits == Length(ys!), true, - "Input registers must have the same number of qubits." ); + EqualityFactI( + nQubits, Length(ys!), + "Input registers must have the same number of qubits." + ); - using ( ancilla = Qubit() ) { - ApplyWithCA(_OuterCDKM, _InnerCDKM(_, _, carry, _), (xs, ys, ancilla)); - CNOT (xs![0], ys![0]); - } + using ( ancilla = Qubit() ) { + ApplyWithCA(_OuterCDKM, _InnerCDKM(_, _, carry, _), (xs, ys, ancilla)); + CNOT(xs![0], ys![0]); } - adjoint auto; - controlled auto; - adjoint controlled auto; } /// # Summary @@ -361,12 +355,11 @@ namespace Microsoft.Quantum.Arithmetic { /// The specified controlled operation makes use of symmetry and mutual /// cancellation of operations to improve on the default implementation /// that adds a control to every operation. - operation _InnerAddTTK (xs : LittleEndian, ys : LittleEndian, carry : Qubit) : Unit - { + operation _InnerAddTTK (xs : LittleEndian, ys : LittleEndian, carry : Qubit) + : Unit is Adj + Ctl { body (...) { (Controlled _InnerAddTTK) (new Qubit[0], (xs, ys, carry)); } - adjoint auto; controlled ( controls, ... ) { let nQubits = Length(xs!); @@ -383,7 +376,6 @@ namespace Microsoft.Quantum.Arithmetic { CCNOT (xs![idx-1], ys![idx-1], xs![idx]); } } - adjoint controlled auto; } /// # Summary @@ -403,21 +395,16 @@ namespace Microsoft.Quantum.Arithmetic { /// Addition Circuits and Unbounded Fan-Out", Quantum Information and /// Computation, Vol. 10, 2010. /// https://arxiv.org/abs/0910.2530 - operation _OuterTTK (xs : LittleEndian, ys : LittleEndian) : Unit - { - body (...) { - let nQubits = Length(xs!); + operation _OuterTTK (xs : LittleEndian, ys : LittleEndian) + : Unit is Adj + Ctl { + let nQubits = Length(xs!); - EqualityFactB( - nQubits == Length(ys!), true, - "Input registers must have the same number of qubits." ); + EqualityFactB( + nQubits == Length(ys!), true, + "Input registers must have the same number of qubits." ); - ApplyToEachCA(CNOT, Zip(Rest(xs!), Rest(ys!))); - (Adjoint CascadeCNOT) (Rest(xs!)); - } - adjoint auto; - controlled auto; - adjoint controlled auto; + ApplyToEachCA(CNOT, Zip(Rest(xs!), Rest(ys!))); + (Adjoint CascadeCNOT) (Rest(xs!)); } /// # Summary @@ -445,27 +432,23 @@ namespace Microsoft.Quantum.Arithmetic { /// # Remarks /// This operation has the same functionality as RippleCarryAdderD and, /// RippleCarryAdderCDKM but does not use any ancilla qubits. - operation RippleCarryAdderTTK (xs : LittleEndian, ys : LittleEndian, carry : Qubit) : Unit - { - body (...) { - let nQubits = Length(xs!); + operation RippleCarryAdderTTK (xs : LittleEndian, ys : LittleEndian, carry : Qubit) + : Unit is Adj + Ctl { + let nQubits = Length(xs!); - EqualityFactB( - nQubits == Length(ys!), true, - "Input registers must have the same number of qubits." ); + EqualityFactI( + nQubits, Length(ys!), + "Input registers must have the same number of qubits." + ); - if (nQubits > 1) { - CNOT(xs![nQubits-1], carry); - ApplyWithCA(_OuterTTK, _InnerAddTTK(_, _, carry), (xs, ys)); - } - else { - CCNOT(xs![0], ys![0], carry); - } - CNOT(xs![0], ys![0]); + if (nQubits > 1) { + CNOT(xs![nQubits-1], carry); + ApplyWithCA(_OuterTTK, _InnerAddTTK(_, _, carry), (xs, ys)); } - adjoint auto; - controlled auto; - adjoint controlled auto; + else { + CCNOT(xs![0], ys![0], carry); + } + CNOT(xs![0], ys![0]); } /// # Summary @@ -491,12 +474,11 @@ namespace Microsoft.Quantum.Arithmetic { /// The specified controlled operation makes use of symmetry and mutual /// cancellation of operations to improve on the default implementation /// that adds a control to every operation. - operation _InnerAddNoCarryTTK (xs : LittleEndian, ys : LittleEndian) : Unit - { + operation _InnerAddNoCarryTTK (xs : LittleEndian, ys : LittleEndian) + : Unit is Adj + Ctl { body (...) { (Controlled _InnerAddNoCarryTTK) (new Qubit[0], (xs, ys)); } - adjoint auto; controlled ( controls, ... ) { let nQubits = Length(xs!); @@ -512,13 +494,12 @@ namespace Microsoft.Quantum.Arithmetic { CCNOT (xs![idx-1], ys![idx-1], xs![idx]); } } - adjoint controlled auto; } /// # Summary + /// Reversible, in-place ripple-carry addition of two integers without carry out. /// /// # Description - /// Reversible, in-place ripple-carry addition of two integers without carry out. /// Given two $n$-bit integers encoded in LittleEndian registers `xs` and `ys`, /// the operation computes the sum of the two integers modulo $2^n$, /// where $n$ is the bit size of the inputs `xs` and `ys`. It does not compute @@ -540,23 +521,18 @@ namespace Microsoft.Quantum.Arithmetic { /// # Remarks /// This operation has the same functionality as RippleCarryAdderTTK but does /// not return the carry bit. - operation RippleCarryAdderNoCarryTTK (xs : LittleEndian, ys : LittleEndian) : Unit - { - body (...) { - let nQubits = Length(xs!); + operation RippleCarryAdderNoCarryTTK (xs : LittleEndian, ys : LittleEndian) + : Unit is Adj + Ctl { + let nQubits = Length(xs!); - EqualityFactB( - nQubits == Length(ys!), true, - "Input registers must have the same number of qubits." ); + EqualityFactB( + nQubits == Length(ys!), true, + "Input registers must have the same number of qubits." ); - if (nQubits > 1) { - ApplyWithCA(_OuterTTK, _InnerAddNoCarryTTK, (xs, ys)); - } - CNOT (xs![0], ys![0]); + if (nQubits > 1) { + ApplyWithCA(_OuterTTK, _InnerAddNoCarryTTK, (xs, ys)); } - adjoint auto; - controlled auto; - adjoint controlled auto; + CNOT (xs![0], ys![0]); } /// # Summary diff --git a/Standard/src/Arithmetic/Modular.qs b/Standard/src/Arithmetic/Modular.qs index 2f9bea6c89d..d0aa04e4171 100644 --- a/Standard/src/Arithmetic/Modular.qs +++ b/Standard/src/Arithmetic/Modular.qs @@ -36,18 +36,13 @@ namespace Microsoft.Quantum.Arithmetic { /// Note that /// implements /// the same operation in the `PhaseLittleEndian` basis. - operation IncrementByModularInteger(increment : Int, modulus : Int, target : LittleEndian) : Unit { - body (...) { - let inner = IncrementPhaseByModularInteger(increment, modulus, _); + operation IncrementByModularInteger(increment : Int, modulus : Int, target : LittleEndian) + : Unit is Adj + Ctl { + let inner = IncrementPhaseByModularInteger(increment, modulus, _); - using (extraZeroBit = Qubit()) { - ApplyPhaseLEOperationOnLECA(inner, LittleEndian(target! + [extraZeroBit])); - } + using (extraZeroBit = Qubit()) { + ApplyPhaseLEOperationOnLECA(inner, LittleEndian(target! + [extraZeroBit])); } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; } /// # Summary @@ -61,6 +56,14 @@ namespace Microsoft.Quantum.Arithmetic { /// \end{align} /// Integers are encoded in little-endian format in QFT basis. /// + /// # Input + /// ## increment + /// Integer increment $a$ to be added to $y$. + /// ## modulus + /// Integer $N$ that mods $y + a$. + /// ## target + /// Integer $y$ in phase-encoded little-endian format that `increment` $a$ is added to. + /// /// # See Also /// - Microsoft.Quantum.Arithmetic.IncrementByModularInteger /// @@ -70,11 +73,11 @@ namespace Microsoft.Quantum.Arithmetic { /// /// For the circuit diagram and explanation see Figure 5 on [Page 5 /// of arXiv:quant-ph/0205095v3](https://arxiv.org/pdf/quant-ph/0205095v3.pdf#page=5). - operation IncrementPhaseByModularInteger(increment : Int, modulus : Int, target : PhaseLittleEndian) : Unit { + operation IncrementPhaseByModularInteger(increment : Int, modulus : Int, target : PhaseLittleEndian) + : Unit is Adj + Ctl { body (...) { Controlled IncrementPhaseByModularInteger(new Qubit[0], (increment, modulus, target)); } - adjoint auto; controlled (controls, ...) { Fact(modulus <= 2 ^ (Length(target!) - 1), $"`multiplier` must be big enough to fit integers modulo `modulus`" + $"with highest bit set to 0"); @@ -112,8 +115,6 @@ namespace Microsoft.Quantum.Arithmetic { Controlled IncrementPhaseByInteger(controls, (increment, target)); } } - - controlled adjoint auto; } /// # Summary @@ -148,33 +149,41 @@ namespace Microsoft.Quantum.Arithmetic { /// of arXiv:quant-ph/0205095v3](https://arxiv.org/pdf/quant-ph/0205095v3.pdf#page=7) /// - This operation corresponds to CMULT(a)MOD(N) in /// [arXiv:quant-ph/0205095v3](https://arxiv.org/pdf/quant-ph/0205095v3.pdf) - operation MultiplyAndAddByModularInteger(constMultiplier : Int, modulus : Int, multiplier : LittleEndian, summand : LittleEndian) : Unit { - body (...) { - let inner = MultiplyAndAddPhaseByModularInteger(constMultiplier, modulus, multiplier, _); + operation MultiplyAndAddByModularInteger(constMultiplier : Int, modulus : Int, multiplier : LittleEndian, summand : LittleEndian) + : Unit is Adj + Ctl { + let inner = MultiplyAndAddPhaseByModularInteger(constMultiplier, modulus, multiplier, _); - using (extraZeroBit = Qubit()) { - ApplyPhaseLEOperationOnLECA(inner, LittleEndian(summand! + [extraZeroBit])); - } + using (extraZeroBit = Qubit()) { + ApplyPhaseLEOperationOnLECA(inner, LittleEndian(summand! + [extraZeroBit])); } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; } /// # Summary /// The same as MultiplyAndAddByModularInteger, but assumes that the summand encodes /// integers in QFT basis. /// + /// # Input + /// ## constantMultiplier + /// An integer $a$ to be added to each basis state label. + /// ## modulus + /// The modulus $N$ which addition and multiplication is taken with respect to. + /// ## multiplier + /// A quantum register representing an unsigned integer whose value is to + /// be added to each basis state label of `summand`. + /// ## phaseSummand + /// A quantum register representing an unsigned integer to use as the target + /// for this operation. + /// /// # Remarks /// Assumes that `phaseSummand` has the highest bit set to 0. /// Also assumes that the value of `phaseSummand` is less than $N$. /// /// # See Also /// - Microsoft.Quantum.Arithmetic.MultiplyAndAddByModularInteger - operation MultiplyAndAddPhaseByModularInteger(constMultiplier : Int, modulus : Int, multiplier : LittleEndian, phaseSummand : PhaseLittleEndian) : Unit is Adj + Ctl { - EqualityFactB(modulus <= 2 ^ (Length(phaseSummand!) - 1), true, $"`multiplier` must be big enough to fit integers modulo `modulus`" + $"with highest bit set to 0"); - EqualityFactB(constMultiplier >= 0 and constMultiplier < modulus, true, $"`constMultiplier` must be between 0 and `modulus`-1"); + operation MultiplyAndAddPhaseByModularInteger(constMultiplier : Int, modulus : Int, multiplier : LittleEndian, phaseSummand : PhaseLittleEndian) + : Unit is Adj + Ctl { + Fact(modulus <= 2 ^ (Length(phaseSummand!) - 1), $"`multiplier` must be big enough to fit integers modulo `modulus`" + $"with highest bit set to 0"); + Fact(constMultiplier >= 0 and constMultiplier < modulus, $"`constMultiplier` must be between 0 and `modulus`-1"); if (_EnableExtraAssertsForArithmetic()) { // assert that the highest bit is zero, by switching to computational basis @@ -184,7 +193,7 @@ namespace Microsoft.Quantum.Arithmetic { AssertPhaseLessThan(modulus, phaseSummand); } - for (i in 0 .. Length(multiplier!) - 1) { + for (i in IndexRange(multiplier!)) { let summand = (ExpModI(2, i, modulus) * constMultiplier) % modulus; Controlled IncrementPhaseByModularInteger([(multiplier!)[i]], (summand, modulus, phaseSummand)); } diff --git a/Standard/src/ErrorCorrection/BitFlipCode.qs b/Standard/src/ErrorCorrection/BitFlipCode.qs index 4fb8d11d905..6d7c1db6cf1 100644 --- a/Standard/src/ErrorCorrection/BitFlipCode.qs +++ b/Standard/src/ErrorCorrection/BitFlipCode.qs @@ -17,23 +17,18 @@ namespace Microsoft.Quantum.ErrorCorrection { /// /// # References /// - doi:10.1103/PhysRevA.85.044302 - operation BFEncoderImpl (coherentRecovery : Bool, data : Qubit[], scratch : Qubit[]) : Unit - { - body (...) + operation _BFEncoder(coherentRecovery : Bool, data : Qubit[], scratch : Qubit[]) + : Unit is Adj { + if (coherentRecovery) { - if (coherentRecovery) - { - Controlled X(scratch, data[0]); - } - - Controlled X(data, scratch[0]); - Controlled X(data, scratch[1]); + Controlled X(scratch, data[0]); } - - adjoint invert; + + Controlled X(data, scratch[0]); + Controlled X(data, scratch[1]); } - - + + /// # Summary /// Encodes into the [3, 1, 3] / ⟦3, 1, 1⟧ bit-flip code. /// @@ -52,12 +47,12 @@ namespace Microsoft.Quantum.ErrorCorrection { /// - LogicalRegister operation EncodeIntoBitFlipCode(physRegister : Qubit[], auxQubits : Qubit[]) : LogicalRegister { - BFEncoderImpl(false, physRegister, auxQubits); + _BFEncoder(false, physRegister, auxQubits); let logicalRegister = LogicalRegister(physRegister + auxQubits); return logicalRegister; } - - + + /// # Summary /// Decodes from the [3, 1, 3] / ⟦3, 1, 1⟧ bit-flip code. /// @@ -72,11 +67,11 @@ namespace Microsoft.Quantum.ErrorCorrection { /// # See Also /// - LogicalRegister /// - EncodeIntoBitFlipCode - operation DecodeFromBitFlipCode(logicalRegister : LogicalRegister) : (Qubit[], Qubit[]) - { + operation DecodeFromBitFlipCode(logicalRegister : LogicalRegister) + : (Qubit[], Qubit[]) { let physRegister = [(logicalRegister!)[0]]; let auxQubits = (logicalRegister!)[1 .. 2]; - Adjoint BFEncoderImpl(false, physRegister, auxQubits); + Adjoint _BFEncoder(false, physRegister, auxQubits); return (physRegister, auxQubits); } diff --git a/Standard/src/ErrorCorrection/KnillDistill.qs b/Standard/src/ErrorCorrection/KnillDistill.qs index 86345d10738..c8da074ad29 100644 --- a/Standard/src/ErrorCorrection/KnillDistill.qs +++ b/Standard/src/ErrorCorrection/KnillDistill.qs @@ -6,10 +6,9 @@ namespace Microsoft.Quantum.ErrorCorrection { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Measurement; - /// # Summary /// Syndrome measurement and the inverse of embedding. - /// + /// /// $X$- and $Z$-stabilizers are not treated equally, /// which is due to the particular choice of the encoding circuit. /// This asymmetry leads to a different syndrome extraction routine. @@ -24,13 +23,13 @@ namespace Microsoft.Quantum.ErrorCorrection { /// would have caused the measured syndrome. /// /// # Remarks - /// + /// /// > [!WARNING] /// > This routine is tailored /// > to a particular encoding circuit for Steane's 7 qubit code; /// > if the encoding circuit is modified then the syndrome outcome /// > might have to be interpreted differently. - /// + /// operation _ExtractLogicalQubitFromSteaneCode (code : LogicalRegister) : (Qubit, Int, Int) { Adjoint SteaneCodeEncoderImpl((code!)[0 .. 0], (code!)[1 .. 6]); @@ -38,57 +37,60 @@ namespace Microsoft.Quantum.ErrorCorrection { let x1 = M((code!)[1]); let x2 = M((code!)[3]); mutable xsyn = 0; - + if (x0 == One) { set xsyn = xsyn ^^^ 1; } - + if (x1 == One) { set xsyn = xsyn ^^^ 2; } - + if (x2 == One) { set xsyn = xsyn ^^^ 4; } - + set xsyn = xsyn - 1; - + // xsyn contains the qubit index (0..6) at which a single Z-error would // produce the given syndrome. let z0 = M((code!)[5]); let z1 = M((code!)[2]); let z2 = M((code!)[4]); mutable zsyn = 0; - + if (z0 == One) { set zsyn = zsyn ^^^ 1; } - + if (z1 == One) { set zsyn = zsyn ^^^ 2; } - + if (z2 == One) { set zsyn = zsyn ^^^ 5; } - + set zsyn = zsyn - 1; - + // zsyn contains the qubit index (0..6) at which a single X-error would // produce the given syndrome. return ((code!)[0], xsyn, zsyn); } - - + + /// # Summary + /// Rotates a single qubit by π/4 about the Y-axis. + /// + /// # Description /// Performs a π/4 rotation about `Y`. - /// + /// /// The rotation is performed by consuming a magic /// state; that is, a copy of the state /// $$ @@ -122,19 +124,19 @@ namespace Microsoft.Quantum.ErrorCorrection { /// This operation supports the `Adjoint` functor, in which /// case the same magic state is consumed, but the effect /// on the data qubit is a $-\pi/4$ $Y$-rotation. - operation InjectPi4YRotation (data : Qubit, magic : Qubit) : Unit - { - body (...) - { + operation InjectPi4YRotation (data : Qubit, magic : Qubit) + : Unit is Adj { + body (...) { Adjoint S(data); CNOT(magic, data); S(data); let r = MResetY(magic); - - if (r == One) - { - // The following five gates is equal to Ry( Pi()/2.0, data) - // up to global phase. + + if (r == One) { + // The following five operations are equivalant to + // Ry( Pi()/2.0, data), up to global phase. + // Since this operation does not support Controlled, we need + // not worry about global phases. S(data); H(data); Adjoint S(data); @@ -142,16 +144,14 @@ namespace Microsoft.Quantum.ErrorCorrection { Adjoint S(data); } } - - adjoint (...) - { + + adjoint (...) { Adjoint S(data); CNOT(magic, data); S(data); let r = MResetY(magic); - - if (r == Zero) - { + + if (r == Zero) { S(data); H(data); S(data); @@ -160,11 +160,12 @@ namespace Microsoft.Quantum.ErrorCorrection { } } } - - + + /// # Summary /// Implements the Knill magic state distillation algorithm. - /// + /// + /// # Description /// Given 15 approximate copies of a magic state /// $$ /// \begin{align} @@ -195,39 +196,35 @@ namespace Microsoft.Quantum.ErrorCorrection { /// /// # References /// - [Knill](https://arxiv.org/abs/quant-ph/0402171) - operation KnillDistill (roughMagic : Qubit[]) : Bool - { + operation KnillDistill (roughMagic : Qubit[]) : Bool { mutable accept = false; - - using (scratch = Qubit[8]) - { + + using (scratch = Qubit[8]) { let anc = scratch[7]; let code = scratch[0 .. 6]; InjectPi4YRotation(code[0], roughMagic[14]); SteaneCodeEncoderImpl(code[0 .. 0], code[1 .. 6]); - - for (idx in 0 .. 6) - { + + for (idx in 0 .. 6) { Adjoint InjectPi4YRotation(code[idx], roughMagic[idx]); CNOT(code[idx], anc); InjectPi4YRotation(code[idx], roughMagic[idx + 7]); } - + let (logicalQubit, xsyn, zsyn) = _ExtractLogicalQubitFromSteaneCode(LogicalRegister(code)); let m = M(anc); - - if ((xsyn == -1 and zsyn == -1) and m == Zero) - { + + if ((xsyn == -1 and zsyn == -1) and m == Zero) { SWAP(logicalQubit, roughMagic[0]); set accept = true; } - + ResetAll(scratch); } - + return accept; } - + } From 30decd398bb0ddcfabfdac45b54e682618b12259 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 8 Jan 2020 14:05:44 -0800 Subject: [PATCH 07/27] Fix to deprecation stub. --- Standard/src/Arithmetic/Deprecated.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Arithmetic/Deprecated.qs b/Standard/src/Arithmetic/Deprecated.qs index 062338ce41a..5de14dbe09c 100644 --- a/Standard/src/Arithmetic/Deprecated.qs +++ b/Standard/src/Arithmetic/Deprecated.qs @@ -196,7 +196,7 @@ namespace Microsoft.Quantum.Canon { /// # Deprecated /// Please use @"microsoft.quantum.canon.applycnotchain". @Deprecated("Microsoft.Quantum.Canon.ApplyCNOTChain") - operation CascadeCNOT (register : Qubit[]) : Unit { + operation CascadeCNOT (register : Qubit[]) : Unit is Adj + Ctl { Microsoft.Quantum.Canon.ApplyCNOTChain(register); } From 0c294d37b1005dca5d5c6e52a81266bc2438df8b Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 8 Jan 2020 14:06:15 -0800 Subject: [PATCH 08/27] Whitespace fix noted by @ScottCarda-MS. --- Standard/src/Arithmetic/Asserts.qs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Standard/src/Arithmetic/Asserts.qs b/Standard/src/Arithmetic/Asserts.qs index 48d8cbec875..3d9201c2486 100644 --- a/Standard/src/Arithmetic/Asserts.qs +++ b/Standard/src/Arithmetic/Asserts.qs @@ -9,9 +9,9 @@ namespace Microsoft.Quantum.Arithmetic { open Microsoft.Quantum.Diagnostics; /// # Summary - /// Asserts that the probability of a specific state of a quantum register has the - /// expected value. - /// + /// Asserts that the probability of a specific state of a quantum register has the + /// expected value. + /// /// # Description /// Given an $n$-qubit quantum state $\ket{\psi}=\sum^{2^n-1}_{j=0}\alpha_j \ket{j}$, /// asserts that the probability $|\alpha_j|^2$ of the state $\ket{j}$ indexed by $j$ From 15b647ca386d55836ba176419cf028f2ca516dfb Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 8 Jan 2020 14:24:07 -0800 Subject: [PATCH 09/27] Fixed minor mistake introduced with previous code quality fix. --- Standard/src/Arithmetic/Integer.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Arithmetic/Integer.qs b/Standard/src/Arithmetic/Integer.qs index 23c96f2c848..fc0158dbc6c 100644 --- a/Standard/src/Arithmetic/Integer.qs +++ b/Standard/src/Arithmetic/Integer.qs @@ -316,7 +316,7 @@ namespace Microsoft.Quantum.Arithmetic { /// This operation has the same functionality as RippleCarryAdderD, but /// only uses one ancilla qubit instead of $n$. operation RippleCarryAdderCDKM (xs : LittleEndian, ys : LittleEndian, carry : Qubit) - : Unit { + : Unit is Adj + Ctl { let nQubits = Length(xs!); EqualityFactI( From 9dbc67f0a51a1b58a2c38a1de22138f032d157bf Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 8 Jan 2020 14:29:48 -0800 Subject: [PATCH 10/27] Incorporated more feedback from @ScottCarda-MS. --- Standard/src/Canon/Combinators/Compose.qs | 2 +- Standard/src/Canon/Combinators/Curry.qs | 8 ++--- .../src/Canon/Combinators/OperationPow.qs | 16 ++++----- Standard/src/Canon/Enumeration/Trotter.qs | 8 ++--- Standard/src/ErrorCorrection/BitFlipCode.qs | 7 ++-- Standard/src/ErrorCorrection/KnillDistill.qs | 26 ++++++-------- Standard/tests/IntegerTests.qs | 36 +++++++++---------- 7 files changed, 47 insertions(+), 56 deletions(-) diff --git a/Standard/src/Canon/Combinators/Compose.qs b/Standard/src/Canon/Combinators/Compose.qs index 517c769ac33..95a0c5ee4f6 100644 --- a/Standard/src/Canon/Combinators/Compose.qs +++ b/Standard/src/Canon/Combinators/Compose.qs @@ -8,7 +8,7 @@ namespace Microsoft.Quantum.Canon { } /// # Summary - /// Returns the composition of two functions. + /// Returns the composition of two functions. /// /// # Description /// Given two functions $f$ and $g$, returns a new function representing diff --git a/Standard/src/Canon/Combinators/Curry.qs b/Standard/src/Canon/Combinators/Curry.qs index fc6f2af45bf..d04f3e48c29 100644 --- a/Standard/src/Canon/Combinators/Curry.qs +++ b/Standard/src/Canon/Combinators/Curry.qs @@ -9,8 +9,8 @@ namespace Microsoft.Quantum.Canon { /// # Summary - /// Returns a curried version of an operation on two inputs. - /// + /// Returns a curried version of an operation on two inputs. + /// /// That is, given an operation with two inputs, this function applies Curry's isomorphism /// $f(x, y) \equiv f(x)(y)$ to return an operation of one input which /// returns an operation of one input. @@ -106,8 +106,8 @@ namespace Microsoft.Quantum.Canon { /// /// # See Also /// - @"microsoft.quantum.canon.uncurryop" - function UncurriedOpC<'T, 'U> (curriedOp : ('T -> ('U => Unit is Ctl))) : (('T, 'U) => Unit is Ctl) - { + function UncurriedOpC<'T, 'U> (curriedOp : ('T -> ('U => Unit is Ctl))) + : (('T, 'U) => Unit is Ctl) { return _UncurriedOpC(curriedOp, _, _); } diff --git a/Standard/src/Canon/Combinators/OperationPow.qs b/Standard/src/Canon/Combinators/OperationPow.qs index 091cc9e2806..21fcbdbd855 100644 --- a/Standard/src/Canon/Combinators/OperationPow.qs +++ b/Standard/src/Canon/Combinators/OperationPow.qs @@ -36,8 +36,8 @@ namespace Microsoft.Quantum.Canon { /// # Summary - /// Raises an operation to a power. - /// + /// Raises an operation to a power. + /// /// That is, given an operation representing a gate $U$, returns a new operation /// $U^m$ for a power $m$. /// @@ -64,9 +64,9 @@ namespace Microsoft.Quantum.Canon { /// # Summary - /// Raises an operation to a power. + /// Raises an operation to a power. /// The modifier `C` indicates that the operation is controllable. - /// + /// /// That is, given an operation representing a gate $U$, returns a new operation /// $U^m$ for a power $m$. /// @@ -91,9 +91,9 @@ namespace Microsoft.Quantum.Canon { /// # Summary - /// Raises an operation to a power. + /// Raises an operation to a power. /// The modifier `A` indicates that the operation is adjointable. - /// + /// /// That is, given an operation representing a gate $U$, returns a new operation /// $U^m$ for a power $m$. /// @@ -118,9 +118,9 @@ namespace Microsoft.Quantum.Canon { /// # Summary - /// Raises an operation to a power. + /// Raises an operation to a power. /// The modifier `A` indicates that the operation is controllable and adjointable. - /// + /// /// That is, given an operation representing a gate $U$, returns a new operation /// $U^m$ for a power $m$. /// diff --git a/Standard/src/Canon/Enumeration/Trotter.qs b/Standard/src/Canon/Enumeration/Trotter.qs index 66ee3020f2b..dcdf635afea 100644 --- a/Standard/src/Canon/Enumeration/Trotter.qs +++ b/Standard/src/Canon/Enumeration/Trotter.qs @@ -110,7 +110,7 @@ namespace Microsoft.Quantum.Canon { /// A quantum register on which the operations act. operation _TrotterArbitraryImplCA<'T> (order:Int, (nSteps : Int, op : ((Int, Double, 'T) => Unit is Adj + Ctl)), stepSize : Double, target : 'T) : Unit is Adj + Ctl { - if(order > 2){ + if (order > 2) { let stepSizeOuter = _TrotterStepSize(order); let stepSizeInner = 1.0 - 4.0 * stepSizeOuter; _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); @@ -118,11 +118,9 @@ namespace Microsoft.Quantum.Canon { _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeInner * stepSize, target); _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); _TrotterArbitraryImplCA(order -2, (nSteps, op), stepSizeOuter * stepSize, target); - } - elif(order == 2){ + } elif (order == 2) { _Trotter2ImplCA((nSteps, op), stepSize, target); - } - else{ + } else { _Trotter1ImplCA((nSteps, op), stepSize, target); } } diff --git a/Standard/src/ErrorCorrection/BitFlipCode.qs b/Standard/src/ErrorCorrection/BitFlipCode.qs index 6d7c1db6cf1..83b778b6adb 100644 --- a/Standard/src/ErrorCorrection/BitFlipCode.qs +++ b/Standard/src/ErrorCorrection/BitFlipCode.qs @@ -19,8 +19,7 @@ namespace Microsoft.Quantum.ErrorCorrection { /// - doi:10.1103/PhysRevA.85.044302 operation _BFEncoder(coherentRecovery : Bool, data : Qubit[], scratch : Qubit[]) : Unit is Adj { - if (coherentRecovery) - { + if (coherentRecovery) { Controlled X(scratch, data[0]); } @@ -45,8 +44,8 @@ namespace Microsoft.Quantum.ErrorCorrection { /// /// # See Also /// - LogicalRegister - operation EncodeIntoBitFlipCode(physRegister : Qubit[], auxQubits : Qubit[]) : LogicalRegister - { + operation EncodeIntoBitFlipCode(physRegister : Qubit[], auxQubits : Qubit[]) + : LogicalRegister { _BFEncoder(false, physRegister, auxQubits); let logicalRegister = LogicalRegister(physRegister + auxQubits); return logicalRegister; diff --git a/Standard/src/ErrorCorrection/KnillDistill.qs b/Standard/src/ErrorCorrection/KnillDistill.qs index c8da074ad29..cbc07cb4fe0 100644 --- a/Standard/src/ErrorCorrection/KnillDistill.qs +++ b/Standard/src/ErrorCorrection/KnillDistill.qs @@ -30,30 +30,27 @@ namespace Microsoft.Quantum.ErrorCorrection { /// > if the encoding circuit is modified then the syndrome outcome /// > might have to be interpreted differently. /// - operation _ExtractLogicalQubitFromSteaneCode (code : LogicalRegister) : (Qubit, Int, Int) - { + operation _ExtractLogicalQubitFromSteaneCode (code : LogicalRegister) + : (Qubit, Int, Int) { Adjoint SteaneCodeEncoderImpl((code!)[0 .. 0], (code!)[1 .. 6]); let x0 = M((code!)[6]); let x1 = M((code!)[1]); let x2 = M((code!)[3]); mutable xsyn = 0; - if (x0 == One) - { + if (x0 == One) { set xsyn = xsyn ^^^ 1; } - if (x1 == One) - { + if (x1 == One) { set xsyn = xsyn ^^^ 2; } - if (x2 == One) - { + if (x2 == One) { set xsyn = xsyn ^^^ 4; } - set xsyn = xsyn - 1; + set xsyn -= 1; // xsyn contains the qubit index (0..6) at which a single Z-error would // produce the given syndrome. @@ -62,22 +59,19 @@ namespace Microsoft.Quantum.ErrorCorrection { let z2 = M((code!)[4]); mutable zsyn = 0; - if (z0 == One) - { + if (z0 == One) { set zsyn = zsyn ^^^ 1; } - if (z1 == One) - { + if (z1 == One) { set zsyn = zsyn ^^^ 2; } - if (z2 == One) - { + if (z2 == One) { set zsyn = zsyn ^^^ 5; } - set zsyn = zsyn - 1; + set zsyn -= 1; // zsyn contains the qubit index (0..6) at which a single X-error would // produce the given syndrome. diff --git a/Standard/tests/IntegerTests.qs b/Standard/tests/IntegerTests.qs index a8605f38db2..403e6c02970 100644 --- a/Standard/tests/IntegerTests.qs +++ b/Standard/tests/IntegerTests.qs @@ -18,12 +18,12 @@ namespace Microsoft.Quantum.Arithmetic { let summand1LE = LittleEndian(register[0 .. numberOfQubits - 1]); let summand2LE = LittleEndian(register[numberOfQubits .. 2*numberOfQubits - 1]); let carry = register[2*numberOfQubits]; - + ApplyXorInPlace(summand1, summand1LE); ApplyXorInPlace(summand2, summand2LE); IntegerAdder(summand1LE, summand2LE, carry); - + let sum = summand1 + summand2; let expected = ModulusI(sum, 2^numberOfQubits); set actual1 = MeasureInteger(summand1LE); @@ -35,7 +35,7 @@ namespace Microsoft.Quantum.Arithmetic { if (measured_carry == One) {set actual_carry = 1;} else {set actual_carry = 0;} EqualityFactI(expected_carry, actual_carry, $"Expected {expected_carry}, got {actual_carry}"); - for (numberOfControls in 1..2) { + for (numberOfControls in 1..2) { using (controls = Qubit[numberOfControls]) { ApplyXorInPlace(summand1, summand1LE); ApplyXorInPlace(summand2, summand2LE); @@ -66,7 +66,7 @@ namespace Microsoft.Quantum.Arithmetic { } } } - + operation IntegerAdderExhaustiveTestHelper (IntegerAdder : ( (LittleEndian, LittleEndian, Qubit) => Unit is Ctl), numberOfQubits : Int) : Unit { for( summand1 in 0 .. 2^numberOfQubits - 1 ) { for( summand2 in 0 .. 2^numberOfQubits - 1 ) { @@ -90,26 +90,26 @@ namespace Microsoft.Quantum.Arithmetic { operation RippleCarryAdderDTestReversible () : Unit { let numberOfQubits = 20; - let summand1 = 823709; - let summand2 = 88487; + let summand1 = 823709; + let summand2 = 88487; IntegerAdderTestHelper(RippleCarryAdderD, summand1, summand2, numberOfQubits); } operation RippleCarryAdderCDKMExhaustiveTest () : Unit { let numberOfQubits = 4; - IntegerAdderExhaustiveTestHelper (RippleCarryAdderCDKM, numberOfQubits); + IntegerAdderExhaustiveTestHelper (RippleCarryAdderCDKM, numberOfQubits); } operation RippleCarryAdderCDKMTestReversible () : Unit { let numberOfQubits = 20; - let summand1 = 823709; - let summand2 = 88487; + let summand1 = 823709; + let summand2 = 88487; IntegerAdderTestHelper(RippleCarryAdderCDKM, summand1, summand2, numberOfQubits); } operation RippleCarryAdderCDKMExhaustiveTestReversible () : Unit { for (numberOfQubits in 3..6) { - IntegerAdderExhaustiveTestHelper (RippleCarryAdderCDKM, numberOfQubits); + IntegerAdderExhaustiveTestHelper (RippleCarryAdderCDKM, numberOfQubits); } } @@ -131,12 +131,12 @@ namespace Microsoft.Quantum.Arithmetic { mutable actual2 = 0; let summand1LE = LittleEndian(register[0 .. numberOfQubits - 1]); let summand2LE = LittleEndian(register[numberOfQubits .. 2*numberOfQubits - 1]); - + ApplyXorInPlace(summand1, summand1LE); ApplyXorInPlace(summand2, summand2LE); IntegerAdder(summand1LE, summand2LE); - + let sum = summand1 + summand2; let expected = ModulusI(sum, 2^numberOfQubits); set actual1 = MeasureInteger(summand1LE); @@ -145,7 +145,7 @@ namespace Microsoft.Quantum.Arithmetic { EqualityFactI(expected, actual2, $"Expected {expected}, got {actual2}"); let expected_carry = (sum / 2^numberOfQubits); - for (numberOfControls in 1..2) { + for (numberOfControls in 1..2) { using (controls = Qubit[numberOfControls]) { ApplyXorInPlace(summand1, summand1LE); ApplyXorInPlace(summand2, summand2LE); @@ -180,8 +180,8 @@ namespace Microsoft.Quantum.Arithmetic { operation RippleCarryAdderNoCarryTTKTestReversible () : Unit { let numberOfQubits = 10; - let summand1 = 1021; - let summand2 = 973; + let summand1 = 1021; + let summand2 = 973; IntegerAdderNoCarryTestHelper(RippleCarryAdderNoCarryTTK, summand1, summand2, numberOfQubits); } @@ -206,13 +206,13 @@ namespace Microsoft.Quantum.Arithmetic { let integer1LE = LittleEndian(register[0 .. numberOfQubits - 1]); let integer2LE = LittleEndian(register[numberOfQubits .. 2*numberOfQubits - 1]); let result = register[2*numberOfQubits]; - + ApplyXorInPlace(integer1, integer1LE); ApplyXorInPlace(integer2, integer2LE); GreaterThan(integer1LE, integer2LE, result); - if (integer1 > integer2) {set gt = One;} + if (integer1 > integer2) {set gt = One;} set actual1 = MeasureInteger(integer1LE); EqualityFactI(integer1, actual1, $"Expected {integer1}, got {actual1}"); set actual2 = MeasureInteger(integer2LE); @@ -221,7 +221,7 @@ namespace Microsoft.Quantum.Arithmetic { EqualityFactB((gt == actualr), true, $"Expected {gt}, got {actualr}"); Reset(result); - for (numberOfControls in 1..2) { + for (numberOfControls in 1..2) { using (controls = Qubit[numberOfControls]) { ApplyXorInPlace(integer1, integer1LE); ApplyXorInPlace(integer2, integer2LE); From acf40671e5a7be30f30d27f60599cfacdabffae6 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 17:57:33 -0800 Subject: [PATCH 11/27] Update Standard/src/Arrays/Map.qs Co-Authored-By: Alan Geller --- Standard/src/Arrays/Map.qs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Standard/src/Arrays/Map.qs b/Standard/src/Arrays/Map.qs index dc80ee861ef..e6e28337d0e 100644 --- a/Standard/src/Arrays/Map.qs +++ b/Standard/src/Arrays/Map.qs @@ -104,7 +104,7 @@ namespace Microsoft.Quantum.Arrays { /// /// # Input /// ## action - /// A operation from `'T` to `'U` that is applied to each element. + /// An operation from `'T` to `'U` that is applied to each element. /// ## array /// An array of elements over `'T`. /// @@ -122,4 +122,3 @@ namespace Microsoft.Quantum.Arrays { } - From 9cdbe1988b29854c9982ee154660c2d969e0a12d Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 17:57:46 -0800 Subject: [PATCH 12/27] Update Standard/src/Canon/Combinators/ApplyIf.qs Co-Authored-By: Alan Geller --- Standard/src/Canon/Combinators/ApplyIf.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Canon/Combinators/ApplyIf.qs b/Standard/src/Canon/Combinators/ApplyIf.qs index d48c9fb5aa6..7b13916832d 100644 --- a/Standard/src/Canon/Combinators/ApplyIf.qs +++ b/Standard/src/Canon/Combinators/ApplyIf.qs @@ -594,7 +594,7 @@ namespace Microsoft.Quantum.Canon { /// /// # Input /// ## bit - /// The boolean value used to determine if `trueOp` or `falseOp` is + /// The boolean value used to determine whether `trueOp` or `falseOp` is /// applied. /// ## trueOp /// The operation to be applied when `bit` is `true`. From 43ae0aa0ccb2259eb660f21740a86bcfca7a061f Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 17:57:55 -0800 Subject: [PATCH 13/27] Update Standard/src/Canon/Combinators/ApplyIf.qs Co-Authored-By: Alan Geller --- Standard/src/Canon/Combinators/ApplyIf.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Canon/Combinators/ApplyIf.qs b/Standard/src/Canon/Combinators/ApplyIf.qs index 7b13916832d..9855fb9e134 100644 --- a/Standard/src/Canon/Combinators/ApplyIf.qs +++ b/Standard/src/Canon/Combinators/ApplyIf.qs @@ -636,7 +636,7 @@ namespace Microsoft.Quantum.Canon { /// /// # Input /// ## bit - /// The boolean value used to determine if `trueOp` or `falseOp` is + /// The boolean value used to determine whether `trueOp` or `falseOp` is /// applied. /// ## trueOp /// The controllable operation to be applied when `bit` is `true`. From bbd5d981440b63a34e4e534f01a5970adf0ff029 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 17:58:03 -0800 Subject: [PATCH 14/27] Update Standard/src/Canon/Combinators/ApplyIf.qs Co-Authored-By: Alan Geller --- Standard/src/Canon/Combinators/ApplyIf.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Canon/Combinators/ApplyIf.qs b/Standard/src/Canon/Combinators/ApplyIf.qs index 9855fb9e134..6550e869936 100644 --- a/Standard/src/Canon/Combinators/ApplyIf.qs +++ b/Standard/src/Canon/Combinators/ApplyIf.qs @@ -678,7 +678,7 @@ namespace Microsoft.Quantum.Canon { /// /// # Input /// ## bit - /// The boolean value used to determine if `trueOp` or `falseOp` is + /// The boolean value used to determine whether `trueOp` or `falseOp` is /// applied. /// ## trueOp /// The adjointable operation to be applied when `bit` is `true`. From e3a93c01d2d11db4e148a73da11dbbd1ce0983f2 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 17:58:15 -0800 Subject: [PATCH 15/27] Update Standard/src/Arithmetic/Integer.qs Co-Authored-By: Alan Geller --- Standard/src/Arithmetic/Integer.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Arithmetic/Integer.qs b/Standard/src/Arithmetic/Integer.qs index fc0158dbc6c..7899a7eeb69 100644 --- a/Standard/src/Arithmetic/Integer.qs +++ b/Standard/src/Arithmetic/Integer.qs @@ -49,7 +49,7 @@ namespace Microsoft.Quantum.Arithmetic { /// In contrast to the `Carry` operation, this does not compute the carry-out bit. operation Sum (carryIn: Qubit, summand1: Qubit, summand2: Qubit) : Unit is Adj + Ctl { - CNOT (summand1, summand2); + CNOT(summand1, summand2); CNOT (carryIn, summand2); } From 101dc90f0ee5c1b963c4954d6e8034857a1830e0 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 17:58:44 -0800 Subject: [PATCH 16/27] Update Standard/src/Arithmetic/Integer.qs Co-Authored-By: Alan Geller --- Standard/src/Arithmetic/Integer.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Arithmetic/Integer.qs b/Standard/src/Arithmetic/Integer.qs index 7899a7eeb69..7843bd45f9e 100644 --- a/Standard/src/Arithmetic/Integer.qs +++ b/Standard/src/Arithmetic/Integer.qs @@ -50,7 +50,7 @@ namespace Microsoft.Quantum.Arithmetic { operation Sum (carryIn: Qubit, summand1: Qubit, summand2: Qubit) : Unit is Adj + Ctl { CNOT(summand1, summand2); - CNOT (carryIn, summand2); + CNOT(carryIn, summand2); } /// # Summary From 9ad181073f8e86442c656a04c9636ac55aaebbdf Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 17:58:58 -0800 Subject: [PATCH 17/27] Update Standard/src/Canon/Combinators/ApplyIf.qs Co-Authored-By: Alan Geller --- Standard/src/Canon/Combinators/ApplyIf.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Canon/Combinators/ApplyIf.qs b/Standard/src/Canon/Combinators/ApplyIf.qs index 6550e869936..69dfc6c4c9b 100644 --- a/Standard/src/Canon/Combinators/ApplyIf.qs +++ b/Standard/src/Canon/Combinators/ApplyIf.qs @@ -720,7 +720,7 @@ namespace Microsoft.Quantum.Canon { /// /// # Input /// ## bit - /// The boolean value used to determine if `trueOp` or `falseOp` is + /// The boolean value used to determine whether `trueOp` or `falseOp` is /// applied. /// ## trueOp /// The unitary operation to be applied when `bit` is `true`. From 90e50dc74abce942a1127ec3dcdbe771eae9db65 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 18:13:05 -0800 Subject: [PATCH 18/27] Update Standard/src/Arithmetic/Integer.qs Co-Authored-By: Alan Geller --- Standard/src/Arithmetic/Integer.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Arithmetic/Integer.qs b/Standard/src/Arithmetic/Integer.qs index 7843bd45f9e..bbccab7f050 100644 --- a/Standard/src/Arithmetic/Integer.qs +++ b/Standard/src/Arithmetic/Integer.qs @@ -47,7 +47,7 @@ namespace Microsoft.Quantum.Arithmetic { /// /// # Remarks /// In contrast to the `Carry` operation, this does not compute the carry-out bit. - operation Sum (carryIn: Qubit, summand1: Qubit, summand2: Qubit) + operation Sum(carryIn: Qubit, summand1: Qubit, summand2: Qubit) : Unit is Adj + Ctl { CNOT(summand1, summand2); CNOT(carryIn, summand2); From 18e3f46284443b6dc62d521f9380fbebdadc6041 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 18:22:33 -0800 Subject: [PATCH 19/27] Update Standard/src/Arithmetic/Integer.qs Co-Authored-By: Alan Geller --- Standard/src/Arithmetic/Integer.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Arithmetic/Integer.qs b/Standard/src/Arithmetic/Integer.qs index bbccab7f050..6b5364f526d 100644 --- a/Standard/src/Arithmetic/Integer.qs +++ b/Standard/src/Arithmetic/Integer.qs @@ -110,7 +110,7 @@ namespace Microsoft.Quantum.Arithmetic { operation RippleCarryAdderD (xs : LittleEndian, ys : LittleEndian, carry : Qubit) : Unit is Adj + Ctl { body (...) { - (Controlled RippleCarryAdderD) (new Qubit[0], (xs, ys, carry)); + Controlled RippleCarryAdderD(new Qubit[0], (xs, ys, carry)); } controlled ( controls, ... ) { let nQubits = Length(xs!); From f75d87c47556ed42c44d6f4f071cc8481ff2d195 Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 18:22:42 -0800 Subject: [PATCH 20/27] Update Standard/src/Arithmetic/Integer.qs Co-Authored-By: Alan Geller --- Standard/src/Arithmetic/Integer.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Arithmetic/Integer.qs b/Standard/src/Arithmetic/Integer.qs index 6b5364f526d..599122118f2 100644 --- a/Standard/src/Arithmetic/Integer.qs +++ b/Standard/src/Arithmetic/Integer.qs @@ -107,7 +107,7 @@ namespace Microsoft.Quantum.Arithmetic { /// The specified controlled operation makes use of symmetry and mutual /// cancellation of operations to improve on the default implementation /// that adds a control to every operation. - operation RippleCarryAdderD (xs : LittleEndian, ys : LittleEndian, carry : Qubit) + operation RippleCarryAdderD(xs : LittleEndian, ys : LittleEndian, carry : Qubit) : Unit is Adj + Ctl { body (...) { Controlled RippleCarryAdderD(new Qubit[0], (xs, ys, carry)); From 26609184237bfe01d82e86ad5d7451c33303e37a Mon Sep 17 00:00:00 2001 From: Chris Granade Date: Mon, 13 Jan 2020 18:22:49 -0800 Subject: [PATCH 21/27] Update Standard/src/Arithmetic/Integer.qs Co-Authored-By: Alan Geller --- Standard/src/Arithmetic/Integer.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Arithmetic/Integer.qs b/Standard/src/Arithmetic/Integer.qs index 599122118f2..07c9d9a306a 100644 --- a/Standard/src/Arithmetic/Integer.qs +++ b/Standard/src/Arithmetic/Integer.qs @@ -69,7 +69,7 @@ namespace Microsoft.Quantum.Arithmetic { /// /// # Remarks /// The target qubit register must have one qubit more than the other register. - operation CascadeCCNOT (register : Qubit[], targets : Qubit[]) + operation CascadeCCNOT(register : Qubit[], targets : Qubit[]) : Unit is Adj + Ctl { let nQubits = Length(targets); From 80ef13b1ee2ae1fa54df0f8ea7ca104119383ce3 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Mon, 13 Jan 2020 18:25:09 -0800 Subject: [PATCH 22/27] Addressing feedback, lots of indentation fixes. --- Standard/src/Arithmetic/Arithmetic.qs | 2 +- .../Canon/Combinators/ApplyMultiControlled.qs | 2 +- Standard/src/Canon/Combinators/Bind.qs | 79 ++++++------------- .../src/Canon/Combinators/OperationPow.qs | 40 +++++----- Standard/src/Canon/Parity.qs | 10 +-- Standard/src/Simulation/BlockEncoding.qs | 54 +++++++------ .../QubitizationPauliEvolutionSet.qs | 9 +-- 7 files changed, 81 insertions(+), 115 deletions(-) diff --git a/Standard/src/Arithmetic/Arithmetic.qs b/Standard/src/Arithmetic/Arithmetic.qs index 0427e251379..189d0e79ce3 100644 --- a/Standard/src/Arithmetic/Arithmetic.qs +++ b/Standard/src/Arithmetic/Arithmetic.qs @@ -37,7 +37,7 @@ namespace Microsoft.Quantum.Arithmetic { /// qubits. /// /// # Description - /// This computes the Majority function in-place on 3 qubits. + /// This operation computes the majority function in-place on 3 qubits. /// /// If we denote output qubit as $z$ and input qubits as $x$ and $y$, /// the operation performs the following transformation: diff --git a/Standard/src/Canon/Combinators/ApplyMultiControlled.qs b/Standard/src/Canon/Combinators/ApplyMultiControlled.qs index 30df72adf15..3a66a084c76 100644 --- a/Standard/src/Canon/Combinators/ApplyMultiControlled.qs +++ b/Standard/src/Canon/Combinators/ApplyMultiControlled.qs @@ -130,7 +130,7 @@ namespace Microsoft.Quantum.Canon { } /// # Summary - /// Performs a controlled "AND ladder" on a register of target qubits. + /// Performs a controlled "AND ladder" on a register of target qubits. /// /// # Description /// This operation applies a transformation described by the following diff --git a/Standard/src/Canon/Combinators/Bind.qs b/Standard/src/Canon/Combinators/Bind.qs index 0d65c7f9449..6bcae71b3ff 100644 --- a/Standard/src/Canon/Combinators/Bind.qs +++ b/Standard/src/Canon/Combinators/Bind.qs @@ -36,8 +36,8 @@ namespace Microsoft.Quantum.Canon { /// let bound = Bound([U, V]); /// bound(x); /// ``` - /// and - /// ```qsharp + /// and + /// ```qsharp /// U(x); V(x); /// ``` /// @@ -52,19 +52,10 @@ namespace Microsoft.Quantum.Canon { /// # See Also /// - Microsoft.Quantum.Canon.BoundA - operation _BoundA<'T> (operations : ('T => Unit is Adj)[], target : 'T) : Unit { - body (...) { - for (op in operations) { - op(target); - } - } - - adjoint (...) { - // TODO: replace with an implementation based on Reversed : 'T[] -> 'T[] - // and AdjointAll : ('T => () is Adj)[] -> ('T => () is Adj). - for (op in Reversed(operations)) { - Adjoint op(target); - } + operation _BoundA<'T> (operations : ('T => Unit is Adj)[], target : 'T) + : Unit is Adj { + for (op in operations) { + op(target); } } @@ -94,32 +85,25 @@ namespace Microsoft.Quantum.Canon { /// let bound = BoundA([U, V]); /// bound(x); /// ``` - /// and - /// ```qsharp + /// and + /// ```qsharp /// U(x); V(x); /// ``` /// /// # See Also /// - Microsoft.Quantum.Canon.Bound - function BoundA<'T> (operations : ('T => Unit is Adj)[]) : ('T => Unit is Adj) - { + function BoundA<'T> (operations : ('T => Unit is Adj)[]) + : ('T => Unit is Adj) { return _BoundA(operations, _); } /// # See Also /// - Microsoft.Quantum.Canon.BoundC - operation _BoundC<'T> (operations : ('T => Unit is Ctl)[], target : 'T) : Unit { - body (...) { - for (op in operations) { - op(target); - } - } - - controlled (controls, ...) { - for (op in operations) { - Controlled op(controls, target); - } + operation _BoundC<'T> (operations : ('T => Unit is Ctl)[], target : 'T) + : Unit is Ctl { + for (op in operations) { + op(target); } } @@ -149,8 +133,8 @@ namespace Microsoft.Quantum.Canon { /// let bound = BoundC([U, V]); /// bound(x); /// ``` - /// and - /// ```qsharp + /// and + /// ```qsharp /// U(x); V(x); /// ``` /// @@ -163,29 +147,10 @@ namespace Microsoft.Quantum.Canon { /// # See Also /// - Microsoft.Quantum.Canon.BoundCA - operation _BoundCA<'T> (operations : ('T => Unit is Adj + Ctl)[], target : 'T) : Unit { - body (...) { - for (op in operations) { - op(target); - } - } - - adjoint (...) { - for (op in Reversed(operations)) { - Adjoint op(target); - } - } - - controlled (controls, ...) { - for (op in operations) { - Controlled op(controls, target); - } - } - - controlled adjoint (controls, ...) { - for (op in Reversed(operations)) { - Controlled Adjoint op(controls, target); - } + operation _BoundCA<'T> (operations : ('T => Unit is Adj + Ctl)[], target : 'T) + : Unit is Adj + Ctl { + for (op in operations) { + op(target); } } @@ -216,8 +181,8 @@ namespace Microsoft.Quantum.Canon { /// let bound = BoundCA([U, V]); /// bound(x); /// ``` - /// and - /// ```qsharp + /// and + /// ```qsharp /// U(x); V(x); /// ``` /// diff --git a/Standard/src/Canon/Combinators/OperationPow.qs b/Standard/src/Canon/Combinators/OperationPow.qs index 21fcbdbd855..657b0c7f085 100644 --- a/Standard/src/Canon/Combinators/OperationPow.qs +++ b/Standard/src/Canon/Combinators/OperationPow.qs @@ -3,34 +3,34 @@ namespace Microsoft.Quantum.Canon { - operation _OperationPow<'T> (oracle : ('T => Unit), power : Int, target : 'T) + operation _OperationPow<'T> (op : ('T => Unit), power : Int, target : 'T) : Unit { for (idxApplication in 0 .. power - 1) { - oracle(target); + op(target); } } - operation _OperationPowC<'T> (oracle : ('T => Unit is Ctl), power : Int, target : 'T) + operation _OperationPowC<'T> (op : ('T => Unit is Ctl), power : Int, target : 'T) : Unit is Ctl { for (idxApplication in 0 .. power - 1) { - oracle(target); + op(target); } } - operation _OperationPowA<'T> (oracle : ('T => Unit is Adj), power : Int, target : 'T) + operation _OperationPowA<'T> (op : ('T => Unit is Adj), power : Int, target : 'T) : Unit is Adj { for (idxApplication in 0 .. power - 1) { - oracle(target); + op(target); } } - operation _OperationPowCA<'T> (oracle : ('T => Unit is Adj + Ctl), power : Int, target : 'T) + operation _OperationPowCA<'T> (op : ('T => Unit is Adj + Ctl), power : Int, target : 'T) : Unit is Adj + Ctl { for (idxApplication in 0 .. power - 1) { - oracle(target); + op(target); } } @@ -42,7 +42,7 @@ namespace Microsoft.Quantum.Canon { /// $U^m$ for a power $m$. /// /// # Input - /// ## oracle + /// ## op /// An operation $U$ representing the gate to be repeated. /// ## power /// The number of times that $U$ is to be repeated. @@ -58,8 +58,8 @@ namespace Microsoft.Quantum.Canon { /// - @"microsoft.quantum.canon.operationpowc" /// - @"microsoft.quantum.canon.operationpowa" /// - @"microsoft.quantum.canon.operationpowca" - function OperationPow<'T> (oracle : ('T => Unit), power : Int) : ('T => Unit) { - return _OperationPow(oracle, power, _); + function OperationPow<'T> (op : ('T => Unit), power : Int) : ('T => Unit) { + return _OperationPow(op, power, _); } @@ -71,7 +71,7 @@ namespace Microsoft.Quantum.Canon { /// $U^m$ for a power $m$. /// /// # Input - /// ## oracle + /// ## op /// An operation $U$ representing the gate to be repeated. /// ## power /// The number of times that $U$ is to be repeated. @@ -85,8 +85,8 @@ namespace Microsoft.Quantum.Canon { /// /// # See Also /// - @"microsoft.quantum.canon.operationpow" - function OperationPowC<'T> (oracle : ('T => Unit is Ctl), power : Int) : ('T => Unit is Ctl) { - return _OperationPowC(oracle, power, _); + function OperationPowC<'T> (op : ('T => Unit is Ctl), power : Int) : ('T => Unit is Ctl) { + return _OperationPowC(op, power, _); } @@ -98,7 +98,7 @@ namespace Microsoft.Quantum.Canon { /// $U^m$ for a power $m$. /// /// # Input - /// ## oracle + /// ## op /// An operation $U$ representing the gate to be repeated. /// ## power /// The number of times that $U$ is to be repeated. @@ -112,8 +112,8 @@ namespace Microsoft.Quantum.Canon { /// /// # See Also /// - @"microsoft.quantum.canon.operationpow" - function OperationPowA<'T> (oracle : ('T => Unit is Adj), power : Int) : ('T => Unit is Adj) { - return _OperationPowA(oracle, power, _); + function OperationPowA<'T> (op : ('T => Unit is Adj), power : Int) : ('T => Unit is Adj) { + return _OperationPowA(op, power, _); } @@ -125,7 +125,7 @@ namespace Microsoft.Quantum.Canon { /// $U^m$ for a power $m$. /// /// # Input - /// ## oracle + /// ## op /// An operation $U$ representing the gate to be repeated. /// ## power /// The number of times that $U$ is to be repeated. @@ -139,8 +139,8 @@ namespace Microsoft.Quantum.Canon { /// /// # See Also /// - @"microsoft.quantum.canon.operationpow" - function OperationPowCA<'T> (oracle : ('T => Unit is Ctl + Adj), power : Int) : ('T => Unit is Ctl + Adj) { - return _OperationPowCA(oracle, power, _); + function OperationPowCA<'T> (op : ('T => Unit is Ctl + Adj), power : Int) : ('T => Unit is Ctl + Adj) { + return _OperationPowCA(op, power, _); } } diff --git a/Standard/src/Canon/Parity.qs b/Standard/src/Canon/Parity.qs index c32808ca1c2..b270a51d880 100644 --- a/Standard/src/Canon/Parity.qs +++ b/Standard/src/Canon/Parity.qs @@ -7,7 +7,7 @@ namespace Microsoft.Quantum.Canon { /// # Summary /// Computes the parity of a register of qubits in-place. - /// + /// /// # Description /// This operation transforms the state of its input as /// $$ @@ -27,9 +27,9 @@ namespace Microsoft.Quantum.Canon { /// # Summary /// Computes the parity of an array of qubits into a target qubit. - /// + /// /// # Description - /// If the array is initially in the state + /// If the array is initially in the state /// $\ket{q_0} \ket{q_1} \cdots \ket{q_{\text{target}}}$, /// the final state is given by /// $\ket{q_0} \ket{q_1 \oplus q_0} \cdots \ket{q_{n - 1} \oplus \cdots \oplus q_0 \oplus q_{\text{target}}}$. @@ -45,8 +45,8 @@ namespace Microsoft.Quantum.Canon { /// ```qsharp /// CNOTChainTarget(Most(qs), Last(qs)); /// ``` - /// and - /// ```qsharp + /// and + /// ```qsharp /// CNOTChain(qs); /// ``` operation CNOTChainTarget(qubits : Qubit[], targetQubit : Qubit) : Unit { diff --git a/Standard/src/Simulation/BlockEncoding.qs b/Standard/src/Simulation/BlockEncoding.qs index c8c0d291d73..3eec6b4feb7 100644 --- a/Standard/src/Simulation/BlockEncoding.qs +++ b/Standard/src/Simulation/BlockEncoding.qs @@ -16,7 +16,7 @@ namespace Microsoft.Quantum.Simulation { /// # Summary /// Represents a unitary where an arbitrary operator of /// interest is encoded in the top-left block. - /// + /// /// That is, a `BlockEncoding` is a unitary $U$ where an arbitrary operator $H$ of /// interest that acts on the system register `s` is encoded in the top- /// left block corresponding to auxiliary state $\ket{0}_a$. That is, @@ -58,8 +58,8 @@ namespace Microsoft.Quantum.Simulation { newtype BlockEncodingReflection = BlockEncoding; /// # Summary - /// Represents a `BlockEncoding` that is controlled by a clock register. - /// + /// Represents a `BlockEncoding` that is controlled by a clock register. + /// /// That is, a `TimeDependentBlockEncoding` is a unitary $U$ controlled by a state /// $\ket{k}_d$ in clock register `d` such that an arbitrary operator $H_k$ of /// interest that acts on the system register `s` is encoded in the top- @@ -86,8 +86,8 @@ namespace Microsoft.Quantum.Simulation { newtype TimeDependentBlockEncoding = ((Qubit[], Qubit[], Qubit[]) => Unit is Adj + Ctl); /// # Summary - /// Converts a `BlockEncoding` into an equivalent `BLockEncodingReflection`. - /// + /// Converts a `BlockEncoding` into an equivalent `BLockEncodingReflection`. + /// /// That is, given a `BlockEncoding` unitary $U$ that encodes some /// operator $H$ of interest, converts it into a `BlockEncodingReflection` $U'$ that /// encodes the same operator, but also satisfies $U'^\dagger = U'$. @@ -129,7 +129,7 @@ namespace Microsoft.Quantum.Simulation { } /// # Summary - /// Converts a block-encoding reflection into a quantum walk. + /// Converts a block-encoding reflection into a quantum walk. /// /// # Description /// Given a `BlockEncodingReflection` represented by a unitary $U$ @@ -160,7 +160,11 @@ namespace Microsoft.Quantum.Simulation { /// # Summary /// Implementation of `Qubitization`. - operation _QuantumWalkByQubitization(blockEncoding: BlockEncodingReflection, auxiliary: Qubit[], system: Qubit[]) + operation _QuantumWalkByQubitization( + blockEncoding : BlockEncodingReflection, + auxiliary : Qubit[], + system : Qubit[] + ) : Unit is Adj + Ctl { Exp([PauliI], -0.5 * PI(), [Head(system)]); RAll0(PI(), auxiliary); @@ -169,8 +173,8 @@ namespace Microsoft.Quantum.Simulation { } /// # Summary - /// Encodes an operator of interest into a `BlockEncoding`. - /// + /// Encodes an operator of interest into a `BlockEncoding`. + /// /// This constructs a `BlockEncoding` unitary $U=P\cdot V\cdot P^\dagger$ that encodes some /// operator $H=\sum_{j}|\alpha_j|U_j$ of interest that is a linear combination of /// unitaries. Typically, $P$ is a state preparation unitary such that @@ -196,30 +200,27 @@ namespace Microsoft.Quantum.Simulation { /// - Microsoft.Quantum.Canon.BlockEncodingReflection function BlockEncodingByLCU<'T,'S>( statePreparation: ('T => Unit is Adj + Ctl), - selector: (('T, 'S) => Unit is Adj + Ctl)) - : (('T, 'S) => Unit is Adj + Ctl) { - return BlockEncodingByLCU_(statePreparation, selector, _, _); + selector: (('T, 'S) => Unit is Adj + Ctl) + ) + : (('T, 'S) => Unit is Adj + Ctl) { + return _BlockEncodingByLCU(statePreparation, selector, _, _); } /// # Summary /// Implementation of `BlockEncodingByLCU`. - operation BlockEncodingByLCU_<'T,'S>( + operation _BlockEncodingByLCU<'T,'S>( statePreparation: ('T => Unit is Adj + Ctl), selector: (('T, 'S) => Unit is Adj + Ctl), auxiliary: 'T, - system: 'S) - : Unit { - body (...){ - ApplyWithCA(statePreparation, selector(_, system), auxiliary); - } - adjoint auto; - controlled auto; - adjoint controlled auto; + system: 'S + ) + : Unit is Adj + Ctl { + ApplyWithCA(statePreparation, selector(_, system), auxiliary); } /// # Summary - /// Encodes an operator of interest into a `BlockEncodingReflection`. - /// + /// Encodes an operator of interest into a `BlockEncodingReflection`. + /// /// This constructs a `BlockEncodingReflection` unitary $U=P\cdot V\cdot P^\dagger$ that encodes some /// operator $H=\sum_{j}|\alpha_j|U_j$ of interest that is a linear combination of /// unitaries. Typically, $P$ is a state preparation unitary such that @@ -244,9 +245,10 @@ namespace Microsoft.Quantum.Simulation { /// - Microsoft.Quantum.Canon.BlockEncoding /// - Microsoft.Quantum.Canon.BlockEncodingReflection function BlockEncodingReflectionByLCU( - statePreparation: (Qubit[] => Unit is Adj + Ctl), - selector: ((Qubit[], Qubit[]) => Unit is Adj + Ctl) - ) : BlockEncodingReflection { + statePreparation : (Qubit[] => Unit is Adj + Ctl), + selector : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) + ) + : BlockEncodingReflection { return BlockEncodingToReflection(BlockEncoding(BlockEncodingByLCU(statePreparation, selector))); } diff --git a/Standard/src/Simulation/QubitizationPauliEvolutionSet.qs b/Standard/src/Simulation/QubitizationPauliEvolutionSet.qs index 805cce4a9d3..9f554dbe83a 100644 --- a/Standard/src/Simulation/QubitizationPauliEvolutionSet.qs +++ b/Standard/src/Simulation/QubitizationPauliEvolutionSet.qs @@ -41,8 +41,8 @@ namespace Microsoft.Quantum.Simulation { } /// # Summary - /// Creates a block-encoding unitary for a Hamiltonian. - /// + /// Creates a block-encoding unitary for a Hamiltonian. + /// /// The Hamiltonian $H=\sum_{j}\alpha_j P_j$ is described by a /// sum of Pauli terms $P_j$, each with real coefficient $\alpha_j$. /// @@ -66,12 +66,11 @@ namespace Microsoft.Quantum.Simulation { let statePrepUnitary = StatePreparationPositiveCoefficients; let multiplexer = MultiplexerFromGenerator; return _PauliBlockEncoding(generatorSystem, statePrepUnitary, multiplexer); - } /// # Summary - /// Creates a block-encoding unitary for a Hamiltonian. - /// + /// Creates a block-encoding unitary for a Hamiltonian. + /// /// The Hamiltonian $H=\sum_{j}\alpha_j P_j$ is described by a /// sum of Pauli terms $P_j$, each with real coefficient $\alpha_j$. /// From dd86e3629fa54aec26249465315d9e6be5b442c8 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 14 Jan 2020 11:50:13 -0800 Subject: [PATCH 23/27] Deprecate the stack data structure. --- Standard/src/Canon/DataStructures/Stack.qs | 124 +++++---------------- 1 file changed, 30 insertions(+), 94 deletions(-) diff --git a/Standard/src/Canon/DataStructures/Stack.qs b/Standard/src/Canon/DataStructures/Stack.qs index 8e690dfa631..d7c703ce582 100644 --- a/Standard/src/Canon/DataStructures/Stack.qs +++ b/Standard/src/Canon/DataStructures/Stack.qs @@ -3,90 +3,45 @@ namespace Microsoft.Quantum.Canon { - - /// # Summary - /// A last-in-first-out stack of `Result` variables. - /// The stack consists of an integer capacity, a stack pointer and a `Result` array. + @Deprecated("") newtype ResultStack = (Int, Int, Result[]); - - - /// # Summary - /// Retrieves the capacity of a . - /// - /// # Input - /// ## stack - /// The stack whose capacity is to be determined. - /// - /// # Output - /// The number of elements fitting into the stack. - function StackCapacity (stack : ResultStack) : Int - { + + + @Deprecated("") + function StackCapacity (stack : ResultStack) : Int { let (size, pos, data) = stack!; return size; } - - - /// # Summary - /// Retrieves the number of elements stored in a - /// . - /// - /// # Input - /// ## stack - /// The stack whose length is to be determined. - /// - /// # Output - /// The number of elements on the stack. - function StackLength (stack : ResultStack) : Int - { + + + @Deprecated("") + function StackLength (stack : ResultStack) : Int { let (size, pos, data) = stack!; return pos; } - - - /// # Summary - /// Removes the topmost element from a . - /// - /// # Input - /// ## stack - /// The stack to be popped. - /// - /// # Output - /// The `stack` with the top element removed. The new stack has the same capacity as - /// the old one, but its length is reduced by one. - function StackPop (stack : ResultStack) : ResultStack - { + + @Deprecated("") + function StackPop (stack : ResultStack) : ResultStack { let (size, pos, data) = stack!; - + if (pos == 0) { fail $"Cannot pop an empty stack."; } - + return ResultStack(size, pos - 1, data); } - - - /// # Summary - /// Pushes a new element onto a . - /// - /// # Input - /// ## stack - /// The stack to be grown. - /// ## datum - /// The `Result` value to be pushed onto `stack`. - /// - /// # Output - /// The `stack` with `datum` added as its new top element. The new stack's length is - /// increased by one. - function StackPush (stack : ResultStack, datum : Result) : ResultStack - { + + + @Deprecated("") + function StackPush (stack : ResultStack, datum : Result) : ResultStack { let (size, pos, data) = stack!; - + if (pos == size) { fail $"Stack is full."; } - + // FIXME: implies an O(n) copy! // This could be fixed by using a native C# operation to // wrap ImmutableStack. @@ -95,44 +50,25 @@ namespace Microsoft.Quantum.Canon set newData w/= pos <- datum; return ResultStack(size, pos + 1, newData); } - - - /// # Summary - /// Retrieves the topmost element of a . - /// - /// # Input - /// ## stack - /// The stack to be inspected. - /// - /// # Output - /// The value stored at the top of `stack`. - function StackPeek (stack : ResultStack) : Result - { + + + @Deprecated("") + function StackPeek (stack : ResultStack) : Result { let (size, pos, data) = stack!; - + if (pos == 0) { fail $"Cannot peek at an empty stack."; } - + return data[pos - 1]; } - - - /// # Summary - /// Creates a new empty with given capacity. - /// - /// # Input - /// ## size - /// The capacity of the new stack. - /// - /// # Output - /// A new `ResultStack` that has capacity `size` and length 0. - function StackNew (size : Int) : ResultStack - { + + @Deprecated("") + function StackNew (size : Int) : ResultStack { return ResultStack(size, 0, new Result[size]); } - + } From f3152d30f0390b04ee6099c137227c04b30c6235 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 14 Jan 2020 11:50:42 -0800 Subject: [PATCH 24/27] Slight improvements to phase est operations. --- .../PhaseEstimation/Iterative.qs | 55 +++++++++---------- .../PhaseEstimation/Robust.qs | 8 +-- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/Standard/src/Characterization/PhaseEstimation/Iterative.qs b/Standard/src/Characterization/PhaseEstimation/Iterative.qs index 93e351b2674..06844cec11b 100644 --- a/Standard/src/Characterization/PhaseEstimation/Iterative.qs +++ b/Standard/src/Characterization/PhaseEstimation/Iterative.qs @@ -48,29 +48,29 @@ namespace Microsoft.Quantum.Characterization { /// Register of state acted upon by the given unitary oracle. /// ## controlQubit /// An auxillary qubit used to control the application of the given oracle. - operation DiscretePhaseEstimationIteration(oracle : DiscreteOracle, power : Int, theta : Double, targetState : Qubit[], controlQubit : Qubit) : Unit - { + operation DiscretePhaseEstimationIteration( + oracle : DiscreteOracle, + power : Int, + theta : Double, + targetState : Qubit[], + controlQubit : Qubit + ) + : Unit is Adj + Ctl { // NB: We accept the control qubit as input so that we can allow for this operation // to subject to the adjoint and control modifiers (that is, such that we do not need // a return statement, but rather *act* on the given qubits). - body (...) - { - // Find the actual inversion angle by rescaling with the power of the - // oracle. - let inversionAngle = -theta * IntAsDouble(power); + // Find the actual inversion angle by rescaling with the power of the + // oracle. + let inversionAngle = -theta * IntAsDouble(power); - // Prepare the control qubit. + // Prepare the control qubit, using the within/apply block to + // return the control qubit to the appropriate measurement basis. + within { H(controlQubit); + } apply { Rz(inversionAngle, controlQubit); Controlled oracle!([controlQubit], (power, targetState)); - - // Return the control qubit to the appropriate measurement basis. - H(controlQubit); } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; } @@ -91,27 +91,26 @@ namespace Microsoft.Quantum.Characterization { /// acting on the target state. /// ## targetState /// Register of state acted upon by the given unitary oracle. - operation ContinuousPhaseEstimationIteration (oracle : ContinuousOracle, time : Double, theta : Double, targetState : Qubit[], controlQubit : Qubit) : Unit + operation ContinuousPhaseEstimationIteration( + oracle : ContinuousOracle, + time : Double, + theta : Double, + targetState : Qubit[], + controlQubit : Qubit + ) : Unit is Adj + Ctl { - body (...) - { - let inversionAngle = -(theta * time); + let inversionAngle = -(theta * time); - // Prepare the control qubit. + // Prepare the control qubit, using the within/apply block to + // return the control qubit to the appropriate measurement basis. + within { H(controlQubit); + } apply { Rz(inversionAngle, controlQubit); Controlled oracle!([controlQubit], (time, targetState)); - - // Return the control qubit to the appropriate measurement basis. - H(controlQubit); } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; } - } diff --git a/Standard/src/Characterization/PhaseEstimation/Robust.qs b/Standard/src/Characterization/PhaseEstimation/Robust.qs index 9739c6cc3af..cdb11021ceb 100644 --- a/Standard/src/Characterization/PhaseEstimation/Robust.qs +++ b/Standard/src/Characterization/PhaseEstimation/Robust.qs @@ -59,9 +59,9 @@ namespace Microsoft.Quantum.Characterization { if (result == Zero) { if (idxExperiment == 0) { - set pZero = pZero + 1.0; + set pZero += 1.0; } elif (idxExperiment == 1) { - set pPlus = pPlus + 1.0; + set pPlus += 1.0; } } @@ -76,10 +76,10 @@ namespace Microsoft.Quantum.Characterization { Reset(controlQubit); } - + return thetaEst; } - + } From a4f50f9e84e33a7bad9909b0bff9c79f6679bcd0 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 14 Jan 2020 12:43:11 -0800 Subject: [PATCH 25/27] Add missing characteristics to CNOTChainTarget. --- Standard/src/Canon/Parity.qs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Standard/src/Canon/Parity.qs b/Standard/src/Canon/Parity.qs index b270a51d880..dfd4844fb13 100644 --- a/Standard/src/Canon/Parity.qs +++ b/Standard/src/Canon/Parity.qs @@ -49,8 +49,9 @@ namespace Microsoft.Quantum.Canon { /// ```qsharp /// CNOTChain(qs); /// ``` - operation CNOTChainTarget(qubits : Qubit[], targetQubit : Qubit) : Unit { - CNOTChain(qubits + [targetQubit]); + operation CNOTChainTarget(qubits : Qubit[], targetQubit : Qubit) + : Unit is Adj + Ctl { + ApplyCNOTChain(qubits + [targetQubit]); } } From 06a349ed2d03d36d7eef08273afc3ac6cac970af Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 14 Jan 2020 12:44:56 -0800 Subject: [PATCH 26/27] =?UTF-8?q?CCNOTChainTarget=20=E2=86=92=20ApplyCNOTC?= =?UTF-8?q?hainWithTarget?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Standard/src/Canon/Deprecated.qs | 8 ++++++-- Standard/src/Canon/Parity.qs | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Standard/src/Canon/Deprecated.qs b/Standard/src/Canon/Deprecated.qs index 0d685c82649..b2a357aa7ab 100644 --- a/Standard/src/Canon/Deprecated.qs +++ b/Standard/src/Canon/Deprecated.qs @@ -26,11 +26,15 @@ namespace Microsoft.Quantum.Canon { return Xor(bit1, bit2); } - /// # Deprecated - /// Please use @"microsoft.quantum.canon.applycnotchain". @Deprecated("Microsoft.Quantum.Canon.ApplyCNOTChain") operation CNOTChain(qubits : Qubit[]) : Unit is Adj + Ctl { ApplyCNOTChain(qubits); } + @Deprecated("Microsoft.Quantum.Canon.ApplyCNOTChainWithTarget") + operation CNOTChainTarget(qubits : Qubit[], targetQubit : Qubit) + : Unit is Adj + Ctl { + ApplyCNOTChainWithTarget(qubits, targetQubit); + } + } diff --git a/Standard/src/Canon/Parity.qs b/Standard/src/Canon/Parity.qs index dfd4844fb13..041b8ff5756 100644 --- a/Standard/src/Canon/Parity.qs +++ b/Standard/src/Canon/Parity.qs @@ -43,13 +43,13 @@ namespace Microsoft.Quantum.Canon { /// # Remarks /// The following are equivalent: /// ```qsharp - /// CNOTChainTarget(Most(qs), Last(qs)); + /// ApplyCNOTChainWithTarget(Most(qs), Last(qs)); /// ``` /// and /// ```qsharp - /// CNOTChain(qs); + /// ApplyCNOTChain(qs); /// ``` - operation CNOTChainTarget(qubits : Qubit[], targetQubit : Qubit) + operation ApplyCNOTChainWithTarget(qubits : Qubit[], targetQubit : Qubit) : Unit is Adj + Ctl { ApplyCNOTChain(qubits + [targetQubit]); } From 37b95d9a1d4700de79be774cbd708758c82f4504 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 14 Jan 2020 17:48:15 -0800 Subject: [PATCH 27/27] Workaround for kata oracle counting. --- Standard/src/Characterization/Deprecated.qs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Standard/src/Characterization/Deprecated.qs b/Standard/src/Characterization/Deprecated.qs index c173160853b..2fec53af203 100644 --- a/Standard/src/Characterization/Deprecated.qs +++ b/Standard/src/Characterization/Deprecated.qs @@ -3,12 +3,14 @@ namespace Microsoft.Quantum.Characterization { open Microsoft.Quantum.Measurement as Meas; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Arrays; /// # Deprecated /// Please use @"microsoft.quantum.measurement.measureAllZ". @Deprecated("Microsoft.Quantum.Measurement.MeasureAllZ") operation MeasureAllZ(register : Qubit[]) : Result { - return Meas.MeasureAllZ(register); + return Measure(ConstantArray(Length(register), PauliZ), register); } }