microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
2c6775258236f295b242bb2f7467fe4e2e8e52f8

Branches

Tags

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

Clone

HTTPS

Download ZIP

samples/Grover.qs

135lines · modecode

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