コード例 #1
0
    def pic_file_from_eng_file(file_prefix, num_qbits, ZL=True):
        """
        This function reads an English file with file prefix = file_prefix
        and it writes a Picture file for it with the same file prefix.

        Parameters
        ----------
        file_prefix : str
        num_qbits : int
        ZL : bool

        Returns
        -------
        None

        """
        end_str = '_' + str(num_qbits) + '_eng.txt'
        file_prefix_tempo = file_prefix + '_tempo'
        from shutil import copyfile
        copyfile(utg.preface(file_prefix + end_str),
                 utg.preface(file_prefix_tempo + end_str))

        emb = CktEmbedder(num_qbits, num_qbits)
        # English out file must different from English in file because one
        # can't read a file at the same time one is writing to it
        wr = SEO_writer(file_prefix, emb, ZL=ZL)
        vman = PlaceholderManager(eval_all_vars=False)
        EchoingSEO_reader(file_prefix_tempo, num_qbits, wr, vars_manager=vman)

        import os
        os.remove(utg.preface(file_prefix_tempo + end_str))
コード例 #2
0
    def main():
        file_prefix_in = 'echo_test'
        file_prefix_out = 'echo_test_perm'
        num_qbits = 6

        # permute qubits by advancing their positions by 1
        bit_map = [1, 2, 3, 4, 5, 0]
        emb = CktEmbedder(num_qbits, num_qbits, bit_map)
        wr = SEO_writer(file_prefix_out, emb)
        EchoingSEO_reader(file_prefix_in, num_qbits, wr)

        EchoingSEO_reader.pic_file_from_eng_file(file_prefix_in, num_qbits)
コード例 #3
0
    def main():
        # We begin by writing a simple circuit with 4 qubits. As usual,
        # the following code will write an English and a Picture file in the
        #  io_folder directory. Note that some rotation angles have been
        # entered into the write() Python functions as legal variable names
        # instead of floats. In the English file, you will see those legal
        # names where the numerical values of those angles would have been.

        num_bits = 4
        file_prefix = 'placeholder_test'
        emb = CktEmbedder(num_bits, num_bits)
        wr = SEO_writer(file_prefix, emb)
        wr.write_Rx(2, rads=np.pi/7)
        wr.write_Rx(1, rads='#2*.5')
        wr.write_Rx(1, rads='my_fun1#2')
        wr.write_Rn(3, rads_list=['#1', '-#1*3', '#3'])
        wr.write_Rx(1, rads='-my_fun2#2#1')
        wr.write_cnot(2, 3)
        wr.close_files()

        # Simply by creating an object of the class SEO_reader with the flag
        #  `write_log` set equal to True, you can create a log file which
        # contains
        # (1) a list of distinct variable numbers
        # (2) a list of distinct function names
        # encountered in the English file
        SEO_reader(file_prefix, num_bits, write_log=True)

        def my_fun1(x):
            return x*.5

        def my_fun2(x, y):
            return x + y

        # partial substitution, this creates new files
        # with #1=30, #2=60, 'my_fun1'->my_fun1,
        # but #3  and 'my_fun2' still undecided
        vman = PlaceholderManager(eval_all_vars=False,
                    var_num_to_rads={1: np.pi/6, 2: np.pi/3},
                    fun_name_to_fun={'my_fun1': my_fun1})
        wr = SEO_writer(file_prefix + '_eval01', emb)
        EchoingSEO_reader(file_prefix, num_bits, wr,
                          vars_manager=vman)

        # this runs the simulator after substituting
        # #1=30, #2=60, #3=90, 'my_fun1'->my_fun1, 'my_fun2'->my_fun2
        vman = PlaceholderManager(
            var_num_to_rads={1: np.pi/6, 2: np.pi/3, 3: np.pi/2},
            fun_name_to_fun={'my_fun1': my_fun1, 'my_fun2': my_fun2}
        )
        sim = SEO_simulator(file_prefix, num_bits, verbose=True,
                            vars_manager=vman)
        print("\n----------------------------------------")
        StateVec.describe_st_vec_dict(sim.cur_st_vec_dict)
コード例 #4
0
class Qubiter_to_AnyQasm(SEO_reader):
    """
    This abstract class is a child of SEO_reader. It reads an input English
    file and writes an AnyQasm file that is a translation of the input
    English file into the AnyQasm language. If the flag write_qubiter_files
    is set to True, this class will also write new English and Picture files
    that are in 1-1 onto line correspondence with the output AnyQasm file.

    Footnote: Some AnyQasm's distinguish between quantum registers qreg and
    classical registers creg. Qubiter does not use cregs because it uses the
    classical memory of your Linux PC instead. AnyQasm has an intricate set
    of commands for measurements. Qubiter has a complete set of measurement
    commands too (see MEAS in Rosetta stone). The AnyQasm and Qubiter
    measurement commands can obviously be translated into each other. We
    leave that part of the translation to a future version of this class.

    This class can run in either a strict or a non-strict mode depending on
    the flag `strict_mode`, which equals False in default mode. In the
    strict mode, the set of gates allowed is constrained to a small but
    universal set that is specified below, and that is allowed in any target
    qasm. In the non-strict mode, more gates are allowed that depend on
    specific target qasm. In the strict mode, the program will end if you
    try to use gates that are not allowed. In the non-strict mode,
    the program will end if you try to use gates for a target language that
    have not been implemented yet in the Qubiter class targeting that
    language, often because the target language doesn't support those gates.
    
    Will refer to target qasm as AnyQasm or aqasm

    Next we give a description of the strict_mode:

    In the strict mode, the input English file that is read can only have
    lines of the following types or else the program will abort with an
    error message:

    1. single qubit rotations (HAD2, SIGX, SIGY, SIGZ, ROTX, ROTY,
    ROTZ or ROTN with no controls)

    2. simple CNOTs (SIGX with a single True control). Call them c->t=(
    c, t) if c is the control and t the target. (c, t) must be allowed
    by 'c_to_tars'.

    3. NOTA or PRINT lines. PRINT lines are commented out.

    If you have an English file that contains lines that are more
    complicated than this (because, for example, they contain rotations with
    one or more controls attached, or because a CNOT is not allowed
    according to 'c_to_tars'), you can use the expander classes
    CGateExpander, DiagUnitaryExpander, MultiplexorExpander,
    and ForbiddenCNotExpander to expand the circuit to an equivalent albeit
    longer circuit that satisfies constraints 1, 2, 3.

    This class can handle a chip with any number of qubits.

    This class halts execution if it encounters a CNOT that is disallowed
    according to the input 'c_to_tars'. 'c_to_tars' varies with chip. Some
    'c_to_tars's are listed in the files 'chip_couplings_...' found in same
    folder as this file. If c_to_tars = None, the class assumes any CNOT is
    possible.


    Attributes
    ----------
    all_fun_names : list[str]
        a list of all the distinct function names encountered in circuit
    all_var_nums : list[int]
        a list of all distinct numbers of the variables encountered in circuit
    aqasm_name : str
        the name of the aqasm language, for example, IBMqasm. Used as ending
        of file name, between '_' and '.txt'
    aqasm_path : str
        path to aqasm file
    aqasm_out : _io.TextIOWrapper
        This output stream is used to write an aqasm file based on the input
        English file.
    c_to_tars : dict[int, list[int]]
        a dictionary mapping j in range(num_qbits) to a list, possibly empty,
        of the physically allowed targets of qubit j, when j is the control
        of a CNOT. If c_to_tars = None, the class assumes any CNOT is
        possible.
    file_prefix : str
    num_qbits : int
    qbtr_wr : SEO_writer
        A SEO_writer object created iff write_qubiter_files is True.
    strict_mode : bool
    vprefix : str
        all variables in aqasm file will be called vprefix + an int
    write_qubiter_files : bool
        The class always writes an AnyQasm text file based on the input
        English file that is read. Iff this is True, the class also writes
        English and Picture files in 1-1 line correspondence with the output
        AnyQasm file


    """
    def __init__(self,
                 file_prefix,
                 num_qbits,
                 aqasm_name='',
                 strict_mode=False,
                 c_to_tars=None,
                 write_qubiter_files=False,
                 vars_manager=None,
                 aqasm_ftype='txt',
                 prelude_str=None,
                 ending_str=None,
                 **kwargs):
        """
        Constructor

        Parameters
        ----------
        file_prefix : str
        num_qbits : int
        aqasm_name : str
        strict_mode : bool
        c_to_tars : dict[int, list[int]]|None
        write_qubiter_files : bool
        vars_manager : PlaceholderManager
        aqasm_ftype : str
            file type of output aqasm file. If this equals 'txt', name of
            aqasm file will end in '.txt'
        prelude_str : str | None
            string to write as prelude to aqasm file. If None, then the
            override method of self.write_prelude() is called
        ending_str : str | None
            string to write as ending to aqasm file. If None, then the
            override method of self.write_ending() is called

        Returns
        -------

        """
        self.file_prefix = file_prefix
        self.num_qbits = num_qbits

        vman = PlaceholderManager(eval_all_vars=False)
        rdr = SEO_reader(file_prefix,
                         num_qbits,
                         vars_manager=vman,
                         write_log=True)
        self.all_var_nums = rdr.vars_manager.all_var_nums
        self.all_fun_names = rdr.vars_manager.all_fun_names

        self.aqasm_name = aqasm_name
        self.strict_mode = strict_mode
        self.vprefix = 'rads'
        self.c_to_tars = c_to_tars
        self.write_qubiter_files = write_qubiter_files

        self.aqasm_path = file_prefix +\
                          '_' + aqasm_name + '.' + aqasm_ftype
        self.aqasm_out = open(utg.preface(self.aqasm_path), 'wt')

        self.qbtr_wr = None
        if write_qubiter_files:
            emb = CktEmbedder(num_qbits, num_qbits)
            out_file_prefix = SEO_reader.xed_file_prefix(file_prefix)
            self.qbtr_wr = SEO_writer(out_file_prefix, emb)

        if prelude_str is not None:
            self.write(prelude_str)
        else:
            self.write_prelude()

        vman1 = PlaceholderManager(eval_all_vars=False)
        SEO_reader.__init__(self,
                            file_prefix,
                            num_qbits,
                            vars_manager=vman1,
                            **kwargs)

        if ending_str is not None:
            self.write(ending_str)
        else:
            self.write_ending()

        self.aqasm_out.close()
        if write_qubiter_files:
            self.qbtr_wr.close_files()

    def write(self, s):
        """
        Writes string s to aqasm and qubiter out files.

        Parameters
        ----------
        s : str

        Returns
        -------
        None

        """
        self.aqasm_out.write(s + '\n')

        if self.write_qubiter_files:
            lines = s.split('\n')
            for line in lines:
                self.qbtr_wr.write_NOTA(line)

    def write_prelude(self):
        """
        Abstract function, writes AnyQasm's opening statements before calls
        to use_ methods for gates.

        Returns
        -------
        None

        """

        assert False

    def write_ending(self):
        """
        Abstract function, writes AnyQasm's ending statements after calls to
        use_ methods for gates.

        Returns
        -------
        None

        """
        assert False

    def new_var_name(self, var_name, coda='', strict=False):
        """
        Starts by asserting that var_name is a legal variable name.

        If var_name is not functional, this method replaces # in var_name by
        self.vprefix and adds coda to end of string.  For example,
        if self.vprefix='rads' and var_name='-#2*.5", then output is
        '-rads2*.5' + coda

        If var_name is functional, this method replaces each # in var_name
        by self.vprefix, adds commas and parenthesis, and adds coda to end
        of string. For example, if self.vprefix='rads' and
        var_name='-fun#1#2', then output is '-fun(rads1, rads2)' + coda

        The above applies only if strict=False. In the strict mode, only an
        empty coda is allowed for functional placeholders. For
        non-functional placeholders, if var_name contains an *, then the str
        after the * and the coda are merged using eval().

        Parameters
        ----------
        var_name : str
        coda : str
        strict : bool

        Returns
        -------
        str

        """
        assert PlaceholderManager.is_legal_var_name(var_name)
        if not PlaceholderManager.is_functional_var(var_name):
            new_coda = coda
            if coda:
                assert len(coda) > 1, "illegal coda: " + coda
            star_pos = var_name.find("*")
            if strict and star_pos != -1 and coda:
                assert coda[0] == '*', "A coda must start with * " +\
                    "in strict mode. Got coda: " + coda
                fac1 = var_name[star_pos + 1:]
                fac2 = coda[1:]
                fac12 = fac1 + '*' + fac2
                try:
                    new_coda = '*' + str(eval(fac12))
                except:
                    assert False, 'cannot eval "' +\
                                  fac12 + '" to merge "' +\
                            var_name + '" and "' + coda + '"'
            end_pos = len(var_name)
            if strict and star_pos != -1:
                end_pos = star_pos

            if var_name[0] == "#":
                return self.vprefix + var_name[1:end_pos] + new_coda
            else:  # starts with -#
                return "-" + self.vprefix + var_name[2:end_pos] + new_coda

        else:
            if strict:
                assert not coda, "functional placeholders cannot " +\
                    'have scaling factors in strict mode'
            first_hash_pos = var_name.find('#')
            nums_strings = var_name[first_hash_pos + 1:].split('#')
            arg_str = '('
            for num_str in nums_strings:
                arg_str += self.vprefix + num_str + ', '
            arg_str = arg_str[:-2] + ')'
            return var_name[:first_hash_pos] + arg_str + coda

    def print_aqasm_file(self):
        """
        Prints aqasm file created by constructor.

        Returns
        -------

        """
        with open(utg.preface(self.aqasm_path)) as f:
            print(f.read())
コード例 #5
0
    def __init__(self,
                 file_prefix,
                 num_qbits,
                 aqasm_name='',
                 strict_mode=False,
                 c_to_tars=None,
                 write_qubiter_files=False,
                 vars_manager=None,
                 aqasm_ftype='txt',
                 prelude_str=None,
                 ending_str=None,
                 **kwargs):
        """
        Constructor

        Parameters
        ----------
        file_prefix : str
        num_qbits : int
        aqasm_name : str
        strict_mode : bool
        c_to_tars : dict[int, list[int]]|None
        write_qubiter_files : bool
        vars_manager : PlaceholderManager
        aqasm_ftype : str
            file type of output aqasm file. If this equals 'txt', name of
            aqasm file will end in '.txt'
        prelude_str : str | None
            string to write as prelude to aqasm file. If None, then the
            override method of self.write_prelude() is called
        ending_str : str | None
            string to write as ending to aqasm file. If None, then the
            override method of self.write_ending() is called

        Returns
        -------

        """
        self.file_prefix = file_prefix
        self.num_qbits = num_qbits

        vman = PlaceholderManager(eval_all_vars=False)
        rdr = SEO_reader(file_prefix,
                         num_qbits,
                         vars_manager=vman,
                         write_log=True)
        self.all_var_nums = rdr.vars_manager.all_var_nums
        self.all_fun_names = rdr.vars_manager.all_fun_names

        self.aqasm_name = aqasm_name
        self.strict_mode = strict_mode
        self.vprefix = 'rads'
        self.c_to_tars = c_to_tars
        self.write_qubiter_files = write_qubiter_files

        self.aqasm_path = file_prefix +\
                          '_' + aqasm_name + '.' + aqasm_ftype
        self.aqasm_out = open(utg.preface(self.aqasm_path), 'wt')

        self.qbtr_wr = None
        if write_qubiter_files:
            emb = CktEmbedder(num_qbits, num_qbits)
            out_file_prefix = SEO_reader.xed_file_prefix(file_prefix)
            self.qbtr_wr = SEO_writer(out_file_prefix, emb)

        if prelude_str is not None:
            self.write(prelude_str)
        else:
            self.write_prelude()

        vman1 = PlaceholderManager(eval_all_vars=False)
        SEO_reader.__init__(self,
                            file_prefix,
                            num_qbits,
                            vars_manager=vman1,
                            **kwargs)

        if ending_str is not None:
            self.write(ending_str)
        else:
            self.write_ending()

        self.aqasm_out.close()
        if write_qubiter_files:
            self.qbtr_wr.close_files()
コード例 #6
0
    def main():
        file_prefix = 'loop_gen_test'
        num_qbits = 4

        # write the English and Picture files
        emb = CktEmbedder(num_qbits, num_qbits)
        wr = SEO_writer(file_prefix, emb)
        wr.write_controlled_one_qbit_gate(
            0, Controls.new_single_trol(num_qbits, 2, False),
            OneQubitGate.rot_ax, ['#1', 1])
        wr.write_LOOP(20, nreps=2)
        wr.write_controlled_one_qbit_gate(
            1, Controls.new_single_trol(num_qbits, 2, False),
            OneQubitGate.rot_ax, ['-my_fun1#1#2', 2])
        wr.write_LOOP(10, nreps=4)
        wr.write_controlled_one_qbit_gate(
            2, Controls.new_single_trol(num_qbits, 3, True), OneQubitGate.rot,
            ['-#1*.5', '#2', '-my_fun3#3'])
        wr.write_NEXT(10)
        wr.write_controlled_one_qbit_gate(
            1, Controls.new_single_trol(num_qbits, 2, False),
            OneQubitGate.rot_ax, ['my_fun1#1#2', 2])
        wr.write_NEXT(20)
        wr.write_controlled_one_qbit_gate(
            0, Controls.new_single_trol(num_qbits, 2, False),
            OneQubitGate.rot_ax, ['#1*.3', 1])
        wr.write_one_qbit_gate(1, OneQubitGate.rot_ax, ['my_fun#1', 1])
        wr.close_files()

        # write a log
        SEO_reader(file_prefix, num_qbits, write_log=True)

        # write a Loop File
        LoopFileGenerator(file_prefix, num_qbits)

        # read a Loop xfile and do simulation
        sim = SEO_simulator(file_prefix, num_qbits, verbose=False, xfile_num=1)
        print("\n----------------------------------------")
        StateVec.describe_st_vec_dict(sim.cur_st_vec_dict)