To use QDD, add the following header to your program :
#include "qdd.h"And hack up the following Makefile :
# --- Location of QDD/BDD package installation QDDLOC = .. # --- Location of QDD/BDD library LIBDIR = $(QDDLOC)/lib # --- Location of QDD/BDD package header INCDIR = $(QDDLOC)/include # --- Linker flags for use with QDD (order and location *is* important) QDDFLAGS = -lqdd -lbdd -lm -lg++ # --- Compiler flags CFLAGS = -g -O3 -Wall # --- Your C++ compiler CPP = g++ all: shornuf shornuf: shornuf.o $(CPP) shornuf.o -L$(LIBDIR) $(QDDFLAGS) -o shornuf shornuf.o: shornuf.cc $(CPP) $(CFLAGS) -c shornuf.cc -I$(INCDIR) -o shornuf.o
void muxaddbit (int a0, int a1, QuantumBit & sel, QuantumBit & b, QuantumBit & ci_sum, QuantumBit & co, QuantumBit & e, int dir) { // Note that the arguments here are object references. // We don't allow QuantumBits/Registers to be copied at all. // This helps guarantee quantum consitency in the model. // We have to cheat to implement reversible operations :( if (dir > 0) { // Allocate a single quantum bit M with an initial value of 0. QuantumBit M(0); // The C++ "^=" operator has been overloaded to be the quantum XOR // operator. The C++ infix "&" allows accumulation of conditions for // use in the quantum XOR. In the following line, if the classical // control signal a1 equals 1, then we will conditionally invert the // quantum bit M in the quantum state where the quantum bits // e and sel are true. if (a1) M ^= e & sel; // Conditionally invert M if a0=1 when e is true and sel is false. if (a0) M ^= e & (! sel); // .. etc ci_sum ^= e & M; ci_sum ^= e & b; co ^= e & M & (! ci_sum); co ^= e & (! M) & b & (! ci_sum); co ^= e & M & b & ci_sum ; // Undo the operations performed on M if (a0) M ^= e & (! sel); if (a1) M ^= e & sel; // By the time we get here, M should be in a pure state .. // in fact, it should be in its original (false) state. // (which I could/should have tested for, I guess :) try { M.unMixed(); } catch (QuantumException e) { // This is really a violation of quantum computing rules .. You cannot // "tell" if a bit is in a pure state. Nonetheless, such tests are // considered necessary during software development .. at least // it helped me :) cerr << "muxaddbit() : Mixed Bits\n" ; throw e; } // At this point, C++ helps us do quantum garbage collection (automagically) // Since M is in a pure state, we can reuse it later } else { // The reverse operation. QuantumBit M(0); if (a1) M ^= e & sel; if (a0) M ^= e & (! sel); co ^= e & M & b & ci_sum ; co ^= e & (! M) & b & (! ci_sum); co ^= e & M & (! ci_sum); ci_sum ^= e & b; ci_sum ^= e & M; if (a0) M ^= e & (! sel); if (a1) M ^= e & sel; try { M.unMixed(); } catch (QuantumException e) { cerr << "muxaddbit(-1) : Mixed Bits\n" ; throw e; } } }
Integer shornuf(Integer Number) { // We use g++ BIGNUM Integers to make life easier when factoring really big numbers. Integer Factor; Integer f1,f2; Integer A; Integer Cv; Integer Xv; int size = ilog2(Number); cout << "Bits : " << size << "\n"; // Here we allocate a quantum register with size bits. QuantumRegister F(size); Integer Fv; QuantumRegister X(size); Integer Pv; int attempt = 1; int found = 0; while ((attempt < 8) && (! found)) { cout << "Attempt # " << attempt << "\n" ; do { A = (rand(size) % Number) | 3 ; } while (gcd(Number,A) != 1) ; cout << "Random A : " << A << "\n"; // Here we set the value of the X register to all zeros. X.Set(0); // We then perform an X.Mix() to place the register in a superposition of states. X.Mix(); F.Set(0); // Perform Quantum Exponentiation (Wow!) expn(A,Number,X,F, 1); // F = a^X mod n // Perform a classical sampling of F. This collapses the entire quantum // state so that it is consistant with the value measured in F. Fv = F.Sample(); // Measure the period of X. Unfortunately, a bit of a quantum cheat. Pv = X.Period(); f1 = gcd((powmod(A,Pv/2,Number) + 1) % Number , Number) ; f2 = gcd((powmod(A,Pv/2,Number) + Number - 1) % Number , Number) ; Xv = X.Sample(); Cv = powmod(A,Xv,Number); assert(Cv == Fv, "Mismatch"); f1 = gcd(Number,f1); f2 = gcd(Number,f2); Factor = (f1 > f2 ? f1 : f2); found = (Factor > 1) && (Factor < Number); attempt++; } return(Factor); }