~ubuntu-branches/ubuntu/oneiric/yacas/oneiric

« back to all changes in this revision

Viewing changes to inprogress/shor2

  • Committer: Bazaar Package Importer
  • Author(s): Gopal Narayanan
  • Date: 2002-04-23 13:50:51 UTC
  • Revision ID: james.westby@ubuntu.com-20020423135051-bbd6ov4orr8eufmw
Tags: upstream-1.0.51
ImportĀ upstreamĀ versionĀ 1.0.51

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* shor 0.1
 
3
 * This file implements the shor algorithm.
 
4
 *
 
5
 * Change log:
 
6
 * 0.1 initial version, implementation of the classical version of
 
7
 *     the factoring algorithm, and some matrix operations using
 
8
 *     the tensor package.
 
9
 */
 
10
 
 
11
 
 
12
/* A short description due to Matthew Hayward :
 
13
 
 
14
 
 
15
Steps to Shor's Algorithm 
 
16
 
 
17
Shor's algorithm for factoring a given integer n can be broken into
 
18
some simple steps. 
 
19
 
 
20
Step 1) Determine if the number n is a prime, a even number, or an
 
21
integer power of a prime number. If it is
 
22
we will not use Shor's algorithm. There are efficient classical methods
 
23
for determining if a integer n belongs
 
24
to one of the above groups, and providing factors for it if it is. This
 
25
step would be performed on a classical computer. 
 
26
 
 
27
Step 2) Pick a integer q that is the power of 2 such that "n^2 <= q < 2*n^2".
 
28
This step would be done on a classical computer. 
 
29
 
 
30
Step 3) Pick a random integer x that is coprime to n. When two numbers
 
31
are coprime it means that their greatest common divisor is 1. There
 
32
are efficient classical methods for picking such an x. This step would be
 
33
done on a classical computer. 
 
34
 
 
35
Step 4) Create a quantum register and partition it into two sets,
 
36
register 1 and register 2. Thus the state of our quantum computer can
 
37
be given by: |reg1, reg2>. Register 1 must have enough qubits to represent
 
38
integers as large as q - 1. Register 2 must have enough qubits to represent
 
39
integers as large as n - 1. The calculations for how many qubits are
 
40
needed would be done on a classical computer. 
 
41
 
 
42
Step 5) Load register 1 with an equally weighted superposition of all
 
43
integers from 0 to q - 1. Load register 2 with all zeros. This
 
44
operation would be performed by our quantum computer. The total state
 
45
of the quantum memory register at this point is: 
 
46
 
 
47
"1/Sqrt(q) Sum(a,0,q-1) |a,0>"
 
48
 
 
49
Step 6) Now apply the transformation "x^a mod n" to for each number stored in
 
50
register 1 and store the result in register 2. Due to quantum parallelism
 
51
this will take only one step, as the quantum computer will
 
52
only calculate "x^|a> mod n", where |a> is the superposition of states created in
 
53
step 5. This step is performed on the quantum computer. The state of the
 
54
quantum memory register at this point is: 
 
55
 
 
56
"1/Sqrt(q) Sum(a,0,q-1) |a,x^a mod n>"
 
57
 
 
58
Step 7) Measure the second register, and observe some value k. This has
 
59
the side effect of collapsing register one into a equal superposition of
 
60
each value a between 0 and q-1 such that 
 
61
 
 
62
"x^a mod n = k"
 
63
 
 
64
This operation is performed by the quantum computer. The state of the
 
65
quantum memory register after this step is: 
 
66
 
 
67
"1/Sqrt(||A||) Sum(a' elements of A) |a',k>"
 
68
 
 
69
Where A is the set of a's such that "x^a mod n = k", and ||A|| is the
 
70
number of elements in that set. 
 
71
 
 
72
Step 8) Now compute the discrete Fourier transform on register one. The
 
73
discrete Fourier transform when applied to a state |a>changes it in the
 
74
following manner: 
 
75
 
 
76
"|a> = 1/Sqrt(q) Sum(c=0,q-1) |c> *Exp(2*Pi*I*a*c/q)"
 
77
 
 
78
This step is performed by the quantum computer in one step through quantum
 
79
parallelism. After the discrete Fourier transform our register is in
 
80
the state: 
 
81
 
 
82
"1/Sqrt(||A||) Sum(a' element of A) 1/Sqrt(q) Sum(c=0,q-1) |c,k> *Exp(2*Pi*I*a'*c/q)"
 
83
 
 
84
Step 9) Measure the state of register one, call this value m, this integer
 
85
m has a very high probability of being a multiple of q/r, where r is the
 
86
desired period. This step is performed by the quantum computer. 
 
87
 
 
88
Step 10) Take the value m, and on a classical computer do some post
 
89
processing which calculates r based on knowledge of m and q. There
 
90
are many ways to do this post processing. This post processing is done on a
 
91
classical computer. 
 
92
 
 
93
Step 11) Once you have attained r, a factor of n can be determined by
 
94
taking "Gcd(x^(r/2)+1,n)" and "Gcd(x^(r/2)-1,n)"
 
95
. If you have found a factor of n, then stop, if not
 
96
go to step 4. This final step is done on a classical computer. 
 
97
 
 
98
Step 11 contains a provision for what to do if Shor's algorithm failed
 
99
to produce factors of n. There are a few reasons why Shor's algorithm
 
100
can fail, for example the discrete Fourier transform could be measured
 
101
to be 0 in step 9, making the post processing in step 10 impossible.
 
102
The algorithm will sometimes find factors of 1 and n, which is not
 
103
useful either. For these reasons step 11 must be able to jump back
 
104
to step four to start over. (Williams, Clearwater) 
 
105
 
 
106
 
 
107
 */
 
108
 
 
109
 
 
110
 
 
111
 
 
112
 
 
113
/* ClassicPeriod : this is the computation that the Shor
 
114
   algorithm is supposed to perform more efficiently.
 
115
   It tries to find the period of n^(p+1) mod m. That is, it
 
116
   will return the p for which n mod m = n^p mod m
 
117
   Example: ClassicPeriod(4,15) -> 2
 
118
 */
 
119
 
 
120
ClassicPeriod(n,m):=
 
121
[
 
122
  Local(i,first,period);
 
123
  i:=n;
 
124
  period:=1;
 
125
  first:=Mod(i,m);
 
126
  i:=i*n;
 
127
  While(Mod(i,m)!=first)
 
128
  [
 
129
    i:=i*n;
 
130
    period++;
 
131
  ];
 
132
  period;
 
133
];
 
134
 
 
135
/* ClassicFactors does the same as Factors, but using a period
 
136
   Example: ClassicFactors(4,15,ClassicPeriod(4,15)) -> {5,3}
 
137
 */
 
138
ClassicFactors(n,m,period):=
 
139
[
 
140
  Local(res);
 
141
  res:=Sqrt(n^period);
 
142
  {Gcd(res+1,m),Gcd(res-1,m)};
 
143
];
 
144
 
 
145
 
 
146
 
 
147
/* Rot: tensor defining a rotation in a plane spanned by two
 
148
 * arbitrary base vectors. Rot(n,m,i,j,a) gives the matrix element
 
149
 * (i,j) of a rotation matrix that rotates the space in the plane (n,m)
 
150
 * around angle a.
 
151
 */
 
152
 
 
153
5  # Rot(ii_IsInteger,_ii,jj_IsInteger,_jj,_angle) <-- 1;
 
154
6  # Rot(ii_IsInteger,_ii,jj_IsInteger,kk_IsInteger,_angle) <-- 0; 
 
155
10 # Rot(_ii,_jj,_ii,_ii,_angle) <-- Cos(angle);
 
156
10 # Rot(_ii,_jj,_ii,_jj,_angle) <-- -Sin(angle);
 
157
10 # Rot(_ii,_jj,_jj,_ii,_angle) <-- Sin(angle);
 
158
10 # Rot(_ii,_jj,_jj,_jj,_angle) <-- Cos(angle);
 
159
20 # Rot(ii_IsInteger,jj_IsInteger,kk_IsInteger,_kk,_angle)_
 
160
     (kk!= ii And kk != jj) <-- 1;
 
161
 
 
162
30 # Rot(ii_IsInteger,jj_IsInteger,kk_IsInteger,ll_IsInteger,_angle)_
 
163
  (kk != ii And kk != jj) <-- 0;
 
164
30 # Rot(ii_IsInteger,jj_IsInteger,kk_IsInteger,ll_IsInteger,_angle)_
 
165
  (ll != ii And ll != jj) <-- 0;
 
166
 
 
167
 
 
168
/* Two examples of use of Rot:
 
169
 * - f1(i,a) returns the i-th vector element
 
170
 *   after rotating a vector X in an aight-dimensional space in the
 
171
 *   plane (2,5).
 
172
 *
 
173
 * - f2(i,a1,a2) does the same, rotating over (5,3) and then (2,5)
 
174
 
 
175
  f1(i,a):=Eval(TExplicitSum(8)TSum({j})Rot(2,5,i,j,a)*X(j));
 
176
  f2(i,a1,a2):=Eval(TExplicitSum(16)TSum({j,k})Rot(2,5,i,j,a1)*Rot(5,3,j,k,a2)*X(k));
 
177
 
 
178
*/
 
179
 
 
180
/* Mir: mirror a vector. Mir(i,j,k) is the matrix that converts a vector
 
181
 * into one with the i-th component changed from X(i) to -X(i).
 
182
 */
 
183
 
 
184
5 # Mir(_ii,_ii,_ii) <-- -1;
 
185
6 # Mir(_ii,_jj,_jj) <--  1;
 
186
7 # Mir(_ii,jj_IsInteger,kk_IsInteger) <--  0;
 
187
 
 
188
/* Example, mirror the i-th component, and show the j-th component 
 
189
  f3(i,j):=Eval(TExplicitSum(8)TSum({k})Mir(i,j,k)*X(k));
 
190
 */
 
191
 
 
192
/* InsertBit inserts a bit into a number num, at position index. the
 
193
 * first bit has index 0.
 
194
 */
 
195
 
 
196
InsertBit(_index,_bit,_num) <--
 
197
[
 
198
  Local(low,high,lowmask);
 
199
  lowmask := (1<<index)-1;
 
200
  low := BitAnd(num,lowmask);
 
201
  high:= (num-low)<<1;
 
202
  BitOr(BitOr(low,high),bit*(1<<index));
 
203
];
 
204
 
 
205
/* Had is an implementation of the Hadamard gate. It rotates the bit n
 
206
 * into a superposition of states (0,1) by rotating around angle Pi/4.
 
207
 
 
208
Had(_n,_Nbits,_ii,_jj) <--
 
209
[
 
210
  Local(list,result,i1,i2,kk,in,kkk);
 
211
  result := 1;
 
212
  list:= (0 .. (2^(Nbits-1) - 1));
 
213
  kkk:=MakeVector(kk,2^(Nbits-1)-1);
 
214
  kk:=Concat({ii},kkk,{jj});
 
215
  in:=1;
 
216
  ForEach(item,list)
 
217
  [
 
218
    i1:=InsertBit(n,0,item)+1;
 
219
    i2:=InsertBit(n,1,item)+1;
 
220
    result:=result*Rot(i1,i2,kk[in],kk[in+1],Pi/4);
 
221
    in++;
 
222
  ];
 
223
  TExplicitSum(2^Nbits)(TSum(kkk)result);
 
224
];
 
225
 
 
226
/* Example: apply one Hadamard gate to a vector space on qubit 1.
 
227
  f4(i):=Eval(TExplicitSum(8)TSum({j})Had(1,3,i,j)*X(j));
 
228
 */
 
229
 
 
230
/* Applying the Hadamard gate twice: a quantum not gate on qubit 1.
 
231
  f5(i):=Eval(TExplicitSum(4)TSum({j,k})Had(1,2,i,j)*Had(1,2,j,k)*X(k));
 
232
 */
 
233
 
 
234
/* This example prepares the state in its ground state:
 
235
 * XX(1)=1 and XX(n!=1)=0.
 
236
 * Applying the Hadamard gate to all the bits. This prepares the system in
 
237
 * a state where each combination is equally probable. Try it out with f6(n),
 
238
 * which should return 1/2 for any integer (1 .. 4)
 
239
 * 
 
240
  RuleBase("XX",{i});
 
241
  f6(i):=Eval(TExplicitSum(4)TSum({j,k})Had(0,2,i,j)*Had(1,2,j,k)*XX(k));
 
242
  10 # XX(1) <-- 1;
 
243
  20 # XX(_n) <-- 0;
 
244
*/
 
245
 
 
246
 
 
247
/* CN: Controlled Not gate. If the control bit is set, the target
 
248
 * bit is inverted.
 
249
 */
 
250
CN(_target,_control,_Nbits,_ii,_jj) <--
 
251
[
 
252
  Local(list,result,i1,i2,kk,in,kkk,cntl);
 
253
  result := 1;
 
254
  list:= (0 .. (2^(Nbits-1) - 1));
 
255
  kkk:=MakeVector(kk,2^(Nbits-2)-1);
 
256
  kk:=Concat({ii},kkk,{jj});
 
257
  in:=1;
 
258
  cntl:= (1<<control);
 
259
 
 
260
  ForEach(item,list)
 
261
  [
 
262
   i1:=InsertBit(target,0,item)+1;
 
263
   i2:=InsertBit(target,1,item)+1;
 
264
    If (BitAnd(cntl,i1-1)!= 0,
 
265
    [
 
266
      result:=result*Rot(i1,i2,kk[in],kk[in+1],Pi/2);
 
267
      in++;
 
268
    ]);  
 
269
  ];
 
270
 
 
271
  TExplicitSum(2^Nbits)(TSum(kkk)result);
 
272
];
 
273
 
 
274
/* Example using CN: 3-qubit space, with bit 0 the control bit
 
275
 * and bit 1 th target bit. This f7(1)=X(1), f7(2)=-X(4), f7(3)=X(3)
 
276
 * and f7(4)=X(2)
 
277
  f7(i):=Eval(TExplicitSum(8)TSum({j})CN(1,0,3,i,j)*X(j));
 
278
*/
 
279
 
 
280
 
 
281
 
 
282
 
 
283
 
 
284
10 # ShorFactor(_M,_x)_(Mod(M , 2) = 0) <--
 
285
  [
 
286
  Echo({"Number is even. Factors found : ",M," = 2*",M>>1});
 
287
  {2,M>>1};
 
288
  ];
 
289
20 # ShorFactor(M_IsPrime,_x) <--
 
290
  [
 
291
  Echo({"Numer is prime. It cannot be factored."});
 
292
  {};
 
293
  ];
 
294
 
 
295
25 # ShorFactor(M_IsPrimePower,_x) <--
 
296
  [
 
297
  Echo({M," is a prime power (not handled yet)."});
 
298
  {M,1};
 
299
  ];
 
300
 
 
301
30 # ShorFactor(_M,_x)_
 
302
([
 
303
  Local(factor);
 
304
  factor := MathGcd(M,x);
 
305
  factor != 1 And factor != M;
 
306
]) <--
 
307
    [
 
308
     Local(factor);
 
309
    factor := MathGcd(M,x);
 
310
    Echo({"Factor found since GCD(",M,",",x,")=",factor});
 
311
    {factor,M/factor};
 
312
    ];
 
313
40 # ShorFactor(_M,_x) <--
 
314
[
 
315
  Local(q,inbits,outbits);
 
316
  q:= (1<<CountBits(M^2));
 
317
  inbits:=CountBits(q-1);
 
318
  outbits:=CountBits(M-1);
 
319
 
 
320
/*
 
321
  shorinitstate(i):=Eval(InState(inbits,i));
 
322
 
 
323
  shormodexpstate(i):=Eval(ModExpState(inbits,i,x,M));
 
324
  nr:= (1<<(inbits+outbits));
 
325
  For(i:=1,i<=nr,i++)
 
326
  [
 
327
    If(shormodexpstate(i) != 0, ShowModExp(inbits,i,x,M));
 
328
  ];
 
329
*/
 
330
 
 
331
  /* TODO old way of calculating */
 
332
  ClassicFactors(x,M,ClassicPeriod(x,M));
 
333
];
 
334
 
 
335
 
 
336
10 # InState(_inbits,i_IsInteger)_((i>>inbits) = 0) <-- 1/Sqrt(1<<inbits);
 
337
20 # InState(_inbits,i_IsInteger)                   <-- 0;
 
338
 
 
339
 
 
340
ModExpState(_inbits,i_IsInteger,_x,_M) <--
 
341
[
 
342
  Local(in,out);
 
343
  i--;
 
344
  in := BitAnd(i,(1<<inbits)-1);
 
345
  out:= (i-in)>>inbits;
 
346
/* Echo({out,aMod(x^in,M)}); */
 
347
  If(out = Mod(x^in,M), 1/Sqrt(1<<inbits), 0);
 
348
];
 
349
 
 
350
ShowModExp(_inbits,i_IsInteger,_x,_M) <--
 
351
[
 
352
  Local(in,out);
 
353
  i--;
 
354
  in := BitAnd(i,(1<<inbits)-1);
 
355
  out:= (i-in)>>inbits;
 
356
  Echo({in,out});
 
357
];
 
358
 
 
359
 
 
360