1.2 DIAGNÓSTICO DEL COLEGIO JUANA ESCOBAR
1.2.3 Problemáticas del Consejo Estudiantil
In order to give an illustrative example, we use the system introduced in Sec. 5 for the case of N qubits. We will extend this system to include a flip-flop interaction (for the Hamiltonian
see e.g. Sec. 2) between the qubits and realize an iSWAP around the corner using a SOPS protocol (see Sec. (2)). This needs the quantum gate library libQuantumGates which I have also documented in [212].
The syntax for the protocol in the ini-file is very simple. Here is the example for the adapted ini-file containing the protocol:
# two-qubits dims=2,2;
#same coupling -> Bell state |Phi+> v_g=1.0,1.0;
#decay rates kappa=0.0,0.0; #dephasing rates gamma_phi=0.0,0.0; #time interval and step t_start=0.0;
t_end=100.0; delta_t=0.001; #the protocol
Protocol="SWAP(0,1,-1.5,1.35)|ISWAPutp(1,2,1.35)|SWAP(0,1,-1.5,1.35)"; #reference frequency to tune qubits to when iSWAP is active
ref_freq_dispersive=100.0; #qubit energies in the idle state e=30.0,50.0,70.0;
#strength of flipflop-interaction J=1.35,1.35;
As one can see, the single gates are like functions separated by a pipe symbol. Arbitrary gates can be concatenated. A separate protocol parser class is needed to decompose the string into a vector of gates. This is done e.g. by this definition and sample implementation of the class CParser which is itself not part of the quantum gate library. From the function CParser::m_Atom2Gate one can understand the syntax of the single gates in the ini-file and also extend it if one were to add new gates to the gate-library (the following code just shows how one particular gate is parsed. Others work analogously and can be obtained ifrom the author in an example project).
class CParser {
public: CParser();
virtual ~CParser();
void m_ParseExpression(const string& expression); CProtocol* m_ProtocolPtr
public:
vector<string> m_GetAtoms(const string& expression); void m_Atom2Gate(const string& atom);
}; CParser::CParser() { m_ProtocolPtr = NULL; m_IniFilePtr = NULL; } CParser::~CParser() { }
{
//check for "’s
if(expression.find_first_of("\"",0)!=string::npos) throw string("\" must not be part of an expression"); vector<string> atoms = m_GetAtoms(expression);
int i=0; for(i=0;i<atoms.size();++i) { m_Atom2Gate(atoms[i]); } }
vector<string> CParser::m_GetAtoms(const string& expression) {
//.separates the single operations
string operationbuffer=expression; vector<string> retval;
if(operationbuffer.find_first_of("|",0)==string::npos) { //only one atom
retval.push_back(operationbuffer); } else { while(operationbuffer.find_first_of("|",0)!=string::npos) {
int endpos = operationbuffer.find_first_of("|",0); retval.push_back(operationbuffer.substr(0,endpos)); operationbuffer.erase(0,endpos+1); } if(operationbuffer.length()>0) retval.push_back(operationbuffer); } return retval; }
void CParser::m_Atom2Gate(const string& atom) { string myatom=atom; string namebuffer; string arguments; int startpos=myatom.find("(",0); if(startpos==string::npos) {
throw string("Atomic expression must contain ("); }
int endpos=myatom.find(")"); if(endpos==string::npos) {
throw string("Atomic expression must contain )"); }
namebuffer=myatom.substr(0,startpos); //myatom.erase(0,startpos); arguments=myatom.substr(startpos+1,endpos-startpos-1); //Komma-separiert vector<string> v_arguments; startpos=arguments.find_first_of(",",0); while(startpos!=string::npos) { v_arguments.push_back(arguments.substr(0,startpos)); cout << v_arguments.back() << endl;
arguments.erase(0,startpos+1); startpos=arguments.find_first_of(",",0); } if(arguments.size()>0) { v_arguments.push_back(arguments); }
cout << v_arguments.back() << endl;
//get time_offset double time_offset=0.0; int i=0; for(i=0;i<m_ProtocolPtr->m_protocol.size();++i) { time_offset+=m_ProtocolPtr->m_protocol[i]->m_Getduration(); } string strtime_offset; convert(time_offset,strtime_offset);
cout << "time_offset" << strtime_offset << endl; if(namebuffer=="R")
{
if(v_arguments.size()==4)//numb_of qubit,rotation axis,frequency,time = pi/frequency* x,
{
v_arguments.push_back("-1"); //no cavities explicitly in simulation
v_arguments.push_back(strtime_offset); m_ProtocolPtr->m_protocol.push_back(new CGateZeroRiseTimeSingleQubitRotation(v_arguments )); } else if(v_arguments.size()==5) { //m_ProtocolPtr->m_protocol.push_back(new CGateFiniteRiseTimeSingleQubitRotation( v_arguments)); v_arguments.push_back(strtime_offset); m_ProtocolPtr->m_protocol.push_back(new CGateZeroRiseTimeSingleQubitRotation( v_arguments)); }
else throw string("Function R must have 5 arguments"); }
else if(namebuffer=="rISWAPutp") {
{
v_arguments.push_back("-1"); //no cavities explicitly in simulation
v_arguments.push_back(strtime_offset);
m_ProtocolPtr->m_protocol.push_back(new CGateZeroRiseTimerISWAPutp(v_arguments)); }
else if(v_arguments.size()==4)//numb_of qubit1, numb_of_qubit2,frequency,
{
v_arguments.push_back(strtime_offset);
m_ProtocolPtr->m_protocol.push_back(new CGateZeroRiseTimerISWAPutp(v_arguments)); }
else throw string("Function rISWAPutp must have 3 or 4 arguments"); }
else {
// other gates
}
else throw string(string("Function")+namebuffer+string(" not known to Parser.")); m_ProtocolPtr->m_protocol.back()->m_pProtocol=m_ProtocolPtr;
}
Extend the right-hand side
Now we need to adapt the right-hand side of the previous example in the sense that we do not look at measurement, so we can use the Runge-Kutta solver and include the protocol. This is straightforward:
CCavityGridRungeKutta5::CCavityGridRungeKutta5() { } CCavityGridRungeKutta5::~CCavityGridRungeKutta5() { }
void CCavityGridRungeKutta5::m_rhs(const CFuncCont* FV /*Function Values to be used*/, CFuncCont* vTarget, const vector<double>& xi, double t)
{
complex i = complex(0.,1.); complex one = complex(1.0,0.0);
vTarget->m_DensMat.set_to_zero(); vTarget->m_DensMat.m_add_term_qubit_energy(0,m_e[0],-i,&FV->m_DensMat); vTarget->m_DensMat.m_add_term_qubit_energy(1,m_e[1],-i,&FV->m_DensMat); vTarget->m_DensMat.m_add_term_qubit_energy(2,m_e[2],-i,&FV->m_DensMat); vTarget->m_DensMat.m_add_term_flipflop(0,1,m_J[0],-i,&FV->m_DensMat); vTarget->m_DensMat.m_add_term_flipflop(1,2,m_J[1],-i,&FV->m_DensMat);
vTarget->m_DensMat += ( (-i)*(m_protocol.m_act(FV->m_DensMat, FV->m_phases,t) ));
vTarget->m_phases[0] = m_e[m_switch_phases[0]]; vTarget->m_phases[1] = m_e[m_switch_phases[1]]; vTarget->m_phases[2] = m_e[m_switch_phases[2]];
for(size_t it=0;it<m_dims.size() && m_bdodecoherence==true;it++) {
vTarget->m_DensMat.m_add_term_decay(it,m_kappa[it],one,&(FV->m_DensMat));
vTarget->m_DensMat.m_add_term_pure_dephasing(it,m_gamma_phi[it],one,&(FV->m_DensMat)); }
Appropriately adapt the main
Here, among some other parameters, we need to parse the protocol and pass it to the system class.
int main(int argc, char **argv) { try { string IniFilename; CIniFileBase MyIniFile; if(argc == 3) { if(!(string(argv[1])=="-i")
throw string("First argument has to be -i"); IniFilename = string(argv[2]);
}
else throw string("-i inifilename missing"); MyIniFile.m_ReadIniFile(IniFilename); CCavityGridRungeKutta5 MyRK; MyRK.m_kappa = MyIniFile.m_GetdvecParameter("kappa"); MyRK.m_gamma_phi = MyIniFile.m_GetdvecParameter("gamma_phi"); MyRK.m_t.push_back(MyIniFile.m_GetParameter("t_start"); MyRK.m_t_end=MyIniFile.m_GetParameter("t_end"); MyRK.m_delta_t = MyIniFile.m_GetParameter("delta_t"); MyRK.m_v_g = MyIniFile.m_GetdvecParameter("v_g"); MyRK.m_Gamma = MyIniFile.m_GetParameter("Gamma"); MyRk.m_bdodecoherence = bool(MyIniFile.m_GetParameter("dodecoherence")); MyRK.m_dims=dims;
//get the protocol from the ini-file
string strproto = MyIniFile.m_GetStrParameter(Protocol); CProtocol MyProtocol;
CParser MyParser;
MyParser.m_pProtocol=&MyProtocol; MyParser.m_ParseExpression(strproto);
//solve the master equation
MyRK.m_eps=pow(10.0,double(-8)); MyRK.m_SetRK5Coefficients(); MyRK.m_evolve(true); } catch(string &e) {
cout << "Error: " << e << endl; }
catch(...) {
cout << "Unknown error" << endl; }
return 0; }