next up previous contents
Next: shor.C Up: Code for my Simulation Previous: complex.C   Contents

qureg.C

#include <iostream.h>
#include <math.h>
#include <time.h>

class QuReg {
public:
  //Default constructor.  Size is the size in bits of our register.
  //In our implementation of Shor's algorithm we will need size bits
  //to represent our value for "q" which is a number we have chosen
  //with small prime factors which is between 2n^2 and 3n^2 inclusive
  //where n is the number we are trying to factor.  We envision our the
  //description of our register of size "S" as 2^S complex number,
  //representing the probability of finding the register on one of or
  //2^S base states.  Thus we use an array of size 2^S, of Complex
  //numbers.  Thus if the size of our register is 3 bits array[7] is
  //the probability amplitude of the state |1,1,1>, and array[7] *
  //Complex Conjugate(array[7]) = probability of choosing that state.
  //We use normalised state vectors thought the simulation, thus the
  //sum of all possible states times their complex conjugates is = 1.
  QuReg(int size); 

  QuReg(); //Default Constructor

  QuReg(const QuReg &); //Copy constructor

  ~QuReg(); //Default destructor.
  
  int DecMeasure(); //Measures our quantum register, and returns the
  //decimal interpretation of the bitstring measured.  
  
  //Dumps all the information about the quantum register.  This has no
  //physical reality, it is only there for debugging.  When verbose !=
  //0 we return every value, when verbose = 0 we return only
  //probability amplitudes which differ from 0.
  void Dump(int verbose);

  //Sets state of the qubits using the arrays of complex amplitudes.
  void SetState(Complex new_state[]);

  //Sets the state to an equal superposition of all possible states
  //between 0 and number inclusive.
  void SetAverage(int number);

  //Normalise the state amplitudes.
  void Norm(); 
  
  //Get the probability of a given state.  This is used in the
  //discrete Fourier transformation.  In a real quantum computer such
  //an operation would not be possible, on the flip side, it would
  //also not be necessary as you could simply build a DFT gate, and
  //run your superposition through it to get the right answer.
  Complex GetProb(int state);

  //Return the size of the register.
  int Size();

private:
  int reg_size;
  Complex *State;
};

QuReg::QuReg() {
  reg_size = 0;
  State = 0;
}

//Constructor.
QuReg::QuReg(int size) {
  reg_size = size;
  State = new Complex[(int)pow(2, reg_size)];
  srand(time(NULL));
}

//Copy Constructor
QuReg::QuReg(const QuReg & old) {
  reg_size = old.reg_size;
  int reg_length = (int) pow(2, reg_size);
  State = new Complex[reg_length];
  for (int i = 0 ; i < reg_length ; i++) {
    State[i] = old.State[i];
  }
}

//Destructor.
QuReg::~QuReg() {
  delete [] State;
}

//Return the probability amplitude of the state'th state.
Complex QuReg::GetProb(int state) {
  if (state >= pow(2, reg_size)) {
    cout << "You are trying to measure past the end of an array in qureg::GetProb!" 
	 << endl << flush;
  } else {
    return(State[state]);
  }
}

//Normalise the probability amplitude, this ensures that the sum of
//the sum of the squares of all the real and imaginary components is
//equal to one.
void QuReg::Norm() {
  double b;
  double f, g;
  b = 0;
  for (int i = 0; i < pow(2, reg_size) ; i++) {
    b += pow(State[i].Real(), 2) + pow(State[i].Imaginary(), 2);
  }
  b = pow(b, -.5);
  for (int i = 0; i < pow(2, reg_size) ; i++) {
    f = State[i].Real() * b;
    g = State[i].Imaginary() * b;
    State[i].Set(f, g);
  }
}

//Returns the size of the register.
int QuReg::Size() {
  return reg_size;
}

//Measure a state, and return the decimal value measured.  Collapse
//the state so that the probability of measuring the measured value in
//the future is 1, and the probability of measuring any other state is
//0.
int QuReg::DecMeasure() {
  int done = 0;
  int DecVal = -1; //-1 is an error, we did not measure anything.
  double rand1, a, b;
  rand1 = rand()/(double)RAND_MAX;
  a = b = 0;
  for (int i = 0 ; i < pow(2, reg_size)  ;i++) {
    if (!done ){
      b += pow(State[i].Real(), 2) + pow(State[i].Imaginary(), 2);
      if (b > rand1 && rand1 > a) {
	//We have just measured the i state.
	for (int j = 0; j < pow(2, reg_size) ; j++) {
	  State[j].Set(0,0);
	}
	State[i].Set(1,0);
	DecVal = i;
	done = 1;
      }
      a += pow(State[i].Real(), 2) + pow(State[i].Imaginary(), 2);
    }
  }
  return DecVal;
}

//For debugging, output information about the register.
void QuReg::Dump(int verbose) {
  for (int i = 0 ; i < pow(2, reg_size) ; i++) {
    if (verbose || fabs(State[i].Real()) > pow(10,-14) 
	|| fabs(State[i].Imaginary()) > pow(10,-14)) {
      cout << "State " << i << " has probability amplitude " 
	   << State[i].Real() << " + i" << State[i].Imaginary() 
	   << endl << flush;
    }
  }
}

//Set the states to those given in the new_state array.
void QuReg::SetState(Complex new_state[]) {
  //Beware, this function will cause segfaults if new_state is too
  //small.
  for (int i = 0 ; i < pow(2, reg_size) ; i++) {
    State[i].Set(new_state[i].Real(), new_state[i].Imaginary());
  }
}

//Set the State to an equal superposition of the integers 0 -> number
//- 1
void QuReg::SetAverage(int number) {
  if (number >= pow(2, reg_size)) {
    cout << "Error, initialising past end of array in qureg::SetAverage.\n";
  } else {
    double prob;
    prob = pow(number, -.5);
    for (int i = 0 ; i <= number ; i++) {
      State[i].Set(prob, 0);
    }
  }
}



Matthew Hayward 2008-04-26