Source code for qubiter.CktEmbedder

# from Controls import Controls


[docs]class CktEmbedder: """ This class stores parameters for embedding a quantum circuit within a larger circuit (one with more qubits). Note that we will use the word "bit" to mean either cbits or qbits. Attributes ---------- bit_map : list[int] 1-1 but not onto map of range(num_qbits_bef) into range(num_qbits_aft) extra_controls : Controls When embedding controls, these extra ones will be added to the before embedding controls num_qbits_aft : int number of qubits after circuit embedding num_qbits_bef : int number of qubits before circuit embedding """
[docs] def __init__(self, num_qbits_bef, num_qbits_aft, bit_map=None): """ Constructor Parameters ---------- num_qbits_bef : int num_qbits_aft : int Returns ------- """ self.num_qbits_bef = num_qbits_bef self.num_qbits_aft = num_qbits_aft assert num_qbits_bef <= num_qbits_aft if num_qbits_aft > num_qbits_bef: assert bit_map, "must give a bit_map" self.bit_map = bit_map from qubiter.Controls import Controls self.extra_controls = Controls(num_qbits_aft)
[docs] def get_num_new_bits(self): """ Returns num_qbits_aft - num_qbits_bef. Returns ------- int """ return self.num_qbits_aft - self.num_qbits_bef
[docs] def is_identity_map(self): """ Returns True (False) if bit_map is None (list). Returns ------- bool """ return self.bit_map is None
[docs] def aft(self, bef): """ Returns bit_map[bef] if bit_map is list. If bit_map is None, returns input 'bef' untouched. Parameters ---------- bef : int Returns ------- int """ if self.is_identity_map(): return bef else: # print("6666666", bef, self.bit_map) return self.bit_map[bef]
[docs] def is_old_bit(self, aft): """ Returns True if aft is in image of bit_map and False otherwise. Parameters ---------- aft : int Returns ------- bool """ if self.is_identity_map(): return True else: return aft in self.bit_map
[docs] @staticmethod def composition(emb2, emb1): """ Returns composite map emb2(emb1()). This entails defining a new CktEmbedder whose bit_map is the composition of the bit maps of the other two. Also, the extra controls of emb2 and emb1 must be merged and given to the composition. Parameters ---------- emb1 : CktEmbedder emb2 : CktEmbedder Returns ------- CktEmbedder """ if emb1.is_identity_map(): return emb2 if emb2.is_identity_map(): return emb1 assert emb1.num_qbits_aft == emb2.num_qbits_bef,\ "can't chain embedders" bit_map = [emb2.aft(emb1.aft(k)) for k in range(emb1.num_qbits_bef)] compo_emb = CktEmbedder( emb1.num_qbits_bef, emb2.num_qbits_aft, bit_map) # new_dict is an empty dictionary initially new_dict = compo_emb.extra_controls.bit_pos_to_kind # add after controls of emb2 new_dict.update(emb2.extra_controls.bit_pos_to_kind) # add after controls of emb1, after mapping them if emb1.extra_controls: old_dict = emb1.extra_controls.bit_pos_to_kind old_dict1 = {emb2.aft(bit): old_dict[bit] for bit in old_dict} new_dict.update(old_dict1) compo_emb.extra_controls.refresh_lists() return compo_emb
if __name__ == "__main__": def main(): print(5) main()