microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/even-newer-stdlib

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

samples/algorithms/DotProductViaPhaseEstimation.qs

165lines · modecode

1// MIT License
2
3// Copyright (c) 2023 KPMG Australia
4
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21// SOFTWARE.
22
23namespace IterativePhaseEstimation {
24 open Microsoft.Quantum.Math;
25 open Microsoft.Quantum.Convert;
26
27 @EntryPoint()
28 operation Main() : (Int, Int) {
29 // The angles for inner product. Inner product is meeasured for vectors
30 // (cos(Θ₁/2), sin(Θ₁/2)) and (cos(Θ₂/2), sin(Θ₂/2)).
31 let theta1 = PI() / 7.0;
32 let theta2 = PI() / 5.0;
33 // Number of iterations
34 let n = 4;
35 // Perform measurements
36 Message("Computing inner product of vectors (cos(Θ₁/2), sin(Θ₁/2))⋅(cos(Θ₂/2), sin(Θ₂/2)) ≈ -cos(x𝝅/2ⁿ)");
37 let result = PerformMeasurements(theta1, theta2, n);
38 // Return result
39 return (result, n);
40 }
41
42 @Config(Adaptive)
43 @Config(not HigherLevelConstructs)
44 @Config(not FloatingPointComputations)
45 operation PerformMeasurements(theta1 : Double, theta2 : Double, n : Int) : Int {
46 let measurementCount = n + 1;
47 return QuantumInnerProduct(theta1, theta2, measurementCount);
48 }
49
50 @Config(HigherLevelConstructs)
51 @Config(FloatingPointComputations)
52 operation PerformMeasurements(theta1 : Double, theta2 : Double, n : Int) : Int {
53 Message($"Θ₁={theta1}, Θ₂={theta2}.");
54
55 // First compute quantum approximation
56 let measurementCount = n + 1;
57 let x = QuantumInnerProduct(theta1, theta2, measurementCount);
58 let angle = PI() * IntAsDouble(x) / IntAsDouble(2^n);
59 let computedInnerProduct = -Cos(angle);
60 Message($"x = {x}, n = {n}.");
61
62 // Now compute true inner product
63 let trueInnterProduct = ClassicalInnerProduct(theta1, theta2);
64
65 Message($"Computed value = {computedInnerProduct}, true value = {trueInnterProduct}");
66
67 return x;
68 }
69
70 function ClassicalInnerProduct(theta1 : Double, theta2 : Double) : Double {
71 return Cos(theta1 / 2.0) * Cos(theta2 / 2.0) + Sin(theta1 / 2.0) * Sin(theta2 / 2.0);
72 }
73
74 operation QuantumInnerProduct(theta1 : Double, theta2 : Double, iterationCount : Int) : Int {
75 //Create target register
76 use TargetReg = Qubit();
77 //Create ancilla register
78 use AncilReg = Qubit();
79 //Run iterative phase estimation
80 let Results = IterativePhaseEstimation(TargetReg, AncilReg, theta1, theta2, iterationCount);
81 Reset(TargetReg);
82 Reset(AncilReg);
83 return Results;
84 }
85
86 operation IterativePhaseEstimation(
87 TargetReg : Qubit,
88 AncilReg : Qubit,
89 theta1 : Double,
90 theta2 : Double,
91 Measurements : Int
92 ) : Int {
93
94 use ControlReg = Qubit();
95 mutable MeasureControlReg = [Zero, size = Measurements];
96 mutable bitValue = 0;
97 //Apply to initialise state, this is defined by the angles theta1 and theta2
98 StateInitialisation(TargetReg, AncilReg, theta1, theta2);
99 for index in 0..Measurements - 1 {
100 H(ControlReg);
101 //Don't apply rotation on first set of oracles
102 if index > 0 {
103 //Loop through previous results
104 for index2 in 0..index - 1 {
105 if MeasureControlReg[Measurements - 1 - index2] == One {
106 //Rotate control qubit dependent on previous measurements and number of measurements
107 let angle = -IntAsDouble(2^(index2)) * PI() / (2.0^IntAsDouble(index));
108 R(PauliZ, angle, ControlReg);
109 }
110 }
111
112 }
113 let powerIndex = (1 <<< (Measurements - 1 - index));
114 //Apply a number of oracles equal to 2^index, where index is the number or measurements left
115 for _ in 1..powerIndex {
116 Controlled GOracle([ControlReg], (TargetReg, AncilReg, theta1, theta2));
117 }
118 H(ControlReg);
119 //Make a measurement mid circuit
120 set MeasureControlReg w/= (Measurements - 1 - index) <- MResetZ(ControlReg);
121 if MeasureControlReg[Measurements - 1 - index] == One {
122 //Assign bitValue based on previous measurement
123 set bitValue += 2^(index);
124 }
125 }
126 return bitValue;
127 }
128
129 /// # Summary
130 /// This is state preperation operator A for encoding the 2D vector (page 7)
131 operation StateInitialisation(
132 TargetReg : Qubit,
133 AncilReg : Qubit,
134 theta1 : Double,
135 theta2 : Double
136 ) : Unit is Adj + Ctl {
137
138 H(AncilReg);
139 // Arbitrary controlled rotation based on theta. This is vector v.
140 Controlled R([AncilReg], (PauliY, theta1, TargetReg));
141 // X gate on ancilla to change from |+〉 to |-〉.
142 X(AncilReg);
143 // Arbitrary controlled rotation based on theta. This is vector c.
144 Controlled R([AncilReg], (PauliY, theta2, TargetReg));
145 X(AncilReg);
146 H(AncilReg);
147 }
148
149 operation GOracle(
150 TargetReg : Qubit,
151 AncilReg : Qubit,
152 theta1 : Double,
153 theta2 : Double
154 ) : Unit is Adj + Ctl {
155
156 Z(AncilReg);
157 within {
158 Adjoint StateInitialisation(TargetReg, AncilReg, theta1, theta2);
159 X(AncilReg);
160 X(TargetReg);
161 } apply {
162 Controlled Z([AncilReg], TargetReg);
163 }
164 }
165}
166