From 24d88337e0ad4a9b8ba88d70c0c6f4c78af98e0c Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 26 Dec 2019 15:30:25 -0800 Subject: [PATCH 1/7] First work on Hadamard and SWAP test operations. --- .../Characterization/Distinguishability.qs | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 Standard/src/Characterization/Distinguishability.qs diff --git a/Standard/src/Characterization/Distinguishability.qs b/Standard/src/Characterization/Distinguishability.qs new file mode 100644 index 00000000000..fb3c8862f4f --- /dev/null +++ b/Standard/src/Characterization/Distinguishability.qs @@ -0,0 +1,165 @@ +namespace Microsoft.Quantum.Characterization { + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Arrays; + + + operation _ApplyHadamardTest( + phaseShift : Bool, + commonPreparation : (Qubit[] => Unit is Adj), + preparation1 : (Qubit[] => Unit is Adj + Ctl), + preparation2 : (Qubit[] => Unit is Adj + Ctl), + control : Qubit, + target : Qubit[] + ) + : Unit is Adj + { + within { + H(control); + } apply { + commonPreparation(target); + Controlled preparation1([control], target); + within { X(control); } + apply { Controlled preparation2([control], target); } + } + + (phaseShift ? S | I)(control); + } + + operation _ApplyHadamardTestOnSingleRegister( + phaseShift : Bool, + commonPreparation : (Qubit[] => Unit is Adj), + preparation1 : (Qubit[] => Unit is Adj + Ctl), + preparation2 : (Qubit[] => Unit is Adj + Ctl), + register : Qubit[] + ) + : Unit is Adj + { + let control = Head(register); + let target = Rest(register); + _ApplyHadamardTest( + phaseShift, + commonPreparation, + preparation1, preparation2, + control, target + ); + } + + /// # Summary + /// Given two operations which each prepare copies of a state, estimates + /// the real part of the overlap between the states prepared by each + /// operation. + /// + /// # Input + /// ## commonPreparation + /// An operation that prepares a fixed input state. + /// ## preparation1 + /// The first of the two state preparation operations to be compared. + /// ## preparation2 + /// The second of the two state preparation operations to be compared. + /// ## nQubits + /// The number of qubits on which `commonPreparation`, `preparation1`, and + /// `preparation2` all act. + /// ## nMeasurements + /// The number of measurements to use in estimating the overlap. + /// + /// # Remarks + /// This operation uses the Hadamard test to find the real part of + /// $$ + /// \begin{align} + /// \braket{\psi | V^{\dagger} U | \psi} + /// \end{align} + /// $$ + /// where $\ket{\psi}$ is the state prepared by `commonPreparation`, + /// $U$ is the unitary representation of the action of `preparation1`, + /// and where $V$ corresponds to `preparation2`. + /// + /// # References + /// TODO + /// + /// # See Also + /// - Microsoft.Quantum.Characterization.EstimateImagOverlapBetweenStates + /// - Microsoft.Quantum.Characterization.EstimateOverlapBetweenStates + operation EstimateRealOverlapBetweenStates( + commonPreparation : (Qubit[] => Unit is Adj), + preparation1 : (Qubit[] => Unit is Adj + Ctl), + preparation2 : (Qubit[] => Unit is Adj + Ctl), + nQubits : Int, nMeasurements : Int + ) + : Double { + return 2.0 * EstimateFrequencyA( + _ApplyHadamardTestOnSingleRegister(false, commonPreparation, preparation1, preparation2, _), + _HeadMeasurement(nQubits + 1), + nQubits + 1, nMeasurements + ) - 1.0; + } + + operation EstimateImagOverlapBetweenStates( + commonPreparation : (Qubit[] => Unit is Adj), + preparation1 : (Qubit[] => Unit is Adj + Ctl), + preparation2 : (Qubit[] => Unit is Adj + Ctl), + nQubits : Int, nMeasurements : Int + ) + : Double { + return 1.0 - EstimateFrequencyA( + _ApplyHadamardTestOnSingleRegister(true, commonPreparation, preparation1, preparation2, _), + _HeadMeasurement(nQubits + 1), + nQubits + 1, nMeasurements + ); + } + + operation _ApplySwapTest( + preparation1 : (Qubit[] => Unit is Adj), + preparation2 : (Qubit[] => Unit is Adj), + control : Qubit, + target1 : Qubit[], + target2 : Qubit[] + ) + : Unit is Adj { + within { + H(control); + } apply { + preparation1(target1); + preparation2(target2); + ApplyToEachCA(Controlled SWAP([control], _), Zip(target1, target2)); + } + } + + operation _ApplySwapTestOnSingleRegister( + preparation1 : (Qubit[] => Unit is Adj), + preparation2 : (Qubit[] => Unit is Adj), + register : Qubit[] + ) + : Unit is Adj { + let control = Head(register); + let targets = Rest(register); + _ApplySwapTest( + preparation1, preparation2, + control, + targets[...Length(targets) / 2 - 1], + targets[Length(targets) / 2...] + ); + } + + function _HeadMeasurement(nQubits : Int) : (Qubit[] => Result) { + return Measure( + ConstantArray(nQubits, PauliI) w/ 0 <- PauliZ, + _ + ); + } + + operation EstimateOverlapBetweenStates( + preparation1 : (Qubit[] => Unit is Adj), + preparation2 : (Qubit[] => Unit is Adj), + nQubits : Int, nMeasurements : Int + ) + : Double { + let nTotalQubits = 2 * nQubits + 1; + return 2.0 * EstimateFrequencyA( + _ApplySwapTestOnSingleRegister(preparation1, preparation2, _), + _HeadMeasurement(nTotalQubits), + nTotalQubits, nMeasurements + ) - 1.0; + } + +} \ No newline at end of file From ac03e25e1d4a256e2d3e2f747fa65df079dd08ed Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 26 Dec 2019 15:36:40 -0800 Subject: [PATCH 2/7] (c) header and typo fix. --- Standard/src/Characterization/Distinguishability.qs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Standard/src/Characterization/Distinguishability.qs b/Standard/src/Characterization/Distinguishability.qs index fb3c8862f4f..649f9bdbf62 100644 --- a/Standard/src/Characterization/Distinguishability.qs +++ b/Standard/src/Characterization/Distinguishability.qs @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + namespace Microsoft.Quantum.Characterization { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Canon; @@ -101,11 +104,11 @@ namespace Microsoft.Quantum.Characterization { nQubits : Int, nMeasurements : Int ) : Double { - return 1.0 - EstimateFrequencyA( + return 2.0 * EstimateFrequencyA( _ApplyHadamardTestOnSingleRegister(true, commonPreparation, preparation1, preparation2, _), _HeadMeasurement(nQubits + 1), nQubits + 1, nMeasurements - ); + ) - 1.0; } operation _ApplySwapTest( From e1f89932785da55c7c1f298a78e51bd0465c81cb Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 26 Dec 2019 16:13:20 -0800 Subject: [PATCH 3/7] Fixed typo with placement of phase shift. --- Standard/src/Characterization/Distinguishability.qs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Standard/src/Characterization/Distinguishability.qs b/Standard/src/Characterization/Distinguishability.qs index 649f9bdbf62..15fb7e5014b 100644 --- a/Standard/src/Characterization/Distinguishability.qs +++ b/Standard/src/Characterization/Distinguishability.qs @@ -24,9 +24,9 @@ namespace Microsoft.Quantum.Characterization { Controlled preparation1([control], target); within { X(control); } apply { Controlled preparation2([control], target); } - } - (phaseShift ? S | I)(control); + (phaseShift ? S | I)(control); + } } operation _ApplyHadamardTestOnSingleRegister( From 79ef526a10865ee9a6778f62199db698a2c46d4e Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 26 Dec 2019 16:41:52 -0800 Subject: [PATCH 4/7] Put public operations above private. --- .../Characterization/Distinguishability.qs | 113 +++++++++--------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/Standard/src/Characterization/Distinguishability.qs b/Standard/src/Characterization/Distinguishability.qs index 15fb7e5014b..b8df21f9afd 100644 --- a/Standard/src/Characterization/Distinguishability.qs +++ b/Standard/src/Characterization/Distinguishability.qs @@ -6,48 +6,6 @@ namespace Microsoft.Quantum.Characterization { open Microsoft.Quantum.Canon; open Microsoft.Quantum.Arrays; - - operation _ApplyHadamardTest( - phaseShift : Bool, - commonPreparation : (Qubit[] => Unit is Adj), - preparation1 : (Qubit[] => Unit is Adj + Ctl), - preparation2 : (Qubit[] => Unit is Adj + Ctl), - control : Qubit, - target : Qubit[] - ) - : Unit is Adj - { - within { - H(control); - } apply { - commonPreparation(target); - Controlled preparation1([control], target); - within { X(control); } - apply { Controlled preparation2([control], target); } - - (phaseShift ? S | I)(control); - } - } - - operation _ApplyHadamardTestOnSingleRegister( - phaseShift : Bool, - commonPreparation : (Qubit[] => Unit is Adj), - preparation1 : (Qubit[] => Unit is Adj + Ctl), - preparation2 : (Qubit[] => Unit is Adj + Ctl), - register : Qubit[] - ) - : Unit is Adj - { - let control = Head(register); - let target = Rest(register); - _ApplyHadamardTest( - phaseShift, - commonPreparation, - preparation1, preparation2, - control, target - ); - } - /// # Summary /// Given two operations which each prepare copies of a state, estimates /// the real part of the overlap between the states prepared by each @@ -111,6 +69,63 @@ namespace Microsoft.Quantum.Characterization { ) - 1.0; } + operation EstimateOverlapBetweenStates( + preparation1 : (Qubit[] => Unit is Adj), + preparation2 : (Qubit[] => Unit is Adj), + nQubits : Int, nMeasurements : Int + ) + : Double { + let nTotalQubits = 2 * nQubits + 1; + return 2.0 * EstimateFrequencyA( + _ApplySwapTestOnSingleRegister(preparation1, preparation2, _), + _HeadMeasurement(nTotalQubits), + nTotalQubits, nMeasurements + ) - 1.0; + } + + + operation _ApplyHadamardTest( + phaseShift : Bool, + commonPreparation : (Qubit[] => Unit is Adj), + preparation1 : (Qubit[] => Unit is Adj + Ctl), + preparation2 : (Qubit[] => Unit is Adj + Ctl), + control : Qubit, + target : Qubit[] + ) + : Unit is Adj + { + within { + H(control); + } apply { + commonPreparation(target); + Controlled preparation1([control], target); + within { X(control); } + apply { Controlled preparation2([control], target); } + + (phaseShift ? S | I)(control); + } + } + + operation _ApplyHadamardTestOnSingleRegister( + phaseShift : Bool, + commonPreparation : (Qubit[] => Unit is Adj), + preparation1 : (Qubit[] => Unit is Adj + Ctl), + preparation2 : (Qubit[] => Unit is Adj + Ctl), + register : Qubit[] + ) + : Unit is Adj + { + let control = Head(register); + let target = Rest(register); + _ApplyHadamardTest( + phaseShift, + commonPreparation, + preparation1, preparation2, + control, target + ); + } + + operation _ApplySwapTest( preparation1 : (Qubit[] => Unit is Adj), preparation2 : (Qubit[] => Unit is Adj), @@ -151,18 +166,4 @@ namespace Microsoft.Quantum.Characterization { ); } - operation EstimateOverlapBetweenStates( - preparation1 : (Qubit[] => Unit is Adj), - preparation2 : (Qubit[] => Unit is Adj), - nQubits : Int, nMeasurements : Int - ) - : Double { - let nTotalQubits = 2 * nQubits + 1; - return 2.0 * EstimateFrequencyA( - _ApplySwapTestOnSingleRegister(preparation1, preparation2, _), - _HeadMeasurement(nTotalQubits), - nTotalQubits, nMeasurements - ) - 1.0; - } - } \ No newline at end of file From 77e3992a0ec1ff4e7d8fc7a55f9a3b8e2bddbbfd Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 26 Dec 2019 16:41:59 -0800 Subject: [PATCH 5/7] Added tests for new operations. --- .../DistinguishabilityTests.qs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Standard/tests/Characterization/DistinguishabilityTests.qs diff --git a/Standard/tests/Characterization/DistinguishabilityTests.qs b/Standard/tests/Characterization/DistinguishabilityTests.qs new file mode 100644 index 00000000000..f9f04bb853d --- /dev/null +++ b/Standard/tests/Characterization/DistinguishabilityTests.qs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Tests { + open Microsoft.Quantum.Math; + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Characterization; + open Microsoft.Quantum.Diagnostics; + + @Test("QuantumSimulator") + operation CheckOverlapBetweenPlusAndOne() : Unit { + let prep1 = ApplyToEachCA(H, _); + let prep2 = ApplyToEachCA(X, _); + + EqualityWithinToleranceFact( + EstimateRealOverlapBetweenStates( + NoOp, prep1, prep2, 1, 1000000 + ), + 1.0 / Sqrt(2.0), + 0.02 + ); + EqualityWithinToleranceFact( + EstimateImagOverlapBetweenStates( + NoOp, prep1, prep2, 1, 1000000 + ), + 0.0, + 0.02 + ); + EqualityWithinToleranceFact( + 0.5, + EstimateOverlapBetweenStates( + prep1, prep2, 1, 1000000 + ), + 0.02 + ); + } + + @Test("QuantumSimulator") + operation CheckOverlapWithCommonPreparation() : Unit { + let common = ApplyToEachCA(H, _); + let prep1 = ApplyToEachCA(S, _); + let prep2 = ApplyToEachCA(Z, _); + + EqualityWithinToleranceFact( + EstimateRealOverlapBetweenStates( + common, prep1, prep2, 1, 1000000 + ), + 0.5, + 0.02 + ); + EqualityWithinToleranceFact( + EstimateImagOverlapBetweenStates( + common, prep1, prep2, 1, 1000000 + ), + 0.5, + 0.02 + ); + } +} From 6f0fb7cfa149a25cf8c88adfa35350366401c047 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 26 Dec 2019 16:50:37 -0800 Subject: [PATCH 6/7] Added API documentation comments. --- .../Characterization/Distinguishability.qs | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/Standard/src/Characterization/Distinguishability.qs b/Standard/src/Characterization/Distinguishability.qs index b8df21f9afd..e87624bdad4 100644 --- a/Standard/src/Characterization/Distinguishability.qs +++ b/Standard/src/Characterization/Distinguishability.qs @@ -36,7 +36,7 @@ namespace Microsoft.Quantum.Characterization { /// and where $V$ corresponds to `preparation2`. /// /// # References - /// TODO + /// - Aharonov *et al.* [quant-ph/0511096](https://arxiv.org/abs/quant-ph/0511096). /// /// # See Also /// - Microsoft.Quantum.Characterization.EstimateImagOverlapBetweenStates @@ -55,6 +55,41 @@ namespace Microsoft.Quantum.Characterization { ) - 1.0; } + /// # Summary + /// Given two operations which each prepare copies of a state, estimates + /// the imaginary part of the overlap between the states prepared by each + /// operation. + /// + /// # Input + /// ## commonPreparation + /// An operation that prepares a fixed input state. + /// ## preparation1 + /// The first of the two state preparation operations to be compared. + /// ## preparation2 + /// The second of the two state preparation operations to be compared. + /// ## nQubits + /// The number of qubits on which `commonPreparation`, `preparation1`, and + /// `preparation2` all act. + /// ## nMeasurements + /// The number of measurements to use in estimating the overlap. + /// + /// # Remarks + /// This operation uses the Hadamard test to find the imaginary part of + /// $$ + /// \begin{align} + /// \braket{\psi | V^{\dagger} U | \psi} + /// \end{align} + /// $$ + /// where $\ket{\psi}$ is the state prepared by `commonPreparation`, + /// $U$ is the unitary representation of the action of `preparation1`, + /// and where $V$ corresponds to `preparation2`. + /// + /// # References + /// - Aharonov *et al.* [quant-ph/0511096](https://arxiv.org/abs/quant-ph/0511096). + /// + /// # See Also + /// - Microsoft.Quantum.Characterization.EstimateRealOverlapBetweenStates + /// - Microsoft.Quantum.Characterization.EstimateOverlapBetweenStates operation EstimateImagOverlapBetweenStates( commonPreparation : (Qubit[] => Unit is Adj), preparation1 : (Qubit[] => Unit is Adj + Ctl), @@ -69,6 +104,36 @@ namespace Microsoft.Quantum.Characterization { ) - 1.0; } + + /// # Summary + /// Given two operations which each prepare copies of a state, estimates + /// the squared overlap between the states prepared by each + /// operation. + /// + /// # Input + /// ## preparation1 + /// The first of the two state preparation operations to be compared. + /// ## preparation2 + /// The second of the two state preparation operations to be compared. + /// ## nQubits + /// The number of qubits on which `commonPreparation`, `preparation1`, and + /// `preparation2` all act. + /// ## nMeasurements + /// The number of measurements to use in estimating the overlap. + /// + /// # Remarks + /// This operation uses the SWAP test to find + /// $$ + /// \begin{align} + /// \left| \braket{00\cdots 0 | V^{\dagger} U | 00\cdots 0} \right|^2 + /// \end{align} + /// $$ + /// where $U$ is the unitary representation of the action of `preparation1`, + /// and where $V$ corresponds to `preparation2`. + /// + /// # See Also + /// - Microsoft.Quantum.Characterization.EstimateRealOverlapBetweenStates + /// - Microsoft.Quantum.Characterization.EstimateImagOverlapBetweenStates operation EstimateOverlapBetweenStates( preparation1 : (Qubit[] => Unit is Adj), preparation2 : (Qubit[] => Unit is Adj), From 53a1206d767710c55405896b1131b051c5909ef2 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 26 Dec 2019 16:51:16 -0800 Subject: [PATCH 7/7] Newline at end of file. --- Standard/src/Characterization/Distinguishability.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Standard/src/Characterization/Distinguishability.qs b/Standard/src/Characterization/Distinguishability.qs index e87624bdad4..483cdbed803 100644 --- a/Standard/src/Characterization/Distinguishability.qs +++ b/Standard/src/Characterization/Distinguishability.qs @@ -231,4 +231,4 @@ namespace Microsoft.Quantum.Characterization { ); } -} \ No newline at end of file +}