0% found this document useful (0 votes)
18 views6 pages

Message

Uploaded by

tiger55024
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views6 pages

Message

Uploaded by

tiger55024
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

// pseudo classic operator to swap bit order

cond qufunct flip(qureg q) {


int i; // declare loop counter
for i=0 to #q/2-1 { // swap 2 symmetric bits
Swap(q[i],q[#q-i-1]);
}
}

// discrete Fourier transform (Coppersmith)

operator dft(qureg q) { // main operator


const n=#q; // set n to length of input
int i; int j; // declare loop counters
for i=1 to n {
for j=1 to i-1 { // apply conditional phase gates
V(pi/2^(i-j),q[n-i] & q[n-j]);
// if q[n-i] and q[n-j] { Phase(pi/2^(i-j)); }
}
H(q[n-i]); // qubit rotation
}
flip(q); // swap bit order of the output
}

int findfactor(int n) {
int i;
if n<=0 { exit "findfactor takes only positive args"; }
for i=2 to floor(sqrt(n)) {
if n mod i == 0 { return i; }
}
return 1;
}

// test if n is a prime number

boolean testprime(int n) {
int i;
if n<=1 { return false; }
if n==2 or n==3 { return true; }
if n mod 2 == 0 { return false; }
for i=3 to floor(sqrt(n)) step 2 {
if n mod i == 0 { return false; }
}
return true;
}

// test if n is a prime power

boolean testprimepower(int n) {
int i;
int f;
i=2;
while i<=floor(sqrt(n)) and f==0 {
if n mod i == 0 { f=i; }
i=i+1;
}
for i=2 to floor(log(n,f)) {
if f^i==n { return true; }
}
return false;
}

// returns x^a mod n

int powmod(int x,int a,int n) {


int u=x;
int y=1;
int i;

for i=0 to 30 {
if a/2^i mod 2 == 1 { y=y*u mod n; }
u=u^2 mod n;
}
return y;
}

// return the modular inverse to a mod n or 0 if gcd(a,n)>1

int invmod(int a,int n) {


int b=a;
int i;

if gcd(a,n)>1 { return 0; }
for i=1 to n {
if b*a mod n == 1 { return b; }
b=b*a mod n;
}
return 0;
}

// finds the denominator q of the best rational approximation p/q


// for x with q<qmax

int denominator(real x,int qmax) {


real y=x;
real z;
int q0;
int q1=1;
int q2;

while true {
z=y-floor(y);
if z<0.5/qmax^2 { return q1; }
y=1/z;
q2=floor(y)*q1+q0;
if q2>=qmax { return q1; }
q0=q1; q1=q2;
}
}

// Conditional Xor

cond qufunct cxor(quconst a,qureg b) {


int i;
for i=0 to #a-1 {
CNot(b[i],a[i]);
}
}
// Conditional multiplexed binary adder for one of 2 classical
// bits and 1 qubit.
// Full adder if #sum=2, half adder if #sum=1.

cond qufunct muxaddbit(boolean a0,boolean a1,quconst sel,quconst b,qureg sum) {


qureg s=sel; // redeclare sel as qureg
quconst e=cond; // explicit enable register

if (a0 xor a1) { // a0 and a1 differ?


if a0 { Not(s); } // write a into sect qubit
if #sum>1 { // set carry if available
CNot(sum[1],sum[0] & s & e);
}
CNot(sum[0],s & e); // add a
if a0 { Not(s); } // restore sect qubit
} else {
if a0 and a1 {
if #sum>1 { // set carry if available
CNot(sum[1],sum[0] & e);
}
CNot(sum[0],e); // add a
}
};
// Add qubit b
if #sum>1 { // set carry if available
CNot(sum[1],b & sum[0]);
}
CNot(sum[0],b); // add b
}

// conditional multiplexed binary adder for one of 2 integers


// and 1 qureg. No output carry.

cond qufunct muxadd(int a0,int a1,quconst sel,quconst b,quvoid sum) {


int i;
for i=0 to #b-2 { // fulladd first #b-1 bits
muxaddbit(bit(a0,i),bit(a1,i),sel,b[i],sum[i:i+1]);
}
// half add last bit
muxaddbit(bit(a0,#b-1),bit(a1,#b-1),sel,b[#b-1],sum[#b-1]);
}

// Comparison operator. flag is toggled if b<a.


// b gets overwritten. Needs a #b-1 qubit junk register j
// as argument which is left dirty.

qufunct lt(int a,qureg b,qureg flag,quvoid j) {


int i;
if bit(a,#b-1) { // disable further comparison
CNot(j[#b-2],b[#b-1]); // and set result flag if
Not(b[#b-1]); // MSB(a)>MSB(b)
CNot(flag,b[#b-1]);
} else {
Not(b[#b-1]); // disable further comparison
CNot(j[#b-2],b[#b-1]); // if MSB(a)<MSB(b)
}
for i=#b-2 to 1 step -1 { // continue for lower bits
if bit(a,i) { // set new junk bit if undecided
CNot(j[i-1],j[i] & b[i]);
Not(b[i]); // honor last junk bit and
CNot(flag,j[i] & b[i]); // set result flag if a[i]>b[i]
} else {
Not(b[i]);
CNot(j[i-1],j[i] & b[i]);
}
}
if bit(a,0) {
Not(b[0]); // if still undecided (j[0]=1)
CNot(flag,j[0] & b[0]); // result is LSB(a)>LSB(b)
}
}

// conditional addition mod n for 1 integer and 1 qureg


// flag is set if a+b<n for invertability

cond qufunct addn(int a,int n,quconst b,quvoid flag,quvoid sum) {


qureg s=sum[0\#b-1];
qureg f=sum[#b-1];
qureg bb=b; // "abuse" sum and b as scratch
quconst e=cond; // explicit enable register

lt(n-a,bb,f,s); // for the less-than operator


if f and e { Not(flag); } // save result of comparison
!lt(n-a,bb,f,s); // restore sum and b
if e {
muxadd(2^#b+a-n,a,flag,b,sum); // add either a or a-n
}
}

// Conditional overwriting addition mod n: sum -> (a+sum) mod n

cond qufunct oaddn(int a,int n,qureg sum) {


qureg j[#sum];
qureg f[1];
quconst e=cond; // explicit enable register

if e { addn(a,n,sum,f,j); } // junk -> a+b mod n


Swap(sum,j); // swap junk and sum
CNot(f,e); // toggle flag
if e { !addn(n-a,n,sum,f,j); } // uncompute b to zero
}

// Conditional Multiplication mod n of an integer a by the qureg b,


// prod <- ab mod n.

cond qufunct muln(int a,int n,quconst b,qureg prod) {


int i;

for i=0 to #prod-1 {


if bit(a,i) and b[0] { Not(prod[i]); }
}
for i=1 to #b-1 {
if b[i] { oaddn(2^i*a mod n,n,prod); }
}
}

// Conditional Overwriting multiplication mod n: b-> ab mod n


cond qufunct omuln(int a,int n,qureg b) {
qureg j[#b];

if gcd(a,n)>1 {
exit "omuln: a and n have to be relativly prime";
}
muln(a,n,b,j);
!muln(invmod(a,n),n,j,b);
cxor(j,b);
cxor(b,j);
}

// Modular exponentiation: b -> x^a mod n

cond qufunct expn(int a,int n,quconst b,quvoid ex) {


int i;

Not(ex[0]); // start with 1


for i=0 to #b-1 {
if b[i] {
omuln(powmod(a,2^i,n),n,ex); // ex -> ex*a^2^i mod n
}
}
}

procedure shor(int number) {


int width=ceil(log(number,2)); // size of number in bits
qureg reg1[2*width]; // first register
qureg reg2[width]; // second register
int qmax=2^width;
int factor; // found factor
int m; real c; // measured value
int x; // base of exponentiation
int p; int q; // rational approximation p/q
int a; int b; // possible factors of number
int e; // e=x^(q/2) mod number

if number mod 2 == 0 { exit "number must be odd"; }


if testprime(number) { exit "prime number"; }
if testprimepower(number) { exit "prime power"; };
{
{ // generate random base
x=floor(random()*(number-3))+2;
} until gcd(x,number)==1;
print "chosen random x =",x;
H(reg1); // Hadamard transform
expn(x,number,reg1,reg2); // modular exponentiation
measure reg2; // measure 2nd register
dft(reg1); // Fourier transform
measure reg1,m; // measure 2st register
reset; // clear local registers
if m==0 { // failed if measured 0
print "measured zero in 1st register. trying again ...";
} else {
c=m*0.5^(2*width); // fixed point form of m
q=denominator(c,qmax); // find rational approximation
p=floor(q*c+0.5);
print "measured",m,", approximation for",c,"is",p,"/",q;
if q mod 2==1 and 2*q<qmax { // odd q ? try expanding p/q
print "odd denominator, expanding by 2";
p=2*p; q=2*q;
}
if q mod 2==1 { // failed if odd q
print "odd period. trying again ...";
} else {
print "possible period is",q;
e=powmod(x,q/2,number); // calculate candidates for
a=(e+1) mod number; // possible common factors
b=(e+number-1) mod number; // with number
print x,"^",q/2,"+ 1 mod",number,"=",a,",",
x,"^",q/2,"- 1 mod",number,"=",b;
factor=max(gcd(number,a),gcd(number,b));
}
}
} until factor>1 and factor<number;
print number,"=",factor,"*",number/factor;
}

You might also like