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. 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/Arithmetic.qs b/Standard/src/Arithmetic/Arithmetic.qs index 1e159d11862..189d0e79ce3 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,21 +24,20 @@ 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 - /// This computes the Majority function in-place on 3 qubits. + /// Applies the three-qubit majority operation in-place on a register of + /// qubits. + /// + /// # Description + /// 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: @@ -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..3d9201c2486 100644 --- a/Standard/src/Arithmetic/Asserts.qs +++ b/Standard/src/Arithmetic/Asserts.qs @@ -9,9 +9,10 @@ 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$ /// 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..5de14dbe09c 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 is Adj + Ctl { + 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..07c9d9a306a 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 @@ -92,42 +64,37 @@ namespace Microsoft.Quantum.Arithmetic { /// # Input /// ## register /// Qubit register, only used for controls. - /// ## target + /// ## targets /// Qubit register, used for controls and as target. /// /// # 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)); + 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,102 +271,95 @@ 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, - ancilla : Qubit) : Unit - { - body (...) { - let nQubits = Length(xs!); - - EqualityFactB( - nQubits == Length(ys!), true, - "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; + operation _InnerCDKM(xs : LittleEndian, ys : LittleEndian, carry : Qubit, + ancilla : Qubit) + : Unit is Adj + Ctl { + let nQubits = Length(xs!); + + 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)] } /// # Summary - /// Reversible, in-place ripple-carry addition of two integers. + /// 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 - /// 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 - { - body (...) { - let nQubits = Length(xs!); + operation RippleCarryAdderCDKM (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." + ); - 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 - /// 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 - { + 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!); @@ -418,7 +376,6 @@ namespace Microsoft.Quantum.Arithmetic { CCNOT (xs![idx-1], ys![idx-1], xs![idx]); } } - adjoint controlled auto; } /// # Summary @@ -427,111 +384,101 @@ 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 - operation _OuterTTK (xs : LittleEndian, ys : LittleEndian) : Unit - { - body (...) { - let nQubits = Length(xs!); + /// https://arxiv.org/abs/0910.2530 + 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 - /// 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 - { - body (...) { - let nQubits = Length(xs!); - - EqualityFactB( - nQubits == Length(ys!), true, - "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]); + operation RippleCarryAdderTTK (xs : LittleEndian, ys : LittleEndian, carry : Qubit) + : Unit is Adj + Ctl { + let nQubits = Length(xs!); + + 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)); } - adjoint auto; - controlled auto; - adjoint controlled auto; + else { + CCNOT(xs![0], ys![0], carry); + } + CNOT(xs![0], ys![0]); } /// # 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 - { + 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!); @@ -547,55 +494,56 @@ 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. + /// Reversible, in-place ripple-carry addition of two integers without carry out. + /// + /// # Description /// 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 - { - 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 + /// 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 +552,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 +563,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 +595,6 @@ namespace Microsoft.Quantum.Arithmetic { ApplyToEachCA(X, ys!); } } - adjoint controlled auto; } } 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/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..e6e28337d0e 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 + /// 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 { } - 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/Canon/Combinators/ApplyIf.qs b/Standard/src/Canon/Combinators/ApplyIf.qs index 93662de16d4..69dfc6c4c9b 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 whether `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 whether `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 whether `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 whether `trueOp` or `falseOp` is /// applied. /// ## trueOp /// The unitary operation to be applied when `bit` is `true`. diff --git a/Standard/src/Canon/Combinators/ApplyMultiControlled.qs b/Standard/src/Canon/Combinators/ApplyMultiControlled.qs index ab207594dff..3a66a084c76 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/Combinators/Bind.qs b/Standard/src/Canon/Combinators/Bind.qs index 5d295731230..6bcae71b3ff 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 @@ -40,8 +36,8 @@ namespace Microsoft.Quantum.Canon { /// let bound = Bound([U, V]); /// bound(x); /// ``` - /// and - /// ```qsharp + /// and + /// ```qsharp /// U(x); V(x); /// ``` /// @@ -49,37 +45,21 @@ 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]; - 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); - } + operation _BoundA<'T> (operations : ('T => Unit is Adj)[], target : 'T) + : Unit is Adj { + for (op in operations) { + op(target); } } - - + + /// # Summary /// Given an array of operations acting on a single input, /// produces a new operation that @@ -105,43 +85,29 @@ 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) - { - return BindAImpl(operations, _); + function BoundA<'T> (operations : ('T => Unit is Adj)[]) + : ('T => Unit is Adj) { + 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]; - op(target); - } - } - - controlled (controls, ...) - { - for (idxOperation in IndexRange(operations)) - { - let op = Controlled operations[idxOperation]; - op(controls, target); - } + operation _BoundC<'T> (operations : ('T => Unit is Ctl)[], target : 'T) + : Unit is Ctl { + for (op in operations) { + op(target); } } - - + + /// # Summary /// Given an array of operations acting on a single input, /// produces a new operation that @@ -167,61 +133,28 @@ namespace Microsoft.Quantum.Canon { /// let bound = BoundC([U, V]); /// bound(x); /// ``` - /// and - /// ```qsharp + /// and + /// ```qsharp /// U(x); V(x); /// ``` /// /// # 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]; - op(target); - } - } - - adjoint (...) - { - for (idxOperation in Length(operations) - 1 .. -1 .. 0) - { - let op = Adjoint operations[idxOperation]; - op(target); - } - } - - controlled (controls, ...) - { - for (idxOperation in IndexRange(operations)) - { - let op = Controlled operations[idxOperation]; - op(controls, target); - } - } - - controlled adjoint (controls, ...) - { - for (idxOperation in Length(operations) - 1 .. -1 .. 0) - { - let op = Controlled (Adjoint operations[idxOperation]); - op(controls, target); - } + operation _BoundCA<'T> (operations : ('T => Unit is Adj + Ctl)[], target : 'T) + : Unit is Adj + Ctl { + for (op in operations) { + op(target); } } - - + + /// # Summary /// Given an array of operations acting on a single input, /// produces a new operation that @@ -248,18 +181,17 @@ namespace Microsoft.Quantum.Canon { /// let bound = BoundCA([U, V]); /// bound(x); /// ``` - /// and - /// ```qsharp + /// and + /// ```qsharp /// U(x); V(x); /// ``` /// /// # 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..95a0c5ee4f6 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..d04f3e48c29 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. - /// + /// 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 @@ -115,24 +106,19 @@ 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) - { - return UncurryOpCImpl(curriedOp, _, _); + function UncurriedOpC<'T, 'U> (curriedOp : ('T -> ('U => Unit is Ctl))) + : (('T, 'U) => Unit is Ctl) { + 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..657b0c7f085 100644 --- a/Standard/src/Canon/Combinators/OperationPow.qs +++ b/Standard/src/Canon/Combinators/OperationPow.qs @@ -1,51 +1,48 @@ // 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) - { - oracle(target); +namespace Microsoft.Quantum.Canon { + + operation _OperationPow<'T> (op : ('T => Unit), power : Int, target : 'T) + : Unit { + for (idxApplication in 0 .. power - 1) { + op(target); } } - - - operation OperationPowImplC<'T> (oracle : ('T => Unit is Ctl), power : Int, target : 'T) : Unit is Ctl { - for (idxApplication in 0 .. power - 1) - { - oracle(target); + + + operation _OperationPowC<'T> (op : ('T => Unit is Ctl), power : Int, target : 'T) + : Unit is Ctl { + for (idxApplication in 0 .. power - 1) { + op(target); } } - - - operation OperationPowImplA<'T> (oracle : ('T => Unit is Adj), power : Int, target : 'T) : Unit is Adj - { - for (idxApplication in 0 .. power - 1) - { - oracle(target); + + + operation _OperationPowA<'T> (op : ('T => Unit is Adj), power : Int, target : 'T) + : Unit is Adj { + for (idxApplication in 0 .. power - 1) { + op(target); } } - - - operation OperationPowImplCA<'T> (oracle : ('T => Unit is Adj + Ctl), power : Int, target : 'T) : Unit is Adj + Ctl - { - for (idxApplication in 0 .. power - 1) - { - oracle(target); + + + operation _OperationPowCA<'T> (op : ('T => Unit is Adj + Ctl), power : Int, target : 'T) + : Unit is Adj + Ctl { + for (idxApplication in 0 .. power - 1) { + op(target); } } - - + + /// # 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$. /// /// # Input - /// ## oracle + /// ## op /// An operation $U$ representing the gate to be repeated. /// ## power /// The number of times that $U$ is to be repeated. @@ -61,21 +58,20 @@ 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> (op : ('T => Unit), power : Int) : ('T => Unit) { + return _OperationPow(op, power, _); } - - + + /// # 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$. /// /// # Input - /// ## oracle + /// ## op /// An operation $U$ representing the gate to be repeated. /// ## power /// The number of times that $U$ is to be repeated. @@ -89,21 +85,20 @@ 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> (op : ('T => Unit is Ctl), power : Int) : ('T => Unit is Ctl) { + return _OperationPowC(op, power, _); } - - + + /// # 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$. /// /// # Input - /// ## oracle + /// ## op /// An operation $U$ representing the gate to be repeated. /// ## power /// The number of times that $U$ is to be repeated. @@ -117,21 +112,20 @@ 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> (op : ('T => Unit is Adj), power : Int) : ('T => Unit is Adj) { + return _OperationPowA(op, power, _); } - - + + /// # 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$. /// /// # Input - /// ## oracle + /// ## op /// An operation $U$ representing the gate to be repeated. /// ## power /// The number of times that $U$ is to be repeated. @@ -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> (op : ('T => Unit is Ctl + Adj), power : Int) : ('T => Unit is Ctl + Adj) { + return _OperationPowCA(op, 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/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]); } - + } diff --git a/Standard/src/Canon/Deprecated.qs b/Standard/src/Canon/Deprecated.qs index 65602fd4116..b2a357aa7ab 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,22 @@ 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); + } + + @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/Enumeration/Trotter.qs b/Standard/src/Canon/Enumeration/Trotter.qs index b8229e14ff7..dcdf635afea 100644 --- a/Standard/src/Canon/Enumeration/Trotter.qs +++ b/Standard/src/Canon/Enumeration/Trotter.qs @@ -108,30 +108,21 @@ 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 +143,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..7966b0027c0 100644 --- a/Standard/src/Canon/IterateThroughCartesianProduct.qs +++ b/Standard/src/Canon/IterateThroughCartesianProduct.qs @@ -3,54 +3,105 @@ 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 + /// ## 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. + /// ## 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..041b8ff5756 100644 --- a/Standard/src/Canon/Parity.qs +++ b/Standard/src/Canon/Parity.qs @@ -3,32 +3,33 @@ namespace Microsoft.Quantum.Canon { open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Arrays; /// # Summary - /// Computes the parity of an array 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$. + /// Computes the parity of a register of qubits in-place. + /// + /// # 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 ApplyCNOTChain(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. - /// - /// If the array is initially in the state + /// + /// # 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 /// $\ket{q_0} \ket{q_1 \oplus q_0} \cdots \ket{q_{n - 1} \oplus \cdots \oplus q_0 \oplus q_{\text{target}}}$. @@ -42,26 +43,15 @@ namespace Microsoft.Quantum.Canon { /// # Remarks /// The following are equivalent: /// ```qsharp - /// CNOTChainTarget(Most(qs), Last(qs)); + /// ApplyCNOTChainWithTarget(Most(qs), Last(qs)); /// ``` - /// and - /// ```qsharp - /// CNOTChain(qs); + /// and + /// ```qsharp + /// ApplyCNOTChain(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 ApplyCNOTChainWithTarget(qubits : Qubit[], targetQubit : Qubit) + : Unit is Adj + Ctl { + ApplyCNOTChain(qubits + [targetQubit]); } } diff --git a/Standard/src/Characterization/Deprecated.qs b/Standard/src/Characterization/Deprecated.qs new file mode 100644 index 00000000000..2fec53af203 --- /dev/null +++ b/Standard/src/Characterization/Deprecated.qs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +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 Measure(ConstantArray(Length(register), PauliZ), register); + } + +} 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); } diff --git a/Standard/src/Characterization/PhaseEstimation/Iterative.qs b/Standard/src/Characterization/PhaseEstimation/Iterative.qs index 48823f2952b..06844cec11b 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,32 +46,34 @@ 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 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); - - // Prepare the control qubit. + // Find the actual inversion angle by rescaling with the power of the + // oracle. + let inversionAngle = -theta * IntAsDouble(power); + + // 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; } - - + + /// # Summary /// Performs a single iteration of an iterative (classically-controlled) phase /// estimation algorithm using arbitrary real powers of a unitary oracle. @@ -89,40 +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); - - // Prepare the control qubit. + let inversionAngle = -(theta * time); + + // 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; } - - - 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/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; } - + } 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/ErrorCorrection/BitFlipCode.qs b/Standard/src/ErrorCorrection/BitFlipCode.qs index 4fb8d11d905..83b778b6adb 100644 --- a/Standard/src/ErrorCorrection/BitFlipCode.qs +++ b/Standard/src/ErrorCorrection/BitFlipCode.qs @@ -17,23 +17,17 @@ namespace Microsoft.Quantum.ErrorCorrection { /// /// # References /// - doi:10.1103/PhysRevA.85.044302 - operation BFEncoderImpl (coherentRecovery : Bool, data : Qubit[], scratch : Qubit[]) : Unit - { - body (...) - { - if (coherentRecovery) - { - Controlled X(scratch, data[0]); - } - - Controlled X(data, scratch[0]); - Controlled X(data, scratch[1]); + operation _BFEncoder(coherentRecovery : Bool, data : Qubit[], scratch : Qubit[]) + : Unit is Adj { + if (coherentRecovery) { + 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. /// @@ -50,14 +44,14 @@ namespace Microsoft.Quantum.ErrorCorrection { /// /// # See Also /// - LogicalRegister - operation EncodeIntoBitFlipCode(physRegister : Qubit[], auxQubits : Qubit[]) : LogicalRegister - { - BFEncoderImpl(false, physRegister, auxQubits); + operation EncodeIntoBitFlipCode(physRegister : Qubit[], auxQubits : Qubit[]) + : LogicalRegister { + _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 +66,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..cbc07cb4fe0 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,71 +23,68 @@ 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) - { + /// + 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. let z0 = M((code!)[5]); let z1 = M((code!)[2]); 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. 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 +118,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 +138,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 +154,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 +190,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; } - + } 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..25484cba36a 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 @@ -155,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, _, _)); } } diff --git a/Standard/src/Simulation/BlockEncoding.qs b/Standard/src/Simulation/BlockEncoding.qs index 25059c970bd..3eec6b4feb7 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, /// @@ -58,10 +58,10 @@ namespace Microsoft.Quantum.Simulation { newtype BlockEncodingReflection = BlockEncoding; /// # 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 + /// 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- /// left block corresponding to auxiliary state $\ket{0}_a$. That is, /// @@ -86,11 +86,11 @@ 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'$. + /// 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,28 @@ 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`. - /// + /// 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,38 +192,35 @@ 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), - selector: (('T, 'S) => Unit is Adj + Ctl)) - : (('T, 'S) => Unit is Adj + Ctl) { - return BlockEncodingByLCU_(statePreparation, selector, _, _); - } + 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), + 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; + auxiliary: 'T, + 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 @@ -243,33 +238,30 @@ 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), - 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))); } /// # 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..9f554dbe83a 100644 --- a/Standard/src/Simulation/QubitizationPauliEvolutionSet.qs +++ b/Standard/src/Simulation/QubitizationPauliEvolutionSet.qs @@ -41,9 +41,9 @@ 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 + /// 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$. /// /// # Input @@ -54,25 +54,24 @@ 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 + /// 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$. /// /// # Input @@ -89,7 +88,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 +96,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 +115,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 +123,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 +132,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; } } 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);