def generate_2QB_Cliffords(_index, **kwargs): seq_QB1 = [] seq_QB2 = [] seq_Cplr = [] generator = kwargs.get('generator', 'CZ') sequence_rb.add_twoQ_clifford(_index, seq_QB1, seq_QB2, gate_seq_Cplr=seq_Cplr, generator=generator) m2QBClifford = np.identity(4, dtype=complex) for i in range(len(seq_QB1)): _mGate = np.matrix([1]) # 2QB Gates if (generator == 'CZ'): if (seq_QB1[i] == gates.CZ or seq_QB2[i] == gates.CZ): # two qubit gates # print('2QB Gate: CZ') _mGate = np.kron(dict_m2QBGate['CZ'], _mGate) m2QBClifford = mul(_mGate, m2QBClifford) continue elif (generator == 'iSWAP_Cplr'): if (seq_Cplr[i] == gates.iSWAP_Cplr): # print('2QB Gate: iSWAP_Cplr') _mGate = np.kron(dict_m2QBGate['iSWAP'], _mGate) m2QBClifford = mul(_mGate, m2QBClifford) continue # 1QB gates # print('1QB Gate:') for g in [seq_QB2[i], seq_QB1[i]]: if (g == gates.I): _mGate = np.kron(dict_m1QBGate['I'], _mGate) elif (g == gates.Xp): _mGate = np.kron(dict_m1QBGate['Xp'], _mGate) elif (g == gates.Xm): _mGate = np.kron(dict_m1QBGate['Xm'], _mGate) elif (g == gates.X2p): _mGate = np.kron(dict_m1QBGate['X2p'], _mGate) elif (g == gates.X2m): _mGate = np.kron(dict_m1QBGate['X2m'], _mGate) elif (g == gates.Yp): _mGate = np.kron(dict_m1QBGate['Yp'], _mGate) elif (g == gates.Ym): _mGate = np.kron(dict_m1QBGate['Ym'], _mGate) elif (g == gates.Y2p): _mGate = np.kron(dict_m1QBGate['Y2p'], _mGate) elif (g == gates.Y2m): _mGate = np.kron(dict_m1QBGate['Y2m'], _mGate) elif (g == gates.Zp): _mGate = np.kron(dict_m1QBGate['Zp'], _mGate) elif (g == gates.Zm): _mGate = np.kron(dict_m1QBGate['Zm'], _mGate) elif (g == gates.Z2p): _mGate = np.kron(dict_m1QBGate['Z2p'], _mGate) elif (g == gates.Z2m): _mGate = np.kron(dict_m1QBGate['Z2m'], _mGate) m2QBClifford = mul(_mGate, m2QBClifford) return (m2QBClifford)
def generate_2QB_Cliffords(_index, **kwargs): seq_QB1 = [] seq_QB2 = [] seq_Aux = [] generator = kwargs.get('generator', 'CZ') sequence_rb.add_twoQ_clifford(_index, seq_QB1, seq_QB2, gate_seq_aux = seq_Aux, generator = generator) m2QBClifford = np.identity(4, dtype = complex) for i in range(len(seq_QB1)): # print(Gate_to_strGate(seq_QB1[i]), Gate_to_strGate(seq_QB2[i]), Gate_to_strGate(seq_Aux[i])) _mGate = np.matrix([1]) if generator == 'CZ': if (seq_QB1[i] == gates.CZ or seq_QB2[i] == gates.CZ ): # two qubit gates _mGate = np.kron(dict_m2QBGate['CZ'], _mGate) m2QBClifford = mul(_mGate, m2QBClifford) continue elif generator == 'CR_CNOT': if seq_Aux[i] == gates.CR: _mGate = np.kron(dict_m2QBGate['CR_CNOT'], _mGate) m2QBClifford = mul(_mGate, m2QBClifford) continue # else: # 1QB gates for g in [seq_QB2[i], seq_QB1[i]]: if (g == gates.I): _mGate = np.kron(dict_m1QBGate['I'], _mGate) elif (g == gates.Xp): _mGate = np.kron(dict_m1QBGate['Xp'], _mGate) elif (g == gates.Xm): _mGate = np.kron(dict_m1QBGate['Xm'], _mGate) elif (g == gates.X2p): _mGate = np.kron(dict_m1QBGate['X2p'], _mGate) elif (g == gates.X2m): _mGate = np.kron(dict_m1QBGate['X2m'], _mGate) elif (g == gates.Yp): _mGate = np.kron(dict_m1QBGate['Yp'], _mGate) elif (g == gates.Ym): _mGate = np.kron(dict_m1QBGate['Ym'], _mGate) elif (g == gates.Y2p): _mGate = np.kron(dict_m1QBGate['Y2p'], _mGate) elif (g == gates.Y2m): _mGate = np.kron(dict_m1QBGate['Y2m'], _mGate) elif (g == gates.Zp): _mGate = np.kron(dict_m1QBGate['Zp'], _mGate) elif (g == gates.VZp): _mGate = np.kron(dict_m1QBGate['VZp'], _mGate) elif (g == gates.Zm): _mGate = np.kron(dict_m1QBGate['Zm'], _mGate) elif (g == gates.Z2p): _mGate = np.kron(dict_m1QBGate['Z2p'], _mGate) elif (g == gates.Z2m): _mGate = np.kron(dict_m1QBGate['Z2m'], _mGate) m2QBClifford = mul(_mGate, m2QBClifford) return (m2QBClifford)
def generate_2QB_Cliffords(_index): seq_QB1 = [] seq_QB2 = [] sequence_rb.add_twoQ_clifford(_index, seq_QB1, seq_QB2) m2QBClifford = np.identity(4, dtype=complex) for i in range(len(seq_QB1)): _mGate = np.matrix([1]) if (seq_QB1[i] == gates.CZ or seq_QB2[i] == gates.CZ): # two qubit gates _mGate = np.kron(dict_m2QBGate['CZ'], _mGate) else: # 1QB gates for g in [seq_QB2[i], seq_QB1[i]]: if (g == gates.I): _mGate = np.kron(dict_m1QBGate['I'], _mGate) elif (g == gates.Xp): _mGate = np.kron(dict_m1QBGate['Xp'], _mGate) elif (g == gates.Xm): _mGate = np.kron(dict_m1QBGate['Xm'], _mGate) elif (g == gates.X2p): _mGate = np.kron(dict_m1QBGate['X2p'], _mGate) elif (g == gates.X2m): _mGate = np.kron(dict_m1QBGate['X2m'], _mGate) elif (g == gates.Yp): _mGate = np.kron(dict_m1QBGate['Yp'], _mGate) elif (g == gates.Ym): _mGate = np.kron(dict_m1QBGate['Ym'], _mGate) elif (g == gates.Y2p): _mGate = np.kron(dict_m1QBGate['Y2p'], _mGate) elif (g == gates.Y2m): _mGate = np.kron(dict_m1QBGate['Y2m'], _mGate) elif (g == gates.Zp): _mGate = np.kron(dict_m1QBGate['Zp'], _mGate) elif (g == gates.Zm): _mGate = np.kron(dict_m1QBGate['Zm'], _mGate) elif (g == gates.Z2p): _mGate = np.kron(dict_m1QBGate['Z2p'], _mGate) elif (g == gates.Z2m): _mGate = np.kron(dict_m1QBGate['Z2m'], _mGate) m2QBClifford = mul(_mGate, m2QBClifford) return (m2QBClifford)
and N_I_gate >= max_N_I_gate): min_N_2QB_gate, min_N_1QB_gate, max_N_I_gate, cheapest_index = ( N_2QB_gate, N_1QB_gate, N_I_gate, j) print( 'the cheapest sequence update! [N_2QB_gate, N_1QB_gate, N_I_gate, seq. index] ' + str([ min_N_2QB_gate, min_N_1QB_gate, max_N_I_gate, cheapest_index ])) seq_recovery_QB1 = [] seq_recovery_QB2 = [] seq_recovery_Cplr = [] sequence_rb.add_twoQ_clifford(cheapest_index, seq_recovery_QB1, seq_recovery_QB2, gate_seq_Cplr=seq_recovery_Cplr, generator=generator) # remove redundant Identity gates index_identity = [] # find where Identity gates are for p in range(len(seq_recovery_QB1)): if generator == 'CZ': if (seq_recovery_QB1[p] == gates.I and seq_recovery_QB2[p] == gates.I): index_identity.append(p) elif generator == 'iSWAP_Cplr': if (seq_recovery_QB1[p] == gates.I and seq_recovery_QB2[p] == gates.I and seq_recovery_Cplr[p] == gates.I): index_identity.append(p)
# if it has equal # of 2QB & 1QB gates, and more 1QB gates, update it. if (N_2QB_gate == min_N_2QB_gate and N_1QB_gate == min_N_1QB_gate and N_I_gate >= max_N_I_gate): min_N_2QB_gate, min_N_1QB_gate, max_N_I_gate, cheapest_index = ( N_2QB_gate, N_1QB_gate, N_I_gate, j) print( 'the cheapest sequence update! [N_2QB_gate, N_1QB_gate, N_I_gate, seq. index] ' + str([ min_N_2QB_gate, min_N_1QB_gate, max_N_I_gate, cheapest_index ])) seq_recovery_QB1 = [] seq_recovery_QB2 = [] sequence_rb.add_twoQ_clifford(cheapest_index, seq_recovery_QB1, seq_recovery_QB2) # remove redundant Identity gates index_identity = [] # find where Identity gates are for p in range(len(seq_recovery_QB1)): if (seq_recovery_QB1[p] == gates.I and seq_recovery_QB2[p] == gates.I): index_identity.append(p) seq_recovery_QB1 = [ m for n, m in enumerate(seq_recovery_QB1) if n not in index_identity ] seq_recovery_QB2 = [ m for n, m in enumerate(seq_recovery_QB2) if n not in index_identity ]
# find the cheapest recovery clifford gates. print('stabilizer state: '+ str(stabilizer)) print('Before recovery, final_psi_00: ' + str(final_psi_00.flatten())) print('find the cheapest recovery clifford gate') min_N_2QB_gate = np.inf min_N_1QB_gate = np.inf max_N_I_gate = -np.inf cheapest_index = None for j in range(N_2QBcliffords): recovery_gate = generate_2QB_Cliffords(j, generator = generator) seq_QB1 = [] seq_QB2 = [] seq_Aux = [] sequence_rb.add_twoQ_clifford(j, seq_QB1, seq_QB2, gate_seq_aux = seq_Aux, generator = generator) if ((np.abs(1-np.abs(dot(recovery_gate, final_psi_00)[0,0])) < 1e-6) and (np.abs(1-np.abs(dot(recovery_gate, final_psi_01)[1,0])) < 1e-6) and (np.abs(1-np.abs(dot(recovery_gate, final_psi_10)[2,0])) < 1e-6) and (np.abs(1-np.abs(dot(recovery_gate, final_psi_11)[3,0])) < 1e-6) and (np.abs(1-dot(recovery_gate, final_psi_01)[1,0]/dot(recovery_gate, final_psi_00)[0,0]) < 1e-6) and (np.abs(1-dot(recovery_gate, final_psi_10)[2,0]/dot(recovery_gate, final_psi_00)[0,0]) < 1e-6) and (np.abs(1-dot(recovery_gate, final_psi_11)[3,0]/dot(recovery_gate, final_psi_00)[0,0]) < 1e-6) ): print(dot(recovery_gate, final_psi_00)[0,0],dot(recovery_gate, final_psi_01)[1,0],dot(recovery_gate, final_psi_10)[2,0],dot(recovery_gate, final_psi_11)[3,0]) # if the gate is recovery, check if it is the cheapest. # Less 2QB Gates, Less 1QB Gates, and More I Gates = the cheapest gates. # The priority: less 2QB gates > less 1QB gates > more I gates N_2QB_gate, N_1QB_gate, N_I_gate = 0, 0, 0