diff --git a/Standard/src/AmplitudeAmplification/Convert.qs b/Standard/src/AmplitudeAmplification/Convert.qs index 70c5ace858c..f86be6d0585 100644 --- a/Standard/src/AmplitudeAmplification/Convert.qs +++ b/Standard/src/AmplitudeAmplification/Convert.qs @@ -31,6 +31,11 @@ namespace Microsoft.Quantum.AmplitudeAmplification { mutable phasesTarget = [0.0, size = nPhasesRef]; mutable phasesStart = [0.0, size = nPhasesRef]; + + if nPhasesRot == 1 { + return ReflectionPhases(phasesStart, phasesTarget); + } + set phasesTarget w/= 0 <- ((rotPhases!)[0] - (rotPhases!)[1]) - PI(); set phasesStart w/= 0 <- -(rotPhases!)[0] + 0.5 * PI(); diff --git a/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs b/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs index 8b92e3a013c..b2ea3633e6d 100644 --- a/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs +++ b/Standard/src/AmplitudeAmplification/StandardAlgorithms.qs @@ -2,8 +2,9 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.AmplitudeAmplification { - open Microsoft.Quantum.Convert; open Microsoft.Quantum.Arrays; + open Microsoft.Quantum.Convert; + open Microsoft.Quantum.Diagnostics; open Microsoft.Quantum.Math; /// # Summary @@ -52,13 +53,27 @@ namespace Microsoft.Quantum.AmplitudeAmplification { /// for phases in the `RotationPhases` format. function FixedPointReflectionPhases(nQueries : Int, successMin : Double) : ReflectionPhases { - let twoPi = 2.0 * PI(); + // In this implementation `nQueries` corresponds to $L$ in + // arXiv:1409.3305. + Fact(nQueries % 2 == 1, "nQueries must be odd"); + + // Initializes L rotation phases, this also initializes the first + // rotation phase with 0.0. mutable phasesRot = [0.0, size = 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); + // The success probability `successMin` is $1 - \delta^2$ in + // arXiv:1409.3305. Variable `beta` corresponds to $\gamma^{-1}$ in + // arXiv:1409.3305, right below Eq. (11) + let beta = Cosh((1.0 / nQueriesDouble) * ArcCosh(Sqrt(1.0 / (1.0 - successMin)))); + + // `alpha` is $\sqrt(1 - \gamma^2)$ in Eq. (11) in arXiv:1409.3305, + // therefore it is $\sqrt(1 - (1 / \beta^2))$ + let alpha = Sqrt(1.0 - 1.0 / (beta * beta)); + + // Iterative computation of rotation phases is described in Eq. (30) in + // arXiv:1603.03996. In there, we can set $j = 1$. + let twoPi = 2.0 * PI(); for idxPhases in 1 .. nQueries - 1 { set phasesRot w/= idxPhases <- phasesRot[idxPhases - 1] + diff --git a/Standard/tests/AmplitudeAmplificationTests.qs b/Standard/tests/AmplitudeAmplificationTests.qs index 16d6dcdc4e6..07f6ce32f6d 100644 --- a/Standard/tests/AmplitudeAmplificationTests.qs +++ b/Standard/tests/AmplitudeAmplificationTests.qs @@ -2,13 +2,15 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Tests { - open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.AmplitudeAmplification; + open Microsoft.Quantum.Arrays; open Microsoft.Quantum.Canon; open Microsoft.Quantum.Convert; open Microsoft.Quantum.Diagnostics; - open Microsoft.Quantum.AmplitudeAmplification; - open Microsoft.Quantum.Oracles; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Logical; open Microsoft.Quantum.Math; + open Microsoft.Quantum.Oracles; ///Here we consider the smallest example of amplitude amplification ///Suppose we have a single-qubit oracle that prepares the state @@ -94,6 +96,18 @@ namespace Microsoft.Quantum.Tests { } } + @Test("QuantumSimulator") + operation TestRotationPhasesAsReflectionPhases() : Unit { + let rotationPhases = RotationPhases([0.1, 0.2, 0.3, 0.4, 0.5]); + let reflectionPhases = RotationPhasesAsReflectionPhases(rotationPhases); + + EqualityFactI(Length(reflectionPhases::AboutStart), 3, "Unexpected length of reflection phases"); + EqualityFactI(Length(reflectionPhases::AboutTarget), 3, "Unexpected length of reflection phases"); + + Fact(All(NearlyEqualD, Zipped(reflectionPhases::AboutStart, [1.4707963267948965,3.041592653589793,3.041592653589793])), "Unexpected reflection phases"); + Fact(All(NearlyEqualD, Zipped(reflectionPhases::AboutTarget, [-3.241592653589793,-3.241592653589793,-1.0707963267948966])), "Unexpected reflection phases"); + } + }