def use_MP_Y(self, tar_bit_pos, controls, rad_angles): """ This is an override of a function in the parent class EchoingSEO_reader. This is the only use_ function of this class that doesn't simply echo its input line. This function does most of its work inside the Multiplexor_SEO_writer.write() function that it calls. Parameters ---------- tar_bit_pos : int controls : Controls rad_angles : list[float] Returns ------- None """ # the flag eval_all_vars = False so should check this assert utg.all_floats(rad_angles) emb, nt, nf = self.emb_for_plexor(tar_bit_pos, controls) self.wr.emb = emb self.wr.rad_angles = rad_angles self.wr.num_T_trols = nt self.wr.num_F_trols = nf # style and num_gbits for wr are set by constructor self.wr.write() # revert to default embedder self.wr.emb = CktEmbedder(self.num_qbits, self.num_qbits)
def emb_for_plexor(self, tar_bit_pos, controls): """ This is an internal function used inside the function use_MP_Y(). The function returns emb, nt, nf to be used as arguments of a MultiplexorSEO_writer that will be used to expand the MP_y line currently being considered. emb is a circuit embedder, nt is the number of T bits and nf is the number of F bits detected in the input argument 'controls'. Parameters ---------- tar_bit_pos : int target bit position of multiplexor currently being considered. controls : Controls controls of the MP_Y currently being considered. Returns ------- CktEmbedder, int, int """ T_bpos = [] F_bpos = [] MP_bpos = [] for bpos, kind in controls.bit_pos_to_kind.items(): # bool is subclass of int # so isinstance(x, int) will be true if x is bool! if isinstance(kind, bool): if kind: T_bpos.append(bpos) else: F_bpos.append(bpos) else: MP_bpos.append(bpos) T_bpos.sort() F_bpos.sort() MP_bpos.sort() if self.gbit_list: g_bpos = self.gbit_list.sort() else: g_bpos = [] bit_map = T_bpos + F_bpos + MP_bpos + [tar_bit_pos] + g_bpos # print("bit_map", bit_map) assert len(bit_map) == len(set(bit_map)),\ "bits used to define multiplexor are not unique" assert len(bit_map) <= self.num_qbits nt = len(T_bpos) nf = len(F_bpos) emb = CktEmbedder(self.num_qbits, self.num_qbits, bit_map) return emb, nt, nf
def __init__(self, file_prefix, num_qbits, style, gbit_list=None, vars_manager=None, **kwargs): """ Constructor Parameters ---------- file_prefix : str num_qbits : int style : str gbit_list : list(int) vars_manager : PlaceholderManager Returns ------- """ self.gbit_list = gbit_list self.style = style if gbit_list: num_gbits = len(gbit_list) else: num_gbits = 0 # default embedder and rad_angles emb = CktEmbedder(num_qbits, num_qbits) rad_angles = None out_file_prefix = SEO_reader.xed_file_prefix(file_prefix) wr = MultiplexorSEO_writer(out_file_prefix, emb, style, rad_angles, num_gbits=num_gbits) # We set the flag eval_all_vars to False but check inside use_ method # that it has non-string arguments vman = PlaceholderManager(eval_all_vars=False) EchoingSEO_reader.__init__(self, file_prefix, num_qbits, wr, vars_manager=vman, **kwargs) self.wr.close_files()
def __init__(self, file_prefix, num_bits, c_to_tars, verbose=False): """ Constructor Parameters ---------- file_prefix : str file prefix of English file which is to be read to assemble a list of CNots used in the file. num_bits : int Number of qubits used in English file with file prefix `file_prefix`. IMP: We assume that c_to_tars refers to a chip with num_bits too. Both the English file and the chip must have the same number of qubits. This is no loss of generality. As long as the English file doesn't mention qubit positions >= num_bits, all you have to do to conform is to change the name of the English file so that it claims to pertain to num_bits qubits. c_to_tars : dict[int, list[int]] a dictionary mapping j in range(num_bits) to a list, possibly empty, of the physically allowed targets of qubit j, when j is the control of a CNOT. verbose : bool Returns ------- """ old_cnots = ChipCouplingsFitter.get_cnots_in_file( file_prefix, num_bits, verbose) self.bit_map = ChipCouplingsFitter.get_bit_map_from_c_to_tars( num_bits, old_cnots, c_to_tars, verbose) emb = CktEmbedder(num_bits, num_bits, self.bit_map) out_file_prefix = SEO_reader.xed_file_prefix(file_prefix) wr = SEO_writer(out_file_prefix, emb) EchoingSEO_reader(file_prefix, num_bits, wr)
def main(): num_qbits = 5 emb = CktEmbedder(num_qbits, num_qbits) trols = Controls(num_qbits) trols.bit_pos_to_kind = {3: True, 4: False} trols.refresh_lists() ang_rads = 30*np.pi/180 for ZL in [False, True]: wr = SEO_writer('wr_test', emb, ZL=ZL) wr.write_NOTA('zero bit last = ' + str(ZL)) wr.write_IF_M_beg(trols) wr.write_IF_M_end() wr.write_LOOP(10, 15) wr.write_NEXT(10) tar_bit_pos = 1 for kind in [0, 1, 2]: wr.write_MEAS(tar_bit_pos, kind) wr.write_PRINT('F2') wr.write_controlled_qbit_swap(0, 2, trols) wr.write_qbit_swap(1, 2) gate = OneQubitGate.phase_fac wr.write_controlled_one_qbit_gate(2, trols, gate, [ang_rads]) wr.write_global_phase_fac(30*np.pi/180) gate = OneQubitGate.P_0_phase_fac wr.write_controlled_one_qbit_gate(2, trols, gate, [ang_rads]) gate = OneQubitGate.P_1_phase_fac wr.write_controlled_one_qbit_gate(2, trols, gate, [ang_rads]) gate = OneQubitGate.sigx wr.write_controlled_one_qbit_gate(2, trols, gate) gate = OneQubitGate.sigy wr.write_controlled_one_qbit_gate(2, trols, gate) gate = OneQubitGate.sigz wr.write_controlled_one_qbit_gate(2, trols, gate) gate = OneQubitGate.had2 wr.write_controlled_one_qbit_gate(2, trols, gate) gate = OneQubitGate.rot_ax wr.write_controlled_one_qbit_gate(2, trols, gate, [ang_rads, 1]) gate = OneQubitGate.rot_ax wr.write_controlled_one_qbit_gate(2, trols, gate, [ang_rads, 2]) gate = OneQubitGate.rot_ax wr.write_controlled_one_qbit_gate(2, trols, gate, [ang_rads, 3]) gate = OneQubitGate.rot wr.write_controlled_one_qbit_gate(2, trols, gate, [ang_rads/3, ang_rads*2/3, ang_rads]) gate = OneQubitGate.sigx wr.write_one_qbit_gate(2, gate) wr.write_cnot(2, 1) tar_bit_pos = 0 trols1 = Controls(num_qbits) trols1.bit_pos_to_kind = {1: 0, 2: 1, 3: True, 4: False} trols1.refresh_lists() wr.write_controlled_multiplexor_gate(tar_bit_pos, trols1, [ang_rads/3, ang_rads*2/3, ang_rads, ang_rads*4/3]) trols2 = Controls(num_qbits) trols2.bit_pos_to_kind = {1: 0, 2: 1} trols2.refresh_lists() wr.write_multiplexor_gate(tar_bit_pos, trols2, [ang_rads/3, ang_rads*2/3, ang_rads, ang_rads*4/3]) wr.close_files()
def main(): num_bits_bef = 4 num_bits_aft = 5 bit_map = list(range(num_bits_bef)) emb = CktEmbedder(num_bits_bef, num_bits_aft, bit_map) # trol_kinds in ZL convention trol_kinds = [True, False, False] wr = CGateSEO_writer('cgate_expansions', emb, do_checking=True, verbose=False) u2_fun_to_fun_arg_list = co.OrderedDict( ((OneBitGates.P_0_phase_fac, [np.pi / 3]), (OneBitGates.P_1_phase_fac, [np.pi / 3]), (OneBitGates.sigx, None), (OneBitGates.sigy, None), (OneBitGates.sigz, None), (OneBitGates.had2, None), (OneBitGates.rot_ax, [np.pi / 3, 2]), (OneBitGates.rot, [np.pi / 3, np.pi / 6, np.pi / 3]))) for u2_fun, fun_arg_list in u2_fun_to_fun_arg_list.items(): wr.write_NOTA('--------new u2 gate --------------------------') for one_line in [True, False]: wr.one_line = one_line if one_line: wr.write(trol_kinds, u2_fun, fun_arg_list) else: for expand_1c_u2 in [False, True]: wr.expand_1c_u2 = expand_1c_u2 wr.write_NOTA('--------expand_1c_u2=' + str(expand_1c_u2)) print("\n", u2_fun, "one_line=", one_line, "expand=", expand_1c_u2) wr.write(trol_kinds, u2_fun, fun_arg_list) wr.close_files() # a check that an expansion multiplies to original num_bits = 5 emb = CktEmbedder(num_bits, num_bits) # trol_kinds in ZL convention trol_kinds = [True, False, False, False] file_prefix = 'cgate_expan_mat_prod' wr = CGateSEO_writer(file_prefix, emb) u2_fun = OneBitGates.rot_ax rads = np.pi / 3 wr.one_line = True wr.write_NOTA("one line=True-----------") wr.write(trol_kinds, u2_fun, [rads, 2]) wr.write_NOTA("herm. conj, one line=False-----------") wr.one_line = False wr.write(trol_kinds, u2_fun, [-rads, 2]) wr.close_files() mp = SEO_MatrixProduct(file_prefix, num_bits) id_mat = np.diag(np.ones((1 << num_bits, ))) err = np.linalg.norm(mp.prod_arr - id_mat) print("err=", err)