-
Notifications
You must be signed in to change notification settings - Fork 0
/
quantum.qs
154 lines (140 loc) · 4.7 KB
/
quantum.qs
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
namespace Microsoft.Samples
{
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Arithmetic;
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Arrays;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Math;
/// This peration copies a classical number into a Qubit using LittleEndian notation.
/// The binary value of the classical number and the Qubit array need to have
/// the same length l.
/// The initial state of all Qubits is supposed to be |0>.
operation QuantumCopy(register: Qubit[], number : Int, length: Int) : Unit
{
body {
mutable exponent = number;
for(i in 0 .. (length-1)){
if(exponent%2!=0){
X(register[i]);
}
set exponent = exponent/2;
}
}
}
operation MeasureRegister(register : Qubit[], length : Int) : (Int)
{
body{
mutable result = 0;
for(i in 0 .. (length - 1)){
let m = (M(register[length-1-i]) == Zero ? 0 | 1);
set result = result + Floor(PowD(2.0,IntAsDouble(i))) * m;
}
return result;
}
}
operation ModularExponentiation
( module : Int,
base: Int,
exponent : Qubit[],
length : Int,
target : Qubit[]) : Unit{
body{
///set the target to 1 in Little Endian notation
X(target[0]);
/// using the MultiplyByModularInteger operation to implements the modular Exponentiation.
for( i in 0 .. (length-1)){
let multiplier = Floor(PowD(IntAsDouble(base), PowD(2.0,IntAsDouble(i))))%module;
(Controlled MultiplyByModularInteger) ([exponent[i]], (multiplier, module, LittleEndian(target)));
}
}
}
operation ModularMultiplication(a : Qubit[], b : Qubit[], result : Qubit[], length : Int, module :Int) : Unit
{
body{
for (i in 0 .. length - 1){
let k = Floor(PowD(2.0,IntAsDouble(i)));
for ( j in 0 .. k - 1){
(Controlled MultiplyAndAddByModularInteger) ([a[i]], (1, module, LittleEndian(b), LittleEndian(result)));
}
}
}
}
operation multiHGate(target : Qubit[], length : Int) : Unit
{
body{
for (i in 0 .. (length - 1)){
H(target[i]);
}
}
}
/// prime = number of elements in G
/// a, b = random numbers
/// l = length of the registers
/// x = target value
/// g = generator of G
operation Shor(prime : Int, a : Int, b : Int, l : Int, x : Int, g : Int) : (Int, Int)
{
using (target = Qubit[l*5]){
let temp = Partitioned([l,l,l,l,l], target);
/// The classical number a is copied in the Qubit register quantum-1 and put in superposition
QuantumCopy(temp[0], a, l);
let quantum_a = temp[0];
multiHGate(quantum_a, l);
let quantum_ga = temp[1];
Message("a");
/// calculate g^a in quantum_2
ModularExponentiation(prime, g, quantum_a, l, quantum_ga);
Message("g^a");
/// The classical number b is copied in the Qubit register quantum-3 and put in superposition
QuantumCopy(temp[2], b, l);
let quantum_b = temp[2];
multiHGate(quantum_b, l);
Message("b");
let quantum_xb = temp[3];
/// calculate x^b in quantum_4
ModularExponentiation(prime, g, quantum_b, l, quantum_xb);
Message("x^b");
///calculate g^a*x-b in quantum_5
let quantum_gaxb = temp[4];
ModularMultiplication (quantum_ga, quantum_xb, quantum_gaxb, l, prime);
Message("g^a*x^b");
/// QTF over the basic 2 register
ApproximateQFT(1,LittleEndianAsBigEndian(LittleEndian(quantum_a)));
ApproximateQFT(1,LittleEndianAsBigEndian(LittleEndian(quantum_b)));
Message("QTF");
/// Measure the basic 2 register
let c = MeasureRegister(quantum_a, l);
let d = MeasureRegister(quantum_b, l);
return (c,d);
}
}
}
/// /// The classical number a is copied in the Qubit register quantum-1 and put in superposition
/// QuantumCopy(temp[0], a, l);
/// let quantum_1 = temp[0]
/// multiHGate(quantum_1, l);
/// let quantum_2 = temp[1];
/// /// calculate g^a in quantum_2
/// ModularExponentiation(prime, g, quantum_1, l, quantum_2);
///
/// /// The classical number b is copied in the Qubit register quantum-3 and put in superposition
/// QuantumCopy(temp[2], b, l);
/// let quantum_3 = temp[2]
/// multiHGate(quantum_3, l);
/// let quantum_4 = temp[3];
/// /// calculate x^b in quantum_4
/// ModularExponentiation(prime, g, quantum_3, l, quantum_4);
///
/// ///calculate g^a*x-b in quantum_5
/// DivideI (quantum_2, quantum_4, quantum_5);
/// quantum_5 = temp[3];
///
/// /// QTF over the first 2 register
/// ApplyQuantumFourierTransform (quantum_1);
/// ApplyQuantumFourierTransform (quantum_2);
///
/// /// Measure the first 2 register
/// let c = Measure(quantum_1);
/// let d = Measure(quantum_2)
///