From 1b4ee09998e142f0700fd814e2c22fb272d9fa19 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 27 Dec 2019 11:11:10 -0800 Subject: [PATCH 1/4] Began simplifying AA interface. --- .../AmplitudeAmplification.qs | 277 +++++------------- .../CommonOracles.qs | 19 +- .../src/AmplitudeAmplification/Convert.qs | 47 +++ .../src/AmplitudeAmplification/Deprecated.qs | 32 ++ .../StandardAlgorithms.qs | 78 +++++ Standard/src/Oracles/Convert.qs | 71 ++--- Standard/src/Oracles/Types.qs | 14 +- 7 files changed, 281 insertions(+), 257 deletions(-) rename Standard/src/{Oracles => AmplitudeAmplification}/CommonOracles.qs (69%) create mode 100644 Standard/src/AmplitudeAmplification/Convert.qs create mode 100644 Standard/src/AmplitudeAmplification/Deprecated.qs create mode 100644 Standard/src/AmplitudeAmplification/StandardAlgorithms.qs diff --git a/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs b/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs index f6564b569ce..0f1aca68c9e 100644 --- a/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs +++ b/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs @@ -8,124 +8,6 @@ namespace Microsoft.Quantum.AmplitudeAmplification { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Oracles; - /// # Summary - /// Converts phases specified as single-qubit rotations to phases - /// specified as partial reflections. - /// - /// # Input - /// ## rotPhases - /// Array of single-qubit rotations to be converted to partial - /// reflections. - /// - /// # Output - /// An operation that implements phases specified as partial reflections. - /// - /// # References - /// We use the convention in - /// - [ *G.H. Low, I. L. Chuang* ](https://arxiv.org/abs/1707.05391) - /// for relating single-qubit rotation phases to reflection operator phases. - function AmpAmpRotationToReflectionPhases (rotPhases : RotationPhases) : ReflectionPhases - { - let nPhasesRot = Length(rotPhases!); - let nPhasesRef = (nPhasesRot + 1) / 2; - - if (nPhasesRot % 2 == 0) - { - fail $"Number of rotations must be odd."; - } - - mutable phasesTarget = new Double[nPhasesRef]; - mutable phasesStart = new Double[nPhasesRef]; - set phasesTarget w/= 0 <- ((rotPhases!)[0] - (rotPhases!)[1]) - PI(); - set phasesStart w/= 0 <- -(rotPhases!)[0] + 0.5 * PI(); - - for (idxPhases in 1 .. nPhasesRef - 2) - { - set phasesTarget w/= idxPhases <- ((rotPhases!)[2 * idxPhases] - (rotPhases!)[2 * idxPhases + 1]) - PI(); - set phasesStart w/= idxPhases <- ((rotPhases!)[2 * idxPhases - 1] - (rotPhases!)[2 * idxPhases]) + PI(); - } - - set phasesTarget w/= nPhasesRef - 1 <- (rotPhases!)[2 * nPhasesRef - 2] - 0.5 * PI(); - set phasesStart w/= nPhasesRef - 1 <- ((rotPhases!)[2 * nPhasesRef - 3] - (rotPhases!)[2 * nPhasesRef - 2]) + PI(); - return ReflectionPhases(phasesStart, phasesTarget); - } - - - /// # Summary - /// Computes partial reflection phases for standard amplitude - /// amplification. - /// - /// # Input - /// ## nIterations - /// Number of amplitude amplification iterations to generate partial - /// reflection phases for. - /// - /// # Output - /// An operation that implements phases specified as partial reflections - /// - /// # Remarks - /// All phases are $\pi$, except for the first reflection about the start - /// state and the last reflection about the target state, which are $0$. - function AmpAmpPhasesStandard (nIterations : Int) : ReflectionPhases - { - mutable phasesTarget = new Double[nIterations + 1]; - mutable phasesStart = new Double[nIterations + 1]; - - for (idxPhases in 0 .. nIterations) - { - set phasesTarget w/= idxPhases <- PI(); - set phasesStart w/= idxPhases <- PI(); - } - - set phasesTarget w/= nIterations <- 0.0; - set phasesStart w/= 0 <- 0.0; - return ReflectionPhases(phasesStart, phasesTarget); - } - - - // 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. - /// - /// # Input - /// ## nQueries - /// Number of queries to the state preparation oracle. Must be an odd - /// integer. - /// ## successMin - /// Target minimum success probability. - /// - /// # Output - /// Array of phases that can be used in fixed-point amplitude amplification - /// quantum algorithm implementation. - /// - /// # References - /// We use the phases in "Fixed-Point Amplitude Amplification with - /// an Optimal Number of Queries" - /// - [YoderLowChuang2014](https://arxiv.org/abs/1409.3305) - /// See also "Methodology of composite quantum gates" - /// - [LowYoderChuang2016](https://arxiv.org/abs/1603.03996) - /// for phases in the `RotationPhases` format. - function AmpAmpPhasesFixedPoint (nQueries : Int, successMin : Double) : ReflectionPhases - { - mutable phasesRot = new Double[nQueries]; - let nQueriesDouble = IntAsDouble(nQueries); - set phasesRot w/= 0 <- 0.0; - let beta = Cosh((1.0 / nQueriesDouble) * ArcCosh(Sqrt(successMin))); - - for (idxPhases in 1 .. nQueries - 1) - { - set phasesRot w/= idxPhases <- phasesRot[idxPhases - 1] + 2.0 * ArcTan(Tan((((2.0 * 1.0) * IntAsDouble(idxPhases)) * PI()) / nQueriesDouble) * Sqrt(1.0 - beta * beta)); - } - - return AmpAmpRotationToReflectionPhases(RotationPhases(phasesRot)); - } - - /// # Summary /// Oblivious amplitude amplification by specifying partial reflections. /// @@ -165,59 +47,59 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// See /// - [ *G.H. Low, I.L. Chuang* ](https://arxiv.org/abs/1610.06546) /// for a generalization to partial reflections. - operation AmpAmpObliviousByReflectionPhasesImpl (phases : ReflectionPhases, ancillaReflection : ReflectionOracle, targetStateReflection : ReflectionOracle, signalOracle : ObliviousOracle, ancillaRegister : Qubit[], systemRegister : Qubit[]) : Unit - { - body (...) - { - let (phasesAncilla, phasesTarget) = phases!; - let nphases = 2 * Length(phasesTarget); - - //FailOn(nphases != Length(phasesAncilla), "Phase array lengths not equal.") - if (phasesAncilla[0] != 0.0) - { - ancillaReflection!(phasesAncilla[0], ancillaRegister); - } - - for (idxPhases in 1 .. nphases - 1) - { - let idxPhaseAncilla = idxPhases / 2; - let idxPhaseTarget = idxPhases / 2; - - if (idxPhases % 2 == 1) - { - signalOracle!(ancillaRegister, systemRegister); - - if (phasesTarget[idxPhaseTarget] != 0.0) - { - targetStateReflection!(phasesTarget[idxPhaseTarget], ancillaRegister); - } + operation _AmpAmpObliviousByReflectionPhases( + phases : ReflectionPhases, + ancillaReflection : ReflectionOracle, + targetStateReflection : ReflectionOracle, + signalOracle : ObliviousOracle, + ancillaRegister : Qubit[], + systemRegister : Qubit[] + ) + : Unit is Adj + Ctl { + let (phasesAncilla, phasesTarget) = phases!; + let nphases = 2 * Length(phasesTarget); + + //FailOn(nphases != Length(phasesAncilla), "Phase array lengths not equal.") + if (phasesAncilla[0] != 0.0) { + ancillaReflection::ApplyReflection(phasesAncilla[0], ancillaRegister); + } + + for (idxPhases in 1 .. nphases - 1) { + let idxPhaseAncilla = idxPhases / 2; + let idxPhaseTarget = idxPhases / 2; + + if (idxPhases % 2 == 1) { + signalOracle!(ancillaRegister, systemRegister); + + if (phasesTarget[idxPhaseTarget] != 0.0) { + targetStateReflection!(phasesTarget[idxPhaseTarget], ancillaRegister); } - else - { - Adjoint signalOracle!(ancillaRegister, systemRegister); - - if (phasesAncilla[idxPhaseAncilla] != 0.0) - { - ancillaReflection!(phasesAncilla[idxPhaseAncilla], ancillaRegister); - } + } else { + Adjoint signalOracle!(ancillaRegister, systemRegister); + + if (phasesAncilla[idxPhaseAncilla] != 0.0) { + ancillaReflection::ApplyReflection( + phasesAncilla[idxPhaseAncilla], ancillaRegister + ); } } } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; } - - + + /// # Summary /// Returns a unitary that implements oblivious amplitude amplification by specifying for partial reflections. - function AmpAmpObliviousByReflectionPhases (phases : ReflectionPhases, ancillaReflection : ReflectionOracle, targetStateReflection : ReflectionOracle, signalOracle : ObliviousOracle) : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) - { - return AmpAmpObliviousByReflectionPhasesImpl(phases, ancillaReflection, targetStateReflection, signalOracle, _, _); + function AmpAmpObliviousByReflectionPhases( + phases : ReflectionPhases, + ancillaReflection : ReflectionOracle, + targetStateReflection : ReflectionOracle, + signalOracle : ObliviousOracle + ) + : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) { + return _AmpAmpObliviousByReflectionPhases(phases, ancillaReflection, targetStateReflection, signalOracle, _, _); } - - + + /// # Summary /// Oblivious amplitude amplification by oracles for partial reflections. /// @@ -243,15 +125,20 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// O\ket{\text{start}}\_{fa}\ket{\psi}\_s= \lambda\ket{1}\_f\ket{\text{anything}}\_a\ket{\text{target}}\_s U \ket{\psi}\_s + \sqrt{1-|\lambda|^2}\ket{0}\_f\cdots, /// \end{align} /// for some unitary $U$. - function AmpAmpObliviousByOraclePhases (phases : ReflectionPhases, ancillaOracle : DeterministicStateOracle, signalOracle : ObliviousOracle, idxFlagQubit : Int) : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) - { + function AmpAmpObliviousByOraclePhases( + phases : ReflectionPhases, + ancillaOracle : DeterministicStateOracle, + signalOracle : ObliviousOracle, + idxFlagQubit : Int + ) + : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) { let ancillaReflection = ReflectionStart(); let targetStateReflection = TargetStateReflectionOracle(idxFlagQubit); let oracleObliviousNew = ObliviousOracleFromDeterministicStateOracle(ancillaOracle, signalOracle); return AmpAmpObliviousByReflectionPhases(phases, ancillaReflection, targetStateReflection, oracleObliviousNew); } - - + + /// # Summary /// Amplitude amplification by partial reflections. /// @@ -271,15 +158,19 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// # Remarks /// Amplitude amplification is a special case of oblivious amplitude amplification where there are no system qubits and the oblivious oracle is set to identity. /// In most cases, `startQubits` is initialized in the state $\ket{\text{start}}\_1$, which is the $-1$ eigenstate of `startStateReflection`. - function AmpAmpByReflectionsPhases (phases : ReflectionPhases, startStateReflection : ReflectionOracle, targetStateReflection : ReflectionOracle) : (Qubit[] => Unit is Adj + Ctl) - { + function AmpAmpByReflectionsPhases( + phases : ReflectionPhases, + startStateReflection : ReflectionOracle, + targetStateReflection : ReflectionOracle + ) + : (Qubit[] => Unit is Adj + Ctl) { // Pass empty qubit array using fact that NoOp does nothing. let qubitEmpty = new Qubit[0]; let signalOracle = ObliviousOracle(NoOp<(Qubit[], Qubit[])>); return (AmpAmpObliviousByReflectionPhases(phases, startStateReflection, targetStateReflection, signalOracle))(_, qubitEmpty); } - - + + /// # Summary /// Amplitude amplification by oracles for partial reflections. /// @@ -312,8 +203,8 @@ namespace Microsoft.Quantum.AmplitudeAmplification { let ancillaOracle = DeterministicStateOracleFromStateOracle(idxFlagQubit, stateOracle); return (AmpAmpObliviousByOraclePhases(phases, ancillaOracle, signalOracle, idxFlagQubit))(_, qubitEmpty); } - - + + /// # Summary /// Standard Amplitude Amplification algorithm /// @@ -346,11 +237,11 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// - [ *G. Brassard, P. Hoyer, M. Mosca, A. Tapp* ](https://arxiv.org/abs/quant-ph/0005055) function AmpAmpByOracle (nIterations : Int, stateOracle : StateOracle, idxFlagQubit : Int) : (Qubit[] => Unit is Adj + Ctl) { - let phases = AmpAmpPhasesStandard(nIterations); + let phases = StandardReflectionPhases(nIterations); return AmpAmpByOraclePhases(phases, stateOracle, idxFlagQubit); } - - + + /// # Summary /// Fixed-Point Amplitude Amplification algorithm /// @@ -363,56 +254,50 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// # Remarks /// The startQubits must be in the $\ket{0 \cdots 0}$ state. This operation iterates over a number of queries in powers of $2$ until either a maximal number of queries /// is reached, or the target state is found. - operation AmpAmpRUSByOracle (statePrepOracle : StateOracle, startQubits : Qubit[]) : Unit - { + operation AmpAmpRUSByOracle(statePrepOracle : StateOracle, startQubits : Qubit[]) + : Unit { // Should be a power of 2 let queriesMax = 999; let successMin = 0.99; mutable finished = Zero; mutable exponentMax = 0; mutable exponentCurrent = 0; - + //Complexity: Let \theta = \mathcal{O}(\sqrt{lambda}) // Number of Measurements = O( Log^2(1/\theta) ) // Number of Queries = O(1/\theta) - using (flagQubit = Qubit[1]) - { + using (flagQubit = Qubit[1]) { let qubits = flagQubit + startQubits; let idxFlagQubit = 0; - - repeat - { - if (2 ^ exponentMax > queriesMax) - { + + repeat { + if (2 ^ exponentMax > queriesMax) { fail $"Target state not found. Maximum number of queries exceeded."; } - - repeat - { + + repeat { let queries = 2 ^ exponentCurrent; - let phases = AmpAmpPhasesFixedPoint(queries, successMin); + let phases = FixedPointReflectionPhases(queries, successMin); (AmpAmpByOraclePhases(phases, statePrepOracle, idxFlagQubit))(qubits); set finished = M(flagQubit[0]); set exponentCurrent = exponentCurrent + 1; } until (finished == One or exponentCurrent > exponentMax) - fixup - { + fixup { // flagQubit is already in Zero for fixup to apply ResetAll(startQubits); } - + set exponentCurrent = 0; set exponentMax = exponentMax + 1; } until (finished == One) - fixup - { + fixup { ResetAll(startQubits); } } } - + } diff --git a/Standard/src/Oracles/CommonOracles.qs b/Standard/src/AmplitudeAmplification/CommonOracles.qs similarity index 69% rename from Standard/src/Oracles/CommonOracles.qs rename to Standard/src/AmplitudeAmplification/CommonOracles.qs index ba169bb7ae4..7bd2bc4e6fb 100644 --- a/Standard/src/Oracles/CommonOracles.qs +++ b/Standard/src/AmplitudeAmplification/CommonOracles.qs @@ -20,20 +20,15 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// # Summary /// Implementation of . - operation TargetStateReflectionOracleImpl (phase : Double, idxFlagQubit : Int, qubits : Qubit[]) : Unit { - body (...) { - R1(phase, qubits[idxFlagQubit]); - } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; + operation _TargetStateReflectionOracle(phase : Double, idxFlagQubit : Int, qubits : Qubit[]) + : Unit is Adj + Ctl { + R1(phase, qubits[idxFlagQubit]); } /// # Summary /// Constructs a `ReflectionOracle` about the target state uniquely marked by the flag qubit. - /// - /// The target state has a single qubit set to 1, and all others 0: $\ket{1}_f$. + /// + /// The target state has a single qubit set to 1, and all others 0: $\ket{1}_f$. /// /// # Input /// ## idxFlagQubit @@ -44,8 +39,8 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// /// # See Also /// - Microsoft.Quantum.Canon.ReflectionOracle - function TargetStateReflectionOracle (idxFlagQubit : Int) : ReflectionOracle { - return ReflectionOracle(TargetStateReflectionOracleImpl(_, idxFlagQubit, _)); + function TargetStateReflectionOracle(idxFlagQubit : Int) : ReflectionOracle { + return ReflectionOracle(_TargetStateReflectionOracle(_, idxFlagQubit, _)); } } diff --git a/Standard/src/AmplitudeAmplification/Convert.qs b/Standard/src/AmplitudeAmplification/Convert.qs new file mode 100644 index 00000000000..72bb061bbd3 --- /dev/null +++ b/Standard/src/AmplitudeAmplification/Convert.qs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.AmplitudeAmplification { + open Microsoft.Quantum.Math; + + /// # Summary + /// Converts phases specified as single-qubit rotations to phases + /// specified as partial reflections. + /// + /// # Input + /// ## rotPhases + /// Array of single-qubit rotations to be converted to partial + /// reflections. + /// + /// # Output + /// An operation that implements phases specified as partial reflections. + /// + /// # References + /// We use the convention in + /// - [ *G.H. Low, I. L. Chuang* ](https://arxiv.org/abs/1707.05391) + /// for relating single-qubit rotation phases to reflection operator phases. + function RotationPhasesAsReflectionPhases(rotPhases : RotationPhases) + : ReflectionPhases { + let nPhasesRot = Length(rotPhases!); + let nPhasesRef = (nPhasesRot + 1) / 2; + + if (nPhasesRot % 2 == 0) { + fail $"Number of rotations must be odd."; + } + + mutable phasesTarget = new Double[nPhasesRef]; + mutable phasesStart = new Double[nPhasesRef]; + set phasesTarget w/= 0 <- ((rotPhases!)[0] - (rotPhases!)[1]) - PI(); + set phasesStart w/= 0 <- -(rotPhases!)[0] + 0.5 * PI(); + + for (idxPhases in 1 .. nPhasesRef - 2) { + set phasesTarget w/= idxPhases <- ((rotPhases!)[2 * idxPhases] - (rotPhases!)[2 * idxPhases + 1]) - PI(); + set phasesStart w/= idxPhases <- ((rotPhases!)[2 * idxPhases - 1] - (rotPhases!)[2 * idxPhases]) + PI(); + } + + set phasesTarget w/= nPhasesRef - 1 <- (rotPhases!)[2 * nPhasesRef - 2] - 0.5 * PI(); + set phasesStart w/= nPhasesRef - 1 <- ((rotPhases!)[2 * nPhasesRef - 3] - (rotPhases!)[2 * nPhasesRef - 2]) + PI(); + return ReflectionPhases(phasesStart, phasesTarget); + } + +} diff --git a/Standard/src/AmplitudeAmplification/Deprecated.qs b/Standard/src/AmplitudeAmplification/Deprecated.qs new file mode 100644 index 00000000000..8904938dbc8 --- /dev/null +++ b/Standard/src/AmplitudeAmplification/Deprecated.qs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.AmplitudeAmplification { + + + /// # Deprecated + /// Please use + // @"microsoft.quantum.amplitudeamplification.rotationphasesasreflectionphases". + @Deprecated("Microsoft.Quantum.AmplitudeAmplification.RotationPhasesAsReflectionPhases") + function AmpAmpRotationToReflectionPhases (rotPhases : RotationPhases) + : ReflectionPhases { + return RotationPhasesAsReflectionPhases(rotPhases); + } + + /// # Deprecated + /// Please use + // @"microsoft.quantum.amplitudeamplification.standardreflectionphases". + @Deprecated("Microsoft.Quantum.AmplitudeAmplification.StandardReflectionPhases") + function AmpAmpPhasesStandard(nIterations : Int) : ReflectionPhases { + return StandardReflectionPhases(nIterations); + } + + /// # Deprecated + /// Please use + // @"microsoft.quantum.amplitudeamplification.fixedpointreflectionphases". + @Deprecated("Microsoft.Quantum.AmplitudeAmplification.FixedPointReflectionPhases") + function AmpAmpPhasesFixedPoint(nQueries : Int, successMin : Double) : ReflectionPhases { + return FixedPointReflectionPhases(nQueries, successMin); + } + +} diff --git a/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs b/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs new file mode 100644 index 00000000000..9bedaeee3d8 --- /dev/null +++ b/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs @@ -0,0 +1,78 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.AmplitudeAmplification { + open Microsoft.Quantum.Convert; + open Microsoft.Quantum.Arrays; + open Microsoft.Quantum.Math; + + /// # Summary + /// Computes partial reflection phases for standard amplitude + /// amplification. + /// + /// # Input + /// ## nIterations + /// Number of amplitude amplification iterations to generate partial + /// reflection phases for. + /// + /// # Output + /// An operation that implements phases specified as partial reflections + /// + /// # Remarks + /// All phases are $\pi$, except for the first reflection about the start + /// state and the last reflection about the target state, which are $0$. + function StandardReflectionPhases(nIterations : Int) : ReflectionPhases { + let commonPhases = ConstantArray(nIterations, PI()); + let targetPhases = commonPhases + [0.0]; + let startPhases = [0.0] + commonPhases; + 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. + /// + /// # Input + /// ## nQueries + /// Number of queries to the state preparation oracle. Must be an odd + /// integer. + /// ## successMin + /// Target minimum success probability. + /// + /// # Output + /// Array of phases that can be used in fixed-point amplitude amplification + /// quantum algorithm implementation. + /// + /// # References + /// We use the phases in "Fixed-Point Amplitude Amplification with + /// an Optimal Number of Queries" + /// - [YoderLowChuang2014](https://arxiv.org/abs/1409.3305) + /// See also "Methodology of composite quantum gates" + /// - [LowYoderChuang2016](https://arxiv.org/abs/1603.03996) + /// for phases in the `RotationPhases` format. + function FixedPointReflectionPhases(nQueries : Int, successMin : Double) + : ReflectionPhases { + let twoPi = 2.0 * PI(); + mutable phasesRot = new Double[nQueries]; + let nQueriesDouble = IntAsDouble(nQueries); + set phasesRot w/= 0 <- 0.0; + let beta = Cosh((1.0 / nQueriesDouble) * ArcCosh(Sqrt(successMin))); + let alpha = Sqrt(1.0 - beta * beta); + + for (idxPhases in 1 .. nQueries - 1) { + set phasesRot w/= idxPhases <- + phasesRot[idxPhases - 1] + + 2.0 * ArcTan( + Tan(twoPi * IntAsDouble(idxPhases) / nQueriesDouble) * alpha + ); + } + + return RotationPhasesAsReflectionPhases(RotationPhases(phasesRot)); + } + +} diff --git a/Standard/src/Oracles/Convert.qs b/Standard/src/Oracles/Convert.qs index 0f9650c653a..3b804227e36 100644 --- a/Standard/src/Oracles/Convert.qs +++ b/Standard/src/Oracles/Convert.qs @@ -6,20 +6,13 @@ namespace Microsoft.Quantum.Oracles { /// # Summary /// Implementation of . - operation _ObliviousOracleFromDeterministicStateOracle (ancillaOracle : DeterministicStateOracle, signalOracle : ObliviousOracle, ancillaRegister : Qubit[], systemRegister : Qubit[]) : Unit - { - body (...) - { - ancillaOracle!(ancillaRegister); - signalOracle!(ancillaRegister, systemRegister); - } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; + operation _ObliviousOracleFromDeterministicStateOracle(ancillaOracle : DeterministicStateOracle, signalOracle : ObliviousOracle, ancillaRegister : Qubit[], systemRegister : Qubit[]) + : Unit is Adj + Ctl { + ancillaOracle!(ancillaRegister); + signalOracle!(ancillaRegister, systemRegister); } - - + + /// # Summary /// Combines the oracles `DeterministicStateOracle` and `ObliviousOracle`. /// @@ -35,27 +28,19 @@ namespace Microsoft.Quantum.Oracles { /// # See Also /// - Microsoft.Quantum.Canon.DeterministicStateOracle /// - Microsoft.Quantum.Canon.ObliviousOracle - function ObliviousOracleFromDeterministicStateOracle (ancillaOracle : DeterministicStateOracle, signalOracle : ObliviousOracle) : ObliviousOracle - { + function ObliviousOracleFromDeterministicStateOracle (ancillaOracle : DeterministicStateOracle, signalOracle : ObliviousOracle) : ObliviousOracle { return ObliviousOracle(_ObliviousOracleFromDeterministicStateOracle(ancillaOracle, signalOracle, _, _)); } - - + + /// # Summary /// Implementation of . - operation _DeterministicStateOracleFromStateOracle (idxFlagQubit : Int, stateOracle : StateOracle, startQubits : Qubit[]) : Unit - { - body (...) - { - stateOracle!(idxFlagQubit, startQubits); - } - - adjoint invert; - controlled distribute; - controlled adjoint distribute; + operation _DeterministicStateOracleFromStateOracle (idxFlagQubit : Int, stateOracle : StateOracle, startQubits : Qubit[]) + : Unit is Adj + Ctl { + stateOracle!(idxFlagQubit, startQubits); } - - + + /// # Summary /// Converts an oracle of type `StateOracle` to `DeterministicStateOracle`. /// @@ -79,8 +64,8 @@ namespace Microsoft.Quantum.Oracles { { return DeterministicStateOracle(_DeterministicStateOracleFromStateOracle(idxFlagQubit, stateOracle, _)); } - - + + /// # Summary /// Implementation of . operation _StateOracleFromDeterministicStateOracle (idxFlagQubit : Int, oracleStateDeterministic : DeterministicStateOracle, qubits : Qubit[]) : Unit @@ -89,13 +74,13 @@ namespace Microsoft.Quantum.Oracles { { oracleStateDeterministic!(qubits); } - + adjoint invert; controlled distribute; controlled adjoint distribute; } - - + + /// # Summary /// Converts an oracle of type `DeterministicStateOracle` to `StateOracle`. /// @@ -115,8 +100,8 @@ namespace Microsoft.Quantum.Oracles { { return StateOracle(_StateOracleFromDeterministicStateOracle(_, deterministicStateOracle, _)); } - - + + /// # Summary /// Implementation of . operation ReflectionOracleFromDeterministicStateOracleImpl (phase : Double, oracle : DeterministicStateOracle, systemRegister : Qubit[]) : Unit @@ -125,20 +110,20 @@ namespace Microsoft.Quantum.Oracles { { ApplyWithCA(Adjoint oracle!, RAll0(phase, _), systemRegister); } - + adjoint invert; controlled distribute; controlled adjoint distribute; } - - + + /// # Summary /// Constructs reflection about a given state from an oracle. - /// - /// Given the oracle $O$ of type + /// + /// 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}$. + /// the result of this function is a reflection around the state $\ket{\psi}$ + /// where $O\ket{0} = \ket{\psi}$. /// /// # Input /// ## oracle diff --git a/Standard/src/Oracles/Types.qs b/Standard/src/Oracles/Types.qs index a3c395ffd95..0350cd20125 100644 --- a/Standard/src/Oracles/Types.qs +++ b/Standard/src/Oracles/Types.qs @@ -14,7 +14,9 @@ namespace Microsoft.Quantum.Oracles { /// This oracle $O = \boldone - (1 - e^{i \phi}) \ket{\psi}\bra{\psi}$ /// performs a partial reflection by a phase $\phi$ about a single pure state /// $\ket{\psi}$. - newtype ReflectionOracle = ((Double, Qubit[]) => Unit is Adj + Ctl); + newtype ReflectionOracle = ( + ApplyReflection: ((Double, Qubit[]) => Unit is Adj + Ctl) + ); // This oracle O|s>_a|ψ>_s = λ |t>_a U |ψ>_s + ... acts on the ancilla state |s>_a to implement the unitary U on any system state |ψ>_s with amplitude λ in the |t>_a basis. @@ -28,7 +30,7 @@ namespace Microsoft.Quantum.Oracles { /// # Remarks /// This oracle defined by /// $$ - ///O\ket{s}\_a\ket{\psi}\_s= \lambda\ket{t}\_a U \ket{\psi}\_s + \sqrt{1-|\lambda|^2}\ket{t^\perp}\_a\cdots + /// O\ket{s}\_a\ket{\psi}\_s= \lambda\ket{t}\_a U \ket{\psi}\_s + \sqrt{1-|\lambda|^2}\ket{t^\perp}\_a\cdots /// $$ /// acts on the ancilla state $\ket{s}\_a$ to implement the unitary $U$ on any system state $\ket{\psi}\_s$ with amplitude $\lambda$ in the basis flagged by $\ket{t}\_a$. /// The first parameter is the qubit register of $\ket{s}\_a$. The second parameter is the qubit register of $\ket{\psi}\_s$. @@ -64,15 +66,15 @@ namespace Microsoft.Quantum.Oracles { /// # Summary /// Represents a discrete-time oracle. - /// - /// This is an oracle that implements $U^m$ for a fixed operation $U$ + /// + /// This is an oracle that implements $U^m$ for a fixed operation $U$ /// and a non-negative integer $m$. newtype DiscreteOracle = ((Int, Qubit[]) => Unit is Adj + Ctl); /// # Summary /// Represents a continuous-time oracle. - /// - /// This is an oracle that implements + /// + /// This is an oracle that implements /// $U(\delta t) : \ket{\psi(t)} \mapsto \ket{\psi(t + \delta t)}$ /// for all times $t$, where $U$ is a fixed operation, and where /// $\delta t$ is a non-negative real number. From 459a18e1e875ba8268c07a48e9fccfed78df471b Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 27 Dec 2019 12:34:51 -0800 Subject: [PATCH 2/4] Expose traditional AA as new public operation. --- .../AmplitudeAmplification.qs | 113 +++++++++++------- .../src/AmplitudeAmplification/Deprecated.qs | 37 +++++- Standard/src/AmplitudeAmplification/Types.qs | 9 +- 3 files changed, 108 insertions(+), 51 deletions(-) diff --git a/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs b/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs index 0f1aca68c9e..ee66c03fc34 100644 --- a/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs +++ b/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs @@ -2,6 +2,7 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.AmplitudeAmplification { + open Microsoft.Quantum.Arrays; open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Convert; open Microsoft.Quantum.Math; @@ -14,31 +15,31 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// # Input /// ## phases /// Phases of partial reflections - /// ## ancillaReflection - /// Reflection operator about start state of ancilla register + /// ## startStateReflection + /// Reflection operator about start state of auxiliary register /// ## targetStateReflection - /// Reflection operator about target state of ancilla register + /// Reflection operator about target state of auxiliary register /// ## signalOracle /// Unitary oracle $O$ of type `ObliviousOracle` that acts jointly on the - /// ancilla and system registers. - /// ## ancillaRegister - /// Ancilla register + /// auxiliary and system registers. + /// ## auxiliaryRegister + /// Auxiliary register /// ## systemRegister /// System register /// /// # Remarks - /// Given a particular ancilla start state $\ket{\text{start}}\_a$, a - /// particular ancilla target state $\ket{\text{target}}\_a$, and any + /// Given a particular auxiliary start state $\ket{\text{start}}\_a$, a + /// particular auxiliary target state $\ket{\text{target}}\_a$, and any /// system state $\ket{\psi}\_s$, suppose that /// \begin{align} /// O\ket{\text{start}}\_a\ket{\psi}\_s= \lambda\ket{\text{target}}\_a U \ket{\psi}\_s + \sqrt{1-|\lambda|^2}\ket{\text{target}^\perp}\_a\cdots /// \end{align} /// for some unitary $U$. /// By a sequence of reflections about the start and target states on the - /// ancilla register interleaved by applications of `signalOracle` and its + /// auxiliary register interleaved by applications of `signalOracle` and its /// adjoint, the success probability of applying U may be altered. /// - /// In most cases, `ancillaRegister` is initialized in the state $\ket{\text{start}}\_a$. + /// In most cases, `auxiliaryRegister` is initialized in the state $\ket{\text{start}}\_a$. /// /// # References /// See @@ -47,56 +48,53 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// See /// - [ *G.H. Low, I.L. Chuang* ](https://arxiv.org/abs/1610.06546) /// for a generalization to partial reflections. - operation _AmpAmpObliviousByReflectionPhases( + operation ApplyObliviousAmplitudeAmplification( phases : ReflectionPhases, - ancillaReflection : ReflectionOracle, + startStateReflection : ReflectionOracle, targetStateReflection : ReflectionOracle, signalOracle : ObliviousOracle, - ancillaRegister : Qubit[], + auxiliaryRegister : Qubit[], systemRegister : Qubit[] ) : Unit is Adj + Ctl { - let (phasesAncilla, phasesTarget) = phases!; - let nphases = 2 * Length(phasesTarget); - - //FailOn(nphases != Length(phasesAncilla), "Phase array lengths not equal.") - if (phasesAncilla[0] != 0.0) { - ancillaReflection::ApplyReflection(phasesAncilla[0], ancillaRegister); - } - - for (idxPhases in 1 .. nphases - 1) { - let idxPhaseAncilla = idxPhases / 2; - let idxPhaseTarget = idxPhases / 2; - - if (idxPhases % 2 == 1) { - signalOracle!(ancillaRegister, systemRegister); - - if (phasesTarget[idxPhaseTarget] != 0.0) { - targetStateReflection!(phasesTarget[idxPhaseTarget], ancillaRegister); - } - } else { - Adjoint signalOracle!(ancillaRegister, systemRegister); + for ((startPhase, targetPhase) in Zip(phases!)) { + if (startPhase != 0.0) { + startStateReflection::ApplyReflection( + startPhase, auxiliaryRegister + ); + } - if (phasesAncilla[idxPhaseAncilla] != 0.0) { - ancillaReflection::ApplyReflection( - phasesAncilla[idxPhaseAncilla], ancillaRegister - ); + within { + signalOracle!(auxiliaryRegister, systemRegister); + } apply { + if (targetPhase != 0.0) { + targetStateReflection!(targetPhase, auxiliaryRegister); } } } + // This gives us one extra application of Adjoint signalOracle!, so we + // apply the forward direction at the end. + signalOracle!(auxiliaryRegister, systemRegister); } + // NB [STYLE]: The name of this operation uses "From" as it is not a type + // conversion function ("As"), but something that constructs + // an operation from given information in a deterministic + // fashion. /// # Summary /// Returns a unitary that implements oblivious amplitude amplification by specifying for partial reflections. - function AmpAmpObliviousByReflectionPhases( + function ObliviousAmplitudeAmplificationFromPartialReflections( phases : ReflectionPhases, - ancillaReflection : ReflectionOracle, + startStateReflection : ReflectionOracle, targetStateReflection : ReflectionOracle, signalOracle : ObliviousOracle ) : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) { - return _AmpAmpObliviousByReflectionPhases(phases, ancillaReflection, targetStateReflection, signalOracle, _, _); + return ApplyObliviousAmplitudeAmplification( + phases, startStateReflection, targetStateReflection, signalOracle, + _, _ + ); } @@ -125,17 +123,38 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// O\ket{\text{start}}\_{fa}\ket{\psi}\_s= \lambda\ket{1}\_f\ket{\text{anything}}\_a\ket{\text{target}}\_s U \ket{\psi}\_s + \sqrt{1-|\lambda|^2}\ket{0}\_f\cdots, /// \end{align} /// for some unitary $U$. - function AmpAmpObliviousByOraclePhases( + function ObliviousAmplitudeAmplificationFromStatePreparation( phases : ReflectionPhases, - ancillaOracle : DeterministicStateOracle, + startStateOracle : DeterministicStateOracle, signalOracle : ObliviousOracle, idxFlagQubit : Int ) : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) { - let ancillaReflection = ReflectionStart(); + let startStateReflection = ReflectionStart(); let targetStateReflection = TargetStateReflectionOracle(idxFlagQubit); - let oracleObliviousNew = ObliviousOracleFromDeterministicStateOracle(ancillaOracle, signalOracle); - return AmpAmpObliviousByReflectionPhases(phases, ancillaReflection, targetStateReflection, oracleObliviousNew); + let obliviousSignalOracle = ObliviousOracleFromDeterministicStateOracle( + startStateOracle, signalOracle + ); + return ObliviousAmplitudeAmplificationFromPartialReflections( + phases, startStateReflection, targetStateReflection, obliviousSignalOracle + ); + } + + operation ApplyAmplitudeAmplification( + phases : ReflectionPhases, + startStateReflection : ReflectionOracle, + targetStateReflection : ReflectionOracle, + target : Qubit[] + ) + : Unit is Adj + Ctl { + // Pass empty qubit array using fact that NoOp does nothing. + let systemRegister = new Qubit[0]; + let signalOracle = ObliviousOracle(NoOp<(Qubit[], Qubit[])>); + let op = ObliviousAmplitudeAmplificationFromPartialReflections( + phases, startStateReflection, targetStateReflection, signalOracle + ); + + op(target, systemRegister); } @@ -167,7 +186,9 @@ namespace Microsoft.Quantum.AmplitudeAmplification { // Pass empty qubit array using fact that NoOp does nothing. let qubitEmpty = new Qubit[0]; let signalOracle = ObliviousOracle(NoOp<(Qubit[], Qubit[])>); - return (AmpAmpObliviousByReflectionPhases(phases, startStateReflection, targetStateReflection, signalOracle))(_, qubitEmpty); + return (ObliviousAmplitudeAmplificationFromPartialReflections( + phases, startStateReflection, targetStateReflection, signalOracle + ))(_, qubitEmpty); } diff --git a/Standard/src/AmplitudeAmplification/Deprecated.qs b/Standard/src/AmplitudeAmplification/Deprecated.qs index 8904938dbc8..d2a9ac55087 100644 --- a/Standard/src/AmplitudeAmplification/Deprecated.qs +++ b/Standard/src/AmplitudeAmplification/Deprecated.qs @@ -2,11 +2,12 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.AmplitudeAmplification { + open Microsoft.Quantum.Oracles; /// # Deprecated /// Please use - // @"microsoft.quantum.amplitudeamplification.rotationphasesasreflectionphases". + /// @"microsoft.quantum.amplitudeamplification.rotationphasesasreflectionphases". @Deprecated("Microsoft.Quantum.AmplitudeAmplification.RotationPhasesAsReflectionPhases") function AmpAmpRotationToReflectionPhases (rotPhases : RotationPhases) : ReflectionPhases { @@ -15,7 +16,7 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// # Deprecated /// Please use - // @"microsoft.quantum.amplitudeamplification.standardreflectionphases". + /// @"microsoft.quantum.amplitudeamplification.standardreflectionphases". @Deprecated("Microsoft.Quantum.AmplitudeAmplification.StandardReflectionPhases") function AmpAmpPhasesStandard(nIterations : Int) : ReflectionPhases { return StandardReflectionPhases(nIterations); @@ -23,10 +24,40 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// # Deprecated /// Please use - // @"microsoft.quantum.amplitudeamplification.fixedpointreflectionphases". + /// @"microsoft.quantum.amplitudeamplification.fixedpointreflectionphases". @Deprecated("Microsoft.Quantum.AmplitudeAmplification.FixedPointReflectionPhases") function AmpAmpPhasesFixedPoint(nQueries : Int, successMin : Double) : ReflectionPhases { return FixedPointReflectionPhases(nQueries, successMin); } + /// # Deprecated + /// Please use @"microsoft.quantum.amplitudeamplification.obliviousamplitudeamplificationfrompartialreflections". + @Deprecated("Microsoft.Quantum.AmplitudeAmplification.ObliviousAmplitudeAmplificationFromPartialReflections") + function AmpAmpObliviousByReflectionPhases( + phases : ReflectionPhases, + startStateReflection : ReflectionOracle, + targetStateReflection : ReflectionOracle, + signalOracle : ObliviousOracle + ) + : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) { + return ObliviousAmplitudeAmplificationFromPartialReflections( + phases, startStateReflection, targetStateReflection, signalOracle + ); + } + + /// # Deprecated + /// Please use @"microsoft.quantum.amplitudeamplification.obliviousamplitudeamplificationfromstatepreparation". + @Deprecated("Microsoft.Quantum.AmplitudeAmplification.ObliviousAmplitudeAmplificationFromStatePreparation") + function AmpAmpObliviousByOraclePhases( + phases : ReflectionPhases, + startStateOracle : DeterministicStateOracle, + signalOracle : ObliviousOracle, + idxFlagQubit : Int + ) + : ((Qubit[], Qubit[]) => Unit is Adj + Ctl) { + return ObliviousAmplitudeAmplificationFromStatePreparation( + phases, startStateOracle, signalOracle, idxFlagQubit + ); + } + } diff --git a/Standard/src/AmplitudeAmplification/Types.qs b/Standard/src/AmplitudeAmplification/Types.qs index 57f3fa2d007..5addb42ddfa 100644 --- a/Standard/src/AmplitudeAmplification/Types.qs +++ b/Standard/src/AmplitudeAmplification/Types.qs @@ -7,9 +7,14 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// Phases for a sequence of partial reflections in amplitude amplification. /// /// # Remarks - /// The first parameter is an array of phases for reflection about the start state. The second parameter is an array of phases for reflection about the target state. + /// The first parameter is an array of phases for reflection about the + /// start state. The second parameter is an array of phases for reflection + /// about the target state. /// Both arrays must be of equal length. Note that in many cases, the first phase about the start state and last phase about the target state introduces a global phase shift and may be set to $0$. - newtype ReflectionPhases = (Double[], Double[]); + newtype ReflectionPhases = ( + AboutStart: Double[], + AboutTarget: Double[] + ); /// # Summary /// Phases for a sequence of single-qubit rotations in amplitude amplification. From 76b6a87531a0fdc73eb659e0b011aeb204a88bbf Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 27 Dec 2019 13:22:12 -0800 Subject: [PATCH 3/4] Removed rest of "AmpAmp" prefix. --- .../AmplitudeAmplification.qs | 67 ++++++++++++++----- .../src/AmplitudeAmplification/Deprecated.qs | 49 ++++++++++++++ 2 files changed, 98 insertions(+), 18 deletions(-) diff --git a/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs b/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs index ee66c03fc34..dde60e11be4 100644 --- a/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs +++ b/Standard/src/AmplitudeAmplification/AmplitudeAmplification.qs @@ -104,10 +104,11 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// # Input /// ## phases /// Phases of partial reflections - /// ## ancillaOracle - /// Unitary oracle $A$ that prepares ancilla start state + /// ## startStateOracle + /// Unitary oracle $A$ that prepares auxiliary start state /// ## signalOracle - /// Unitary oracle $O$ of type `ObliviousOracle` that acts jointly on the ancilla and system register + /// Unitary oracle $O$ of type `ObliviousOracle` that acts jointly on the + /// auxiliary and system register /// ## idxFlagQubit /// Index to single-qubit flag register /// @@ -115,8 +116,8 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// An operation that implements oblivious amplitude amplification based on partial reflections. /// /// # Remarks - /// This imposes stricter conditions on form of the ancilla start and target states than in `AmpAmpObliviousByReflectionPhases`. - /// It is assumed that $A\ket{0}\_f\ket{0}\_a= \ket{\text{start}}\_{fa}$ prepares the ancilla start state $\ket{\text{start}}\_{fa}$ from the computational basis $\ket{0}\_f\ket{0}$. + /// This imposes stricter conditions on form of the auxiliary start and target states than in `AmpAmpObliviousByReflectionPhases`. + /// It is assumed that $A\ket{0}\_f\ket{0}\_a= \ket{\text{start}}\_{fa}$ prepares the auxiliary start state $\ket{\text{start}}\_{fa}$ from the computational basis $\ket{0}\_f\ket{0}$. /// It is assumed that the target state is marked by $\ket{1}\_f$. /// It is assumed that /// \begin{align} @@ -140,6 +141,22 @@ namespace Microsoft.Quantum.AmplitudeAmplification { ); } + /// # Summary + /// Applies amplitude amplification on a given register, using a given set + /// of phases and oracles to reflect about the initial and final states. + /// + /// # Input + /// ## phases + /// A set of phases describing the partial reflections at each step of the + /// amplitude amplification algorithm. See + /// @"microsoft.quantum.amplitudeamplification.standardreflectionphases" + /// for an example. + /// ## startStateReflection + /// An oracle that reflects about the initial state. + /// ## targetStateReflection + /// An oracle that reflects about the desired final state. + /// ## target + /// A register to perform amplitude amplification on. operation ApplyAmplitudeAmplification( phases : ReflectionPhases, startStateReflection : ReflectionOracle, @@ -177,7 +194,7 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// # Remarks /// Amplitude amplification is a special case of oblivious amplitude amplification where there are no system qubits and the oblivious oracle is set to identity. /// In most cases, `startQubits` is initialized in the state $\ket{\text{start}}\_1$, which is the $-1$ eigenstate of `startStateReflection`. - function AmpAmpByReflectionsPhases( + function AmplitudeAmplificationFromPartialReflections( phases : ReflectionPhases, startStateReflection : ReflectionOracle, targetStateReflection : ReflectionOracle @@ -192,6 +209,10 @@ namespace Microsoft.Quantum.AmplitudeAmplification { } + // NB [STYLE]: The name of this operation uses "From" as it is not a type + // conversion function ("As"), but something that constructs + // an operation from given information in a deterministic + // fashion. /// # Summary /// Amplitude amplification by oracles for partial reflections. /// @@ -216,13 +237,19 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// \begin{align} /// A\ket{0}\_{f}\ket{0}\_s= \lambda\ket{1}\_f\ket{\text{target}}\_s + \sqrt{1-|\lambda|^2}\ket{0}\_f\cdots, /// \end{align} - /// In most cases, `flagQubit` and `ancillaRegister` is initialized in the state $\ket{0}\_{f}\ket{0}\_s$. - function AmpAmpByOraclePhases (phases : ReflectionPhases, stateOracle : StateOracle, idxFlagQubit : Int) : (Qubit[] => Unit is Adj + Ctl) - { - let qubitEmpty = new Qubit[0]; + /// In most cases, `flagQubit` and `auxiliaryRegister` are initialized in the state $\ket{0}\_{f}\ket{0}\_s$. + function AmplitudeAmplificationFromStatePreparation( + phases : ReflectionPhases, + stateOracle : StateOracle, + idxFlagQubit : Int + ) + : (Qubit[] => Unit is Adj + Ctl) { + let systemRegister = new Qubit[0]; let signalOracle = ObliviousOracle(NoOp<(Qubit[], Qubit[])>); - let ancillaOracle = DeterministicStateOracleFromStateOracle(idxFlagQubit, stateOracle); - return (AmpAmpObliviousByOraclePhases(phases, ancillaOracle, signalOracle, idxFlagQubit))(_, qubitEmpty); + let startStateOracle = DeterministicStateOracleFromStateOracle(idxFlagQubit, stateOracle); + return (ObliviousAmplitudeAmplificationFromStatePreparation( + phases, startStateOracle, signalOracle, idxFlagQubit + ))(_, systemRegister); } @@ -252,14 +279,18 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// \begin{align} /// \operatorname{AmpAmpByOracle}\ket{0}\_{f}\ket{0}\_s= \sin((2n+1)\sin^{-1}(\lambda))\ket{1}\_f\ket{\text{target}}\_s + \cdots\ket{0}\_f /// \end{align} - /// In most cases, `flagQubit` and `ancillaRegister` is initialized in the state $\ket{0}\_f\ket{0}\_a$. + /// In most cases, `flagQubit` and `auxiliaryRegister` is initialized in the state $\ket{0}\_f\ket{0}\_a$. /// /// # References /// - [ *G. Brassard, P. Hoyer, M. Mosca, A. Tapp* ](https://arxiv.org/abs/quant-ph/0005055) - function AmpAmpByOracle (nIterations : Int, stateOracle : StateOracle, idxFlagQubit : Int) : (Qubit[] => Unit is Adj + Ctl) - { + function StandardAmplitudeAmplification( + nIterations : Int, + stateOracle : StateOracle, + idxFlagQubit : Int + ) + : (Qubit[] => Unit is Adj + Ctl) { let phases = StandardReflectionPhases(nIterations); - return AmpAmpByOraclePhases(phases, stateOracle, idxFlagQubit); + return AmplitudeAmplificationFromStatePreparation(phases, stateOracle, idxFlagQubit); } @@ -275,7 +306,7 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// # Remarks /// The startQubits must be in the $\ket{0 \cdots 0}$ state. This operation iterates over a number of queries in powers of $2$ until either a maximal number of queries /// is reached, or the target state is found. - operation AmpAmpRUSByOracle(statePrepOracle : StateOracle, startQubits : Qubit[]) + operation ApplyFixedPointAmplification(statePrepOracle : StateOracle, startQubits : Qubit[]) : Unit { // Should be a power of 2 let queriesMax = 999; @@ -299,7 +330,7 @@ namespace Microsoft.Quantum.AmplitudeAmplification { repeat { let queries = 2 ^ exponentCurrent; let phases = FixedPointReflectionPhases(queries, successMin); - (AmpAmpByOraclePhases(phases, statePrepOracle, idxFlagQubit))(qubits); + (AmplitudeAmplificationFromStatePreparation(phases, statePrepOracle, idxFlagQubit))(qubits); set finished = M(flagQubit[0]); set exponentCurrent = exponentCurrent + 1; } diff --git a/Standard/src/AmplitudeAmplification/Deprecated.qs b/Standard/src/AmplitudeAmplification/Deprecated.qs index d2a9ac55087..6f0f2158ac4 100644 --- a/Standard/src/AmplitudeAmplification/Deprecated.qs +++ b/Standard/src/AmplitudeAmplification/Deprecated.qs @@ -60,4 +60,53 @@ namespace Microsoft.Quantum.AmplitudeAmplification { ); } + /// # Deprecated + /// Please use @"microsoft.quantum.amplitudeamplification.amplitudeamplificationfrompartialreflections". + @Deprecated("Microsoft.Quantum.AmplitudeAmplification.AmplitudeAmplificationFromPartialReflections") + function AmpAmpByReflectionPhases( + phases : ReflectionPhases, + startStateReflection : ReflectionOracle, + targetStateReflection : ReflectionOracle + ) + : (Qubit[] => Unit is Adj + Ctl) { + return AmplitudeAmplificationFromPartialReflections( + phases, startStateReflection, targetStateReflection + ); + } + + /// # Deprecated + /// Please use @"microsoft.quantum.amplitudeamplification.amplitudeamplificationfromstatepreparation". + @Deprecated("Microsoft.Quantum.AmplitudeAmplification.AmplitudeAmplificationFromStatePreparation") + function AmpAmpByOraclePhases( + phases : ReflectionPhases, + stateOracle : StateOracle, + idxFlagQubit : Int + ) + : (Qubit[] => Unit is Adj + Ctl) { + return AmplitudeAmplificationFromStatePreparation( + phases, stateOracle, idxFlagQubit + ); + } + + /// # Deprecated + /// Please use @"microsoft.quantum.amplitudeamplification.standardamplitudeamplification". + @Deprecated("Microsoft.Quantum.AmplitudeAmplification.StandardAmplitudeAmplification") + function AmpAmpByOracle( + nIterations : Int, + stateOracle : StateOracle, + idxFlagQubit : Int + ) + : (Qubit[] => Unit is Adj + Ctl) { + return StandardAmplitudeAmplification(nIterations, stateOracle, idxFlagQubit); + } + + + /// # Deprecated + /// Please use @"microsoft.quantum.amplitudeamplification.applyfixedpointamplification". + @Deprecated("Microsoft.Quantum.AmplitudeAmplification.ApplyFixedPointAmplification") + operation AmpAmpRUSByOracle(statePrepOracle : StateOracle, startQubits : Qubit[]) + : Unit { + ApplyFixedPointAmplification(statePrepOracle, startQubits); + } + } From 90238fba39669482e7729b0562360d6d624684a1 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Mon, 30 Dec 2019 11:32:36 -0800 Subject: [PATCH 4/4] Resolve deprecation warning. --- Standard/src/Preparation/UniformSuperposition.qs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Standard/src/Preparation/UniformSuperposition.qs b/Standard/src/Preparation/UniformSuperposition.qs index 6cd27f4fdb8..177c43dcef9 100644 --- a/Standard/src/Preparation/UniformSuperposition.qs +++ b/Standard/src/Preparation/UniformSuperposition.qs @@ -9,12 +9,12 @@ namespace Microsoft.Quantum.Preparation { open Microsoft.Quantum.AmplitudeAmplification; open Microsoft.Quantum.Oracles; open Microsoft.Quantum.Math; - + /// # Summary - /// Creates a uniform superposition over states that encode 0 through `nIndices`. - /// + /// Creates a uniform superposition over states that encode 0 through `nIndices`. + /// /// That is, this unitary $U$ creates a uniform superposition over all number states - /// $0$ to $M-1$, given an input state $\ket{0\cdots 0}$. In other words, + /// $0$ to $M-1$, given an input state $\ket{0\cdots 0}$. In other words, /// $$ /// \begin{align} /// U\ket{0}=\frac{1}{\sqrt{M}}\sum_{j=0}^{M-1}\ket{j}. @@ -57,7 +57,7 @@ namespace Microsoft.Quantum.Preparation { let qubits = flagQubit + targetQubits; let stateOracle = StateOracle(PrepareUniformSuperposition_(nIndices, nQubits, _, _)); - (AmpAmpByOracle(1, stateOracle, 0))(qubits); + (StandardAmplitudeAmplification(1, stateOracle, 0))(qubits); ApplyToEachCA(X, flagQubit); } @@ -88,5 +88,5 @@ namespace Microsoft.Quantum.Preparation { controlled auto; adjoint controlled auto; } - + }