forked from microsoft/QuantumKatas
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReferenceImplementation.qs
More file actions
135 lines (96 loc) · 3.79 KB
/
ReferenceImplementation.qs
File metadata and controls
135 lines (96 loc) · 3.79 KB
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
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
//////////////////////////////////////////////////////////////////////
// This file contains reference solutions to all tasks.
// The tasks themselves can be found in Tasks.qs file.
// We recommend that you try to solve the tasks yourself first,
// but feel free to look up the solution if you get stuck.
//////////////////////////////////////////////////////////////////////
namespace Quantum.Kata.SimonsAlgorithm {
open Microsoft.Quantum.Primitive;
open Microsoft.Quantum.Canon;
//////////////////////////////////////////////////////////////////
// Part I. Oracles
//////////////////////////////////////////////////////////////////
// Task 1.1. f(x) = x₀ ⊕ ... ⊕ xₙ₋₁ (parity of the number of bits set to 1)
operation Oracle_CountBits_Reference (x : Qubit[], y : Qubit) : Unit {
body (...) {
let N = Length(x);
for (i in 0 .. N - 1) {
CNOT(x[i], y);
}
}
adjoint invert;
}
// Task 1.2. Bitwise right shift
operation Oracle_BitwiseRightShift_Reference (x : Qubit[], y : Qubit[]) : Unit {
body (...) {
let N = Length(x);
for (i in 1 .. N - 1) {
CNOT(x[i - 1], y[i]);
}
}
adjoint invert;
}
// Task 1.3. Linear operator
operation Oracle_OperatorOutput_Reference (x : Qubit[], y : Qubit, A : Int[]) : Unit {
body (...) {
let N = Length(x);
for (i in 0 .. N - 1) {
if (A[i] == 1) {
CNOT(x[i], y);
}
}
}
adjoint invert;
}
// Task 1.4. Multidimensional linear operator
operation Oracle_MultidimensionalOperatorOutput_Reference (x : Qubit[], y : Qubit[], A : Int[][]) : Unit {
body (...) {
let N1 = Length(y);
let N2 = Length(x);
for (i in 0 .. N1 - 1) {
for (j in 0 .. N2 - 1) {
if ((A[i])[j] == 1) {
CNOT(x[j], y[i]);
}
}
}
}
adjoint invert;
}
//////////////////////////////////////////////////////////////////
// Part II. Simon's Algorithm
//////////////////////////////////////////////////////////////////
// Task 2.1. State preparation for Simon's algorithm
operation SA_StatePrep_Reference (query : Qubit[]) : Unit {
body (...) {
ApplyToEachA(H, query);
}
adjoint invert;
}
// Task 2.2. Quantum part of Simon's algorithm
operation Simon_Algorithm_Reference (N : Int, Uf : ((Qubit[], Qubit[]) => Unit)) : Int[] {
mutable j = new Int[N];
// allocate input and answer registers with N qubits each
using ((x, y) = (Qubit[N], Qubit[N])) {
// prepare qubits in the right state
SA_StatePrep_Reference(x);
// apply oracle
Uf(x, y);
// apply Hadamard to each qubit of the input register
ApplyToEach(H, x);
// measure all qubits of the input register;
// the result of each measurement is converted to an Int
for (i in 0 .. N - 1) {
if (M(x[i]) == One) {
set j[i] = 1;
}
}
// before releasing the qubits make sure they are all in |0⟩ states
ResetAll(x);
ResetAll(y);
}
return j;
}
}