microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/second-api-refactor

Branches

Tags

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

Clone

HTTPS

Download ZIP

samples/algorithms/Grover.qs

127lines · 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
41 ) : Result[] {
42
43 use qubits = Qubit[nQubits];
44
45 // Initialize a uniform superposition over all possible inputs.
46 PrepareUniform(qubits);
47
48 // The search itself consists of repeatedly reflecting about the marked
49 // state and our start state, which we can write out in Q# as a for loop.
50 for _ in 1..iterations {
51 phaseOracle(qubits);
52 ReflectAboutUniform(qubits);
53 }
54
55 // Measure and return the answer.
56 return MResetEachZ(qubits);
57 }
58
59 /// # Summary
60 /// Returns the optimal number of Grover iterations needed to find a marked
61 /// item, given the number of qubits in a register.
62 function CalculateOptimalIterations(nQubits : Int) : Int {
63 if nQubits > 126 {
64 fail "This sample supports at most 126 qubits.";
65 }
66
67 let nItems = 2.0^IntAsDouble(nQubits);
68 let angle = ArcSin(1. / Sqrt(nItems));
69 let iterations = Round(0.25 * PI() / angle - 0.5);
70 iterations
71 }
72
73 /// # Summary
74 /// Reflects about the basis state marked by alternating zeros and ones.
75 /// This operation defines what input we are trying to find in the search.
76 operation ReflectAboutMarked(inputQubits : Qubit[]) : Unit {
77 Message("Reflecting about marked state...");
78 use outputQubit = Qubit();
79 within {
80 // We initialize the outputQubit to (|0⟩ - |1⟩) / √2, so that
81 // toggling it results in a (-1) phase.
82 X(outputQubit);
83 H(outputQubit);
84 // Flip the outputQubit for marked states.
85 // Here, we get the state with alternating 0s and 1s by using the X
86 // operation on every other qubit.
87 for q in inputQubits[...2...] {
88 X(q);
89 }
90 } apply {
91 Controlled X(inputQubits, outputQubit);
92 }
93 }
94
95 /// # Summary
96 /// Given a register in the all-zeros state, prepares a uniform
97 /// superposition over all basis states.
98 operation PrepareUniform(inputQubits : Qubit[]) : Unit is Adj + Ctl {
99 for q in inputQubits {
100 H(q);
101 }
102 }
103
104 /// # Summary
105 /// Reflects about the all-ones state.
106 operation ReflectAboutAllOnes(inputQubits : Qubit[]) : Unit {
107 Controlled Z(Most(inputQubits), Tail(inputQubits));
108 }
109
110 /// # Summary
111 /// Reflects about the uniform superposition state.
112 operation ReflectAboutUniform(inputQubits : Qubit[]) : Unit {
113 within {
114 // Transform the uniform superposition to all-zero.
115 Adjoint PrepareUniform(inputQubits);
116 // Transform the all-zero state to all-ones
117 for q in inputQubits {
118 X(q);
119 }
120 } apply {
121 // Now that we've transformed the uniform superposition to the
122 // all-ones state, reflect about the all-ones state, then let the
123 // within/apply block transform us back.
124 ReflectAboutAllOnes(inputQubits);
125 }
126 }
127}
128