qggates.cpp

00001 /***************************************************************************
00002  *   QGame++                                                               *
00003  *   =======                                                               *
00004  *   A Quantum Gate And Measurement Emulator.                              *
00005  *                                                                         *
00006  *   Copyright (C) 2003/04 by Manuel Nickschas                             *
00007  *   <qgame-devel@nickschas.de>                                            *
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  *   This program is distributed in the hope that it will be useful,       *
00015  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017  *   GNU General Public License for more details.                          *
00018  *                                                                         *
00019  *   You should have received a copy of the GNU General Public License     *
00020  *   along with this program; if not, write to the                         *
00021  *   Free Software Foundation, Inc.,                                       *
00022  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
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 &reg) throw(Error) {
00047   vector<Complex> res;
00048   if(numQubits!=reg.numQb()) throw(E_MISMATCH);
00049   for(int row = 0; row<numAmps; row++) { //cerr << "\n ** ";
00050     Complex dum(0,0);
00051     for(int col = 0; col<numAmps; col++) { //cerr << matrix[row][col] << " ";
00052       dum+=matrix[row][col]*reg[col];
00053     }
00054     res.push_back(dum);
00055   }  // TODO: optimize!
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 }

Generated on Sat Apr 3 18:42:28 2004 for QGame++ by doxygen 1.3.5