forked from microsoft/Quantum
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
241 lines (176 loc) · 9.7 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Math;
namespace Microsoft.Quantum.Samples.DatabaseSearch
{
class Program
{
public static void Pause()
{
System.Console.WriteLine("\n\nPress any key to continue...\n\n");
System.Console.ReadKey();
}
static void Main(string[] args)
{
#region Setup
// We begin by defining a quantum simulator to be our target
// machine.
var sim = new QuantumSimulator(throwOnReleasingQubitsNotInZeroState: true);
#endregion
#region Random Database Search with Manual Oracle Definitions
// Let us investigate the success probability of classical random search.
// This corresponds to the case where we only prepare the start state, and
// do not perform any Grover iterates to amplify the marked subspace.
var nIterations = 0;
// We now define the size `N` = 2^n of the database to searched in terms of
// number of qubits `n`.
var nDatabaseQubits = 3;
var databaseSize = Pow(2.0, nDatabaseQubits);
// We now execute the classical random search and verify that the success
// probability matches the classical result of 1/N. Let us repeat 100
// times to collect enough statistics.
var classicalSuccessProbability = 1.0 / databaseSize;
var repeats = 1000;
var successCount = 0;
Console.Write(
$"Classical random search for marked element in database.\n" +
$" Database size: {databaseSize}.\n" +
$" Success probability: {classicalSuccessProbability}\n\n");
foreach (var idxAttempt in Enumerable.Range(0, repeats))
{
// Each operation has a static method called Run which takes a simulator as
// an argument, along with all the arguments defined by the operation itself.
var task = ApplyQuantumSearch.Run(sim, nIterations, nDatabaseQubits);
// We extract the return value of the operation by getting the Results property.
var data = task.Result;
// Extract the marked qubit state
var markedQubit = data.Item1;
var databaseRegister = data.Item2.ToArray();
successCount += markedQubit == Result.One ? 1 : 0;
// Print the results of the search every 100 attempts
if ((idxAttempt + 1) % 100 == 0)
{
Console.Write(
$"Attempt {idxAttempt}. " +
$"Success: {markedQubit}, " +
$"Probability: {Round((double)successCount / ((double)idxAttempt + 1),3)} " +
$"Found database index {string.Join(", ", databaseRegister.Select(x => x.ToString()).ToArray())} \n");
}
}
Pause();
#endregion
#region Quantum Database Search with Manual Oracle Definitions
// Let us investigate the success probability of the quantum search.
// We define the size `N` = 2^n of the database to searched in terms of
// number of qubits `n`.
nDatabaseQubits = 6;
databaseSize = Pow(2.0, nDatabaseQubits);
// We now perform Grover iterates to amplify the marked subspace.
nIterations = 3;
// Number of queries to database oracle.
var queries = nIterations * 2 + 1;
// We now execute the quantum search and verify that the success
// probability matches the theoretical prediction.
classicalSuccessProbability = 1.0 / databaseSize;
var quantumSuccessProbability = Pow(Sin((2.0 * (double)nIterations + 1.0) * Asin(1.0 / Sqrt(databaseSize))),2.0);
repeats = 100;
successCount = 0;
Console.Write(
$"\n\nQuantum search for marked element in database.\n" +
$" Database size: {databaseSize}.\n" +
$" Classical success probability: {classicalSuccessProbability}\n" +
$" Queries per search: {queries} \n" +
$" Quantum success probability: {quantumSuccessProbability}\n\n");
foreach (var idxAttempt in Enumerable.Range(0, repeats))
{
// Each operation has a static method called Run which takes a simulator as
// an argument, along with all the arguments defined by the operation itself.
var task = ApplyQuantumSearch.Run(sim, nIterations, nDatabaseQubits);
// We extract the return value of the operation by getting the Results property.
var data = task.Result;
// Extract the marked qubit state
var markedQubit = data.Item1;
var databaseRegister = data.Item2.ToArray();
successCount += markedQubit == Result.One ? 1 : 0;
// Print the results of the search every 10 attempts
if ((idxAttempt + 1) % 10 == 0)
{
var empiricalSuccessProbability = Round((double)successCount / ((double)idxAttempt + 1), 3);
// This is how much faster the quantum algorithm performs on average
// over the classical search.
var speedupFactor = Round(empiricalSuccessProbability / classicalSuccessProbability / (double)queries, 3);
Console.Write(
$"Attempt {idxAttempt}. " +
$"Success: {markedQubit}, " +
$"Probability: {empiricalSuccessProbability} " +
$"Speedup: {speedupFactor} " +
$"Found database index {string.Join(", ", databaseRegister.Select(x => x.ToString()).ToArray())} \n");
}
}
Pause();
#endregion
#region Multiple Element Quantum Database Search with the Canon
// Let us investigate the success probability of the quantum search with multiple
// marked elements.
// We define the size `N` = 2^n of the database to searched in terms of
// number of qubits `n`.
nDatabaseQubits = 8;
databaseSize = Pow(2.0, nDatabaseQubits);
// We define the marked elements. These must be smaller than `databaseSize`.
var markedElements = new long[] { 0, 39, 101, 234 };
var nMarkedElements = markedElements.Length;
// We now perform Grover iterates to amplify the marked subspace.
nIterations = 3;
// Number of queries to database oracle.
queries = nIterations * 2 + 1;
// We now execute the quantum search and verify that the success
// probability matches the theoretical prediction.
classicalSuccessProbability = (double)(nMarkedElements) / databaseSize;
quantumSuccessProbability = Pow(Sin((2.0 * (double)nIterations + 1.0) * Asin(Sqrt(nMarkedElements) / Sqrt(databaseSize))), 2.0);
repeats = 10;
successCount = 0;
Console.Write(
$"\n\nQuantum search for marked element in database.\n" +
$" Database size: {databaseSize}.\n" +
$" Marked elements: {string.Join(",", markedElements.Select(x => x.ToString()).ToArray())}" +
$" Classical success probability: {classicalSuccessProbability}\n" +
$" Queries per search: {queries} \n" +
$" Quantum success probability: {quantumSuccessProbability}\n\n");
foreach (var idxAttempt in Enumerable.Range(0, repeats))
{
// Each operation has a static method called Run which takes a simulator as
// an argument, along with all the arguments defined by the operation itself.
var task = ApplyGroverSearch.Run(sim, new QArray<long>(markedElements), nIterations, nDatabaseQubits);
// We extract the return value of the operation by getting the Results property.
var data = task.Result;
// Extract the marked qubit state
var markedQubit = data.Item1;
var databaseRegister = data.Item2;
successCount += markedQubit == Result.One ? 1 : 0;
// Print the results of the search every 1 attempt
if ((idxAttempt + 1) % 1 == 0)
{
var empiricalSuccessProbability = Round((double)successCount / ((double)idxAttempt + 1), 3);
// This is how much faster the quantum algorithm performs on average
// over the classical search.
var speedupFactor = Round(empiricalSuccessProbability / classicalSuccessProbability / (double)queries, 3);
Console.Write(
$"Attempt {idxAttempt}. " +
$"Success: {markedQubit}, " +
$"Probability: {empiricalSuccessProbability} " +
$"Speedup: {speedupFactor} " +
$"Found database index {databaseRegister} \n");
}
}
Pause();
#endregion
}
}
}