microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.16.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

samples/algorithms/Grover.qs

124lines · modecode

1/// # Sample
2/// Grover's Search Algorithm
3///
4/// # Description
5/// Grover's search algorithm is a quantum algorithm that finds with high
6/// probability the unique input to a black box function that produces a
7/// particular output value.
8///
9/// This Q# program implements the Grover's search algorithm.
10import Std.Convert.*;
11import Std.Math.*;
12import Std.Arrays.*;
13import Std.Measurement.*;
14import Std.Diagnostics.*;
15
16operation Main() : Result[] {
17 let nQubits = 5;
18
19 // Grover's algorithm relies on performing a "Grover iteration" an
20 // optimal number of times to maximize the probability of finding the
21 // value we are searching for.
22 // You can set the number iterations to a value lower than optimal to
23 // intentionally reduce precision.
24 let iterations = CalculateOptimalIterations(nQubits);
25 Message($"Number of iterations: {iterations}");
26
27 // Use Grover's algorithm to find a particular marked state.
28 let results = GroverSearch(nQubits, iterations, ReflectAboutMarked);
29 return results;
30}
31
32/// # Summary
33/// Implements Grover's algorithm, which searches all possible inputs to an
34/// operation to find a particular marked state.
35operation GroverSearch(
36 nQubits : Int,
37 iterations : Int,
38 phaseOracle : Qubit[] => Unit
39) : Result[] {
40
41 use qubits = Qubit[nQubits];
42
43 // Initialize a uniform superposition over all possible inputs.
44 PrepareUniform(qubits);
45
46 // The search itself consists of repeatedly reflecting about the marked
47 // state and our start state, which we can write out in Q# as a for loop.
48 for _ in 1..iterations {
49 phaseOracle(qubits);
50 ReflectAboutUniform(qubits);
51 }
52
53 // Measure and return the answer.
54 return MResetEachZ(qubits);
55}
56
57/// # Summary
58/// Returns the optimal number of Grover iterations needed to find a marked
59/// item, given the number of qubits in a register.
60function CalculateOptimalIterations(nQubits : Int) : Int {
61 if nQubits > 126 {
62 fail "This sample supports at most 126 qubits.";
63 }
64
65 let nItems = 2.0^IntAsDouble(nQubits);
66 let angle = ArcSin(1. / Sqrt(nItems));
67 let iterations = Round(0.25 * PI() / angle - 0.5);
68 iterations
69}
70
71/// # Summary
72/// Reflects about the basis state marked by alternating zeros and ones.
73/// This operation defines what input we are trying to find in the search.
74operation ReflectAboutMarked(inputQubits : Qubit[]) : Unit {
75 Message("Reflecting about marked state...");
76 use outputQubit = Qubit();
77 within {
78 // We initialize the outputQubit to (|0⟩ - |1⟩) / √2, so that
79 // toggling it results in a (-1) phase.
80 X(outputQubit);
81 H(outputQubit);
82 // Flip the outputQubit for marked states.
83 // Here, we get the state with alternating 0s and 1s by using the X
84 // operation on every other qubit.
85 for q in inputQubits[...2...] {
86 X(q);
87 }
88 } apply {
89 Controlled X(inputQubits, outputQubit);
90 }
91}
92
93/// # Summary
94/// Given a register in the all-zeros state, prepares a uniform
95/// superposition over all basis states.
96operation PrepareUniform(inputQubits : Qubit[]) : Unit is Adj + Ctl {
97 for q in inputQubits {
98 H(q);
99 }
100}
101
102/// # Summary
103/// Reflects about the all-ones state.
104operation ReflectAboutAllOnes(inputQubits : Qubit[]) : Unit {
105 Controlled Z(Most(inputQubits), Tail(inputQubits));
106}
107
108/// # Summary
109/// Reflects about the uniform superposition state.
110operation ReflectAboutUniform(inputQubits : Qubit[]) : Unit {
111 within {
112 // Transform the uniform superposition to all-zero.
113 Adjoint PrepareUniform(inputQubits);
114 // Transform the all-zero state to all-ones
115 for q in inputQubits {
116 X(q);
117 }
118 } apply {
119 // Now that we've transformed the uniform superposition to the
120 // all-ones state, reflect about the all-ones state, then let the
121 // within/apply block transform us back.
122 ReflectAboutAllOnes(inputQubits);
123 }
124}
125