microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.0.10-rc

Branches

Tags

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

Clone

HTTPS

Download ZIP

samples/algorithms/Grover.qs

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