Esempio n. 1
0
    def __init__(self,
                 file_prefix,
                 emb,
                 style,
                 rad_angles=None,
                 num_T_trols=0,
                 num_F_trols=0,
                 num_gbits=0,
                 **kwargs):
        """
        Constructor

        Parameters
        ----------
        file_prefix : str
        emb : CktEmbedder
        style : str
        rad_angles : list(float)
        num_T_trols : int
        num_F_trols : int
        num_gbits : int
        kwargs : dict()

        Returns
        -------
        None

        """
        self.style = style
        self.rad_angles = rad_angles
        if rad_angles:
            self.rad_angles = ut.centered_rads1(rad_angles)
        self.num_T_trols = num_T_trols
        self.num_F_trols = num_F_trols
        self.num_gbits = 0
        if style == 'oracular':
            self.num_gbits = num_gbits

        num_bits = emb.num_bits_bef
        assert num_bits >= 2, "multiplexor must have at least 2 qubits"

        ntf = num_T_trols + num_F_trols
        num_MP_trols = num_bits - ntf - num_gbits - 1
        assert num_MP_trols > 0
        if rad_angles:
            assert len(rad_angles) == (1 << num_MP_trols), \
                "wrong  number of multiplexor angles"

        SEO_writer.__init__(self, file_prefix, emb, **kwargs)
Esempio n. 2
0
    def write_exact(self):
        """
        Writes in English file a multiple line, exact representation of the
        d-unitary.

        Returns
        -------
        None

        """
        num_bits = self.emb.num_bits_bef
        nt = self.num_T_trols
        nf = self.num_F_trols
        ntf = nt + nf
        num_MP_trols = num_bits - ntf - self.num_gbits
        rads_arr = np.array(ut.centered_rads1(self.rad_angles))
        if np.linalg.norm(rads_arr) < 1e-6:
            print("unit d-unitary")
            return

        conj_rads = HadamardTransform.ht(num_MP_trols, rads_arr)
        num_factors = (1 << num_MP_trols)
        f, lazy = BitVector.lazy_advance(0, 0)  # start at f=1
        cur_rot_bpos = 0
        prev_rot_bpos = 0
        cur_bvec = BitVector(num_MP_trols+1, 1)  # start at 1
        prev_bvec = BitVector(num_MP_trols+1, 0)
        diff_bvec = BitVector(num_MP_trols+1, 0)

        TF_dict = dict(enumerate([True]*nt + [False]*nf))
        trols1 = Controls(num_bits)
        trols1.bit_pos_to_kind = TF_dict.copy()
        trols1.refresh_lists()
        trols2 = Controls(num_bits)

        def write_cnots(diff_bvec1, init_prev_T_bit):
            prev_T_bit = init_prev_T_bit
            while True:
                cur_T_bit = diff_bvec1.find_T_bit_to_left_of(prev_T_bit)
                if cur_T_bit == -1:
                    break
                trols2.bit_pos_to_kind = TF_dict.copy()
                trols2.bit_pos_to_kind[cur_T_bit + ntf] = True
                trols2.refresh_lists()
                self.write_controlled_one_bit_gate(
                    ntf + init_prev_T_bit, trols2, OneBitGates.sigx)
                prev_T_bit = cur_T_bit

        norma = np.power(np.sqrt(2), num_MP_trols)
        # for first A factor, f = 0, just global phase
        # write conditioned global phase
        global_ph = conj_rads[0]*norma/len(conj_rads)
        if abs(global_ph) > 1e-6:
            self.write_controlled_one_bit_gate(ntf, trols1,
                    OneBitGates.phase_fac, [global_ph])

        while f < num_factors:
            cur_bvec.dec_rep = lazy
            # Since we have excluded f=0, f always has at least one T bit.
            cur_rot_bpos = cur_bvec.find_rightmost_T_bit()
            # print(cur_bvec.get_bit_string(), cur_rot_bpos)
            rads = ut.centered_rads(conj_rads[cur_bvec.dec_rep]/norma)
            if abs(rads) < 1e-6:
                pass
            else:
                # If cur_rot_bpos equals (doesn't equal) prev_rot_bpos,
                # then there is (isn't) cancellation between:
                # (1)the c-nots sigma_x(cur_rot_bpos)^n()
                # contributed by the right part of the current A factor
                # and
                # (2)the c-nots sigma_x(prev_rot_bpos)^n()
                # contributed by the left part of the previous A factor.

                if cur_rot_bpos == prev_rot_bpos:
                    diff_bvec = BitVector.new_with_T_on_diff(
                        cur_bvec, prev_bvec)
                    write_cnots(diff_bvec, cur_rot_bpos)
                else:
                    write_cnots(prev_bvec, prev_rot_bpos)
                    write_cnots(cur_bvec, cur_rot_bpos)
                    diff_bvec = BitVector.copy(cur_bvec)

                self.write_controlled_one_bit_gate(
                    ntf + cur_rot_bpos, trols1, OneBitGates.rot_ax, [rads, 3])
                prev_bvec = BitVector.copy(cur_bvec)
                prev_rot_bpos = cur_rot_bpos

            f, lazy = BitVector.lazy_advance(f, lazy)

        # Don't forget the leftmost c-nots
        write_cnots(prev_bvec, prev_rot_bpos)
Esempio n. 3
0
    def write_exact(self):
        """
        Writes in English file a multiple line, exact representation of the
        multiplexor.

        Returns
        -------
        None

        """
        num_bits = self.emb.num_bits_bef
        nt = self.num_T_trols
        nf = self.num_F_trols
        ntf = nt + nf
        num_MP_trols = num_bits - ntf - self.num_gbits - 1
        rads_arr = np.array(ut.centered_rads1(self.rad_angles))
        if np.linalg.norm(rads_arr) < 1e-6:
            print("unit multiplexor")
            return

        conj_rads = HadamardTransform.ht(num_MP_trols, rads_arr)
        num_factors = (1 << num_MP_trols)

        cur_bvec = BitVector(num_MP_trols+1, 0)  # start at zero
        prev_bvec = BitVector(num_MP_trols+1, 0)

        TF_dict = dict(enumerate([True]*nt + [False]*nf))
        trols1 = Controls(num_bits)
        trols1.bit_pos_to_kind = TF_dict.copy()
        trols1.refresh_lists()
        trols2 = Controls(num_bits)

        def write_cnots(diff_bvec):
            prev_T_bit = num_MP_trols
            while True:
                cur_T_bit = diff_bvec.find_T_bit_to_right_of(prev_T_bit)
                if cur_T_bit == -1:
                    break
                trols2.bit_pos_to_kind = TF_dict.copy()
                trols2.bit_pos_to_kind[cur_T_bit + ntf] = True
                trols2.refresh_lists()
                self.write_controlled_one_bit_gate(
                    ntf + num_MP_trols, trols2, OneBitGates.sigx)
                prev_T_bit = cur_T_bit

        norma = np.power(np.sqrt(2), num_MP_trols)
        f = 0
        lazy = 0
        while f < num_factors:
            rads = conj_rads[cur_bvec.dec_rep]/norma
            if abs(rads) < 1e-6:
                pass
            else:
                diff_bvec = BitVector.new_with_T_on_diff(cur_bvec, prev_bvec)
                write_cnots(diff_bvec)
                self.write_controlled_one_bit_gate(
                    ntf + num_MP_trols, trols1, OneBitGates.rot_ax, [rads, 2])
                prev_bvec = BitVector.copy(cur_bvec)
            f, lazy = BitVector.lazy_advance(f, lazy)
            cur_bvec.dec_rep = lazy

        # Don't forget the leftmost c-nots:
        diff_bvec = prev_bvec
        write_cnots(diff_bvec)