Below is the much simpler code for a single qubit. You may find it entertaining and educational to write a simple driver program for this class to toy with a single qubit.
#include <iostream> #include <math.h> #include <stdlib.h> #include "complex.h" using namespace std; class Qubit { public: Qubit(); //Default constructor. virtual ~Qubit(); //Default destructor. int Measure(); //Returns zero_state = 0 or one_state = 1 in accordance //with the probabilities of zero_state and one_state. void Dump() const; //Prints our zero_state, and one_state, without //disturbing anything, this operation has no physical //realization, it is only for information and debugging. //It should never be used in an algorithm for //information. void SetState(const Complex& zero_prob, const Complex& one_prob); // Takes two complex numbers and sets the states to //those values. void SetAverage(); //Sets the state to 2^(1/2) zero_state, 2^(1/2) //one_state. No imaginary/phase component. double MCC(int state) const; //Multiply the zero or one state by its complex //conjugate, and return the value. This value //will always be a real number, with no imaginary //component. private: Complex zero_state; //The probability of finding the Qubit in the zero or all imaginary //state. I currently use only the real portion. Complex one_state; //The probability of finding the Qubit in the one or all real state. //I currently use only the real portion. //|zero_state|^2 + |one_state|^2 should always be 1. //This notation means z_s * ComplexConjugate(z_s) + o_s * //ComplexConjugate(o_s) = 1. }; //Qubit constructor, initially sets things in the zero state. Qubit::Qubit() { zero_state = Complex(1,0); one_state = Complex(0,0); srand(time(NULL)); } //Returns <state>_state * ComplexConjugate(<state>_state). double Qubit::MCC(int state) const { if (state == 0) { return (pow(zero_state.Real(), 2) + pow(zero_state.Imaginary(), 2)); } else { return (pow(one_state.Real(), 2) + pow(one_state.Imaginary(), 2)); } } //Measurement operator. Destructively collapses superpositions. int Qubit::Measure() { double rand1 = rand()/(double)RAND_MAX; //This assumes that the sum of the squares of the amplitudes are = 1 if (MCC(0) > rand1) { zero_state.Set(1,0); one_state.Set(0,0); return 0; } else { zero_state.Set(0,0); one_state.Set(1,0); return 1; } } //Outputs state info for our qubit. For debugging purposes. void Qubit::Dump() const{ cout << "Amplitude of the zero state is " << zero_state.Real() << " +i" << zero_state.Imaginary() << endl << flush; cout << "Amplitude of the one state is " << one_state.Real() << " +i" << one_state.Imaginary() << endl << flush; } //Sets the zero and one states to arbitrary amplitudes. Outputs //an error message if the two values MCC'ed != 1 + 0i. void Qubit::SetState(const Complex& zero_prob, const Complex& one_prob) { zero_state = zero_prob; one_state = one_prob; //Determine if |zero_state|^2 + |one_state|^2 == 1, if not we //are not in a valid state. double probab; probab = MCC(0) + MCC(1); if (fabs(probab - 1) > pow(10, -10)) { //This funny expression //allows us some rounding errors. cout << "Warning, total probability for in SetState is different from 1." << endl << flush; } } //Sets the qubit 1/2 way between the 0 state and the 1 state. No phase. void Qubit::SetAverage() { zero_state.Set(pow(2, -.5), 0); one_state.Set(pow(2, -.5), 0); }