00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "qgame++.h"
00026 #include "qgtypes.h"
00027 #include "qgerror.h"
00028
00029 using namespace qgame;
00030 using namespace std;
00031
00032
00033
00034
00035
00036 Complex::Complex(double r, double i) {
00037 re = r; im = i;
00038 }
00039
00040 double Complex::Re() {
00041 return re;
00042 }
00043
00044 double Complex::Im() {
00045 return im;
00046 }
00047
00048 Complex Complex::operator+(const Complex &c) {
00049 double r = re + c.re;
00050 double i = im + c.im;
00051 return Complex(r,i);
00052 }
00053
00054 Complex Complex::operator+=(const Complex &c) {
00055 re += c.re;
00056 im += c.im;
00057 return *this;
00058 }
00059
00060 Complex Complex::operator-(const Complex &c) {
00061 double r = re - c.re;
00062 double i = im - c.im;
00063 return Complex(r,i);
00064 }
00065
00066 Complex Complex::operator*(const Complex &c) {
00067 double r = re*c.re - im*c.im;
00068 double i = re*c.im + im*c.re;
00069 return Complex(r,i);
00070 }
00071
00072 Complex Complex::operator*=(const Complex &c) {
00073 double r = re*c.re - im*c.im;
00074 double i = re*c.im + im*c.re;
00075 re = r; im = i;
00076 return *this;
00077 }
00078
00079 std::ostream& qgame::operator<<(std::ostream &o, const Complex &c) {
00080 o << '(' << c.re << ',' << c.im << ')';
00081 return o;
00082 }
00083
00084 double Complex::sqabs() {
00085 return re*re + im*im;
00086 }
00087
00088
00089 double qgame::sqabs(const Complex &c) {
00090 return c.re*c.re + c.im*c.im;
00091 }
00092
00093
00094
00095
00096
00097 unsigned int QubitList::size() const {
00098 return qbl.size();
00099 }
00100
00101 void QubitList::append(int x) {
00102 qbl.push_back(x);
00103 }
00104
00105 int QubitList::operator[](const unsigned int i) const throw(Error) {
00106 if(i>=qbl.size()) throw Error(E_OUTOFBOUNDS);
00107 return qbl[i];
00108 }
00109
00110 ostream & qgame::operator<<(ostream &o, const QubitList &l) {
00111 o << "{ ";
00112 for(int i=l.size()-1; i>=0; i--) o << l[i] << " ";
00113 o << "}";
00114 }
00115
00116
00117
00118
00119
00120 QuSubReg::QuSubReg(int s) {
00121 num = s;
00122 sub = vector<Complex*>(1<<s, (Complex*)NULL);
00123
00124 }
00125
00126 QuSubReg::~QuSubReg() {
00127
00128 }
00129
00130 unsigned int QuSubReg::numAmps() const {
00131 return 1<<num;
00132 }
00133
00134 unsigned int QuSubReg::numQb() const {
00135 return num;
00136 }
00137
00138 Complex & QuSubReg::operator[](const unsigned int i) throw(Error) {
00139 if(i>=sub.size()) throw Error(E_OUTOFBOUNDS);
00140 return *sub[i];
00141 }
00142
00143
00144
00145
00146
00147 Qureg::Qureg(int s) {
00148 num = s;
00149 amp = vector<Complex>(1<<s, Complex(0,0));
00150 amp[0] = Complex(1,0);
00151 }
00152
00153 vector<QuSubReg> Qureg::getSubRegs(const QubitList &qubits) {
00154 vector<QuSubReg> result;
00155 int numqb = qubits.size();
00156 int numot = num - numqb;
00157 QubitList otbits;
00158 for(int i=0; i<num; i++) {
00159 bool flg = false;
00160 for(int j=0; j<numqb; j++) {
00161 if(qubits[j]==i) { flg = true; break; }
00162 }
00163 if(!flg) otbits.append(i);
00164 }
00165 for(int sr=0; sr<(1<<numot); sr++) {
00166 int index2 = 0; int dum = sr;
00167 for(int i = 0; i<numot; i++) {
00168 if(dum%2) index2 += (1<<otbits[i]);
00169 dum = dum>>1;
00170 }
00171 QuSubReg sreg(numqb);
00172 for(int sqb=0; sqb<(1<<numqb); sqb++) {
00173 int index = index2; dum = sqb;
00174 for(int i = 0; i<numqb; i++) {
00175 if(dum%2) index += (1<<qubits[i]);
00176 dum = dum>>1;
00177 }
00178 sreg.sub[sqb] = &[index];
00179 }
00180 result.push_back(sreg);
00181 }
00182 return result;
00183 }
00184
00185
00186 vector<double> Qureg::getProbabilities(const QubitList &qubits) {
00187 vector<double> result = vector<double>(1<<qubits.size(),0);
00188 vector<QuSubReg> subregs = getSubRegs(qubits);
00189 double t = 0;
00190
00191 for(int s = 0; s < subregs.size(); s++) {
00192 for(int a = 0; a < subregs[s].numAmps(); a++) {
00193 result[a] += sqabs(subregs[s][a]);
00194
00195 t += sqabs(subregs[s][a]);
00196 }
00197 }
00198
00199 if(fabs(1-t)>.0000001) cerr << "\n\nWARNING: Non-unitary transformation? p="<<t;
00200
00201
00202 return result;
00203 }
00204
00205
00206 void Qureg::collapse(const QubitList &qubits, int value) {
00207 vector<QuSubReg> subregs = getSubRegs(qubits);
00208 for(int s = 0; s < subregs.size(); s++) {
00209 for(int a = 0; a < subregs[s].numAmps(); a++) {
00210 if(a != value) subregs[s][a] = 0;
00211 }
00212 }
00213 normalize();
00214 }
00215
00216 void Qureg::normalize() {
00217 double sum = 0;
00218 for(int i=0; i<amp.size(); i++) sum += sqabs(amp[i]);
00219 if(sum == 0) cerr << "\nWARNING: Cannot happen!";
00220 sum = 1.0/sqrt(sum);
00221 for(int i=0; i<amp.size(); i++) amp[i]*=sum;
00222
00223 }
00224
00225 unsigned int Qureg::size() const {
00226 return num;
00227 }
00228
00229 Complex & Qureg::operator[](const unsigned int i) throw(Error) {
00230 if(i>=amp.size()) throw Error(E_OUTOFBOUNDS);
00231 return amp[i];
00232 };
00233
00234 #if 0
00235
00236 std::ostream& qgame::operator<<(std::ostream &o, const Qureg &r) {
00237 o << "[ ";
00238 for(int i=0; i<r.amp.size();i++) o << r.amp[i] << ' ';
00239 o << "]";
00240 return o;
00241 }
00242 #else
00243
00244 std::ostream& qgame::operator<<(std::ostream &o, Qureg r) {
00245 for(int i = 0; i<r.amp.size(); i++) {
00246 o << "\n |";
00247 int dum = i;
00248 for(int j = r.num-1; j>=0; j--) {
00249 if(dum >= 1<<j) { dum -= 1<<j; o << "1"; }
00250 else o << "0";
00251 }
00252 o << ">: " << r[i] << " (p = " << sqabs(r.amp[i]) << ")";
00253 }
00254 return o;
00255 }
00256
00257 #endif
00258
00259
00260
00261
00262
00263
00264 TestCase::TestCase(const string &casestr) {
00265 char buf[256];
00266 desiredRes = -1;
00267 if(casestr.length()<3) return;
00268
00269 int k;
00270 for(k=0; k<casestr.length()-2; k++) {
00271 if(casestr[k]=='-') break;
00272 if(casestr[k]!='0' && casestr[k]!='1') return;
00273 buf[k] = casestr[k];
00274 }
00275 buf[k] = '\0';
00276 if(casestr[k]!='-') return;
00277 char *endpnt;
00278 desiredRes = strtol(casestr.c_str()+k+1,&endpnt,10);
00279 if(*endpnt != '\0') desiredRes = -1;
00280 oracleTT = buf;
00281 }