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 "qggates.h"
00026 #include "qgtypes.h"
00027
00028 #include <sstream>
00029
00030 using namespace qgame;
00031 using namespace std;
00032
00033 string QGate::dump() const {
00034 return "GENERIC QGATE";
00035 }
00036
00037 ostream & qgame::operator<<(ostream &o, const QGate &g) {
00038 o << g.dump();
00039 return o;
00040 }
00041
00042 unsigned int QMatrixGate::numQb() {
00043 return numQubits;
00044 }
00045
00046 void QMatrixGate::apply(QuSubReg ®) throw(Error) {
00047 vector<Complex> res;
00048 if(numQubits!=reg.numQb()) throw(E_MISMATCH);
00049 for(int row = 0; row<numAmps; row++) {
00050 Complex dum(0,0);
00051 for(int col = 0; col<numAmps; col++) {
00052 dum+=matrix[row][col]*reg[col];
00053 }
00054 res.push_back(dum);
00055 }
00056 for(int row = 0; row<numAmps; row++) {
00057 reg[row]=res[row];
00058 }
00059 }
00060
00061 QMatrixGate::QMatrixGate(vector<vector<Complex> > m) {
00062 numAmps = m.size();
00063 numQubits = (int)(log((double)numAmps)/log(2.)+.5);
00064 matrix = m;
00065 }
00066
00067 string QMatrixGate::dump() const {
00068 return "MATRIX-GATE";
00069 }
00070
00071
00072
00073 QGateQNOT::QGateQNOT() {
00074 numQubits = 1;
00075 numAmps = 2;
00076 vector<Complex> row0,row1;
00077 row0.push_back(0); row0.push_back(1);
00078 row1.push_back(1); row1.push_back(0);
00079 matrix.push_back(row0);
00080 matrix.push_back(row1);
00081 }
00082
00083 string QGateQNOT::dump() const {
00084 return "QNOT";
00085 }
00086
00087 QGateCNOT::QGateCNOT() {
00088 numQubits = 2;
00089 numAmps = 4;
00090 vector<Complex> row(4,Complex(0,0));
00091 matrix.insert(matrix.begin(),4,row);
00092 matrix[0][0]=matrix[1][1]=matrix[2][3]=matrix[3][2]=Complex(1,0);
00093 }
00094
00095 string QGateCNOT::dump() const {
00096 return "CNOT";
00097 }
00098
00099 QGateNAND::QGateNAND() {
00100 numQubits = 3;
00101 numAmps = 8;
00102 vector<Complex> row(8,Complex(0,0));
00103 matrix.insert(matrix.begin(),8,row);
00104 matrix[1][0]=matrix[0][1]=matrix[2][3]=matrix[3][2]=Complex(1,0);
00105 matrix[4][5]=matrix[5][4]=matrix[6][7]=matrix[7][6]=Complex(1,0);
00106 }
00107
00108 string QGateNAND::dump() const {
00109 return "NAND";
00110 }
00111
00112 QGateSRN::QGateSRN() {
00113 numQubits = 1;
00114 numAmps = 2;
00115 vector<Complex> row(2,Complex(1./sqrt(2.),0));
00116 matrix.insert(matrix.begin(),2,row);
00117 matrix[0][1]=Complex(-1./sqrt(2.),0);
00118 }
00119
00120 string QGateSRN::dump() const {
00121 return "SRN";
00122 }
00123
00124 QGateH2::QGateH2() {
00125 numQubits = 1;
00126 numAmps = 2;
00127 vector<Complex> row(2,Complex(1./sqrt(2.),0));
00128 matrix.insert(matrix.begin(),2,row);
00129 matrix[1][1]=Complex(-1./sqrt(2.),0);
00130 }
00131
00132 string QGateH2::dump() const {
00133 return "HADAMARD";
00134 }
00135
00136 QGateUTHETA::QGateUTHETA(double t) {
00137 theta = t;
00138 numQubits = 1;
00139 numAmps = 2;
00140 vector<Complex> row(2,Complex(cos(t),0));
00141 matrix.insert(matrix.begin(),2,row);
00142 matrix[0][1]=Complex(sin(t),0);
00143 matrix[1][0]=Complex(-sin(t),0);
00144 }
00145
00146 string QGateUTHETA::dump() const {
00147 ostringstream ss;
00148 ss << "U-THETA [theta="<<theta<<"]";
00149 return ss.str();
00150 }
00151
00152 QGateCPHASEOLD::QGateCPHASEOLD(double a) {
00153 alpha = a;
00154 numQubits = 2;
00155 numAmps = 4;
00156 vector<Complex> row(4,Complex(0,0));
00157 matrix.insert(matrix.begin(),4,row);
00158 matrix[0][0]=matrix[1][1]=Complex(1,0);
00159 matrix[2][3]=Complex(cos(alpha),sin(alpha));
00160 matrix[3][2]=Complex(cos(-alpha),sin(-alpha));
00161 }
00162
00163 string QGateCPHASEOLD::dump() const {
00164 ostringstream ss;
00165 ss << "CPHASE-OLD [alpha="<<alpha<<"]";
00166 return ss.str();
00167 }
00168
00169 QGateCPHASE::QGateCPHASE(double a) {
00170 alpha = a;
00171 numQubits = 2;
00172 numAmps = 4;
00173 vector<Complex> row(4,Complex(0,0));
00174 matrix.insert(matrix.begin(),4,row);
00175 matrix[0][0]=matrix[1][1]=matrix[2][2]=Complex(1,0);
00176 matrix[3][3]=Complex(cos(alpha),sin(alpha));
00177 }
00178
00179 string QGateCPHASE::dump() const {
00180 ostringstream ss;
00181 ss << "CPHASE [alpha="<<alpha<<"]";
00182 return ss.str();
00183 }
00184
00185 QGateU2::QGateU2(double ph,double t,double ps,double a) {
00186 phi = ph; theta = t; psi = ps; alpha = a;
00187 numQubits = 1;
00188 numAmps = 2;
00189 vector<Complex> row(2,Complex(0,0));
00190 matrix.insert(matrix.begin(),2,row);
00191 matrix[0][0]=Complex(cos(-phi-psi+alpha)*cos( theta),sin(-phi-psi+alpha)*cos( theta));
00192 matrix[0][1]=Complex(cos(-phi+psi+alpha)*sin(-theta),sin(-phi+psi+alpha)*sin(-theta));
00193 matrix[1][0]=Complex(cos( phi-psi+alpha)*sin( theta),sin( phi-psi+alpha)*sin( theta));
00194 matrix[1][1]=Complex(cos( phi+psi+alpha)*cos( theta),sin( phi+psi+alpha)*cos( theta));
00195 }
00196
00197 string QGateU2::dump() const {
00198 ostringstream ss;
00199 ss << "U2 [phi="<<phi<<" theta="<<theta<<" psi="<<psi<<" alpha="<<alpha<<"]";
00200 return ss.str();
00201 }
00202
00203 QGateSWAP::QGateSWAP() : QMatrixGate() {
00204 numQubits = 2;
00205 numAmps = 4;
00206 vector<Complex> row(4,Complex(0,0));
00207 matrix.insert(matrix.begin(),4,row);
00208 matrix[0][0]=matrix[2][1]=matrix[1][2]=matrix[3][3]=Complex(1,0);
00209 }
00210
00211 string QGateSWAP::dump() const {
00212 return "SWAP";
00213 }
00214
00215 QOracle::QOracle(const string &tt) : QMatrixGate() {
00216 truthtable = tt;
00217 numAmps = tt.length()*2;
00218 numQubits = (int)(log((double)numAmps)/log(2.)+.5);
00219 vector<Complex> row(numAmps,Complex(0,0));
00220 matrix.insert(matrix.begin(),numAmps,row);
00221 for(int i=0; i<tt.length();i++) {
00222 if(tt[i]=='0') {
00223 matrix[i*2][i*2]=1;matrix[i*2+1][i*2+1]=1;
00224 } else if(tt[i]=='1') {
00225 matrix[i*2][i*2+1]=1;matrix[i*2+1][i*2]=1;
00226 } else throw Error(E_SYNTAX);
00227 }
00228 }
00229
00230 string QOracle::dump() const {
00231 return "ORACLE [tt="+truthtable+"]";
00232 }