예제 #1
0
    def from_tuplelist(tuple_list):
        """
        Populates a Layout from a list containing virtual
        qubits---(QuantumRegister, int) tuples---, or None.

        Args:
            tuple_list (list):
                e.g.: [qr[0], None, qr[2], qr[3]]
        Returns:
            Layout: the corresponding Layout object
        Raises:
            LayoutError: If the elements are not (Register, integer) or None
        """
        out = Layout()
        for physical, virtual in enumerate(tuple_list):
            if virtual is None:
                continue
            elif Layout.is_virtual(virtual):
                if virtual in out._v2p:
                    raise LayoutError('Duplicate values not permitted; Layout is bijective.')
                out[virtual] = physical
            else:
                raise LayoutError("The list should contain elements of the form"
                                  " (Register, integer) or None")
        return out
예제 #2
0
    def generate_from_intlist(int_list, *qregs):
        """Converts a list of integers to a Layout
        mapping virtual qubits (index of the list) to
        physical qubits (the list values).

        Args:
            int_list (list): A list of integers.
            *qregs (QuantumRegisters): The quantum registers to apply
                the layout to.
        Returns:
            Layout: The corresponding Layout object.
        Raises:
            LayoutError: Invalid input layout.
        """
        # check for duplicate values in list
        if len(int_list) != len(set(int_list)):
            raise LayoutError(
                'Duplicate values not permitted in integer layout.')
        n_qubits = sum(reg.size for reg in qregs)
        # Check if list is too short to cover all qubits
        if len(int_list) < n_qubits:
            err_msg = 'Integer list length must equal number of qubits in circuit.'
            raise LayoutError(err_msg)
        out = Layout()
        main_idx = 0
        for qreg in qregs:
            for idx in range(qreg.size):
                out[(qreg, idx)] = int_list[main_idx]
                main_idx += 1
        if main_idx != len(int_list):
            for int_item in int_list[main_idx:]:
                out[int_item] = None
        return out
예제 #3
0
    def combine_into_edge_map(self, another_layout):
        """ Combines self and another_layout into an "edge map".

        For example::

              self       another_layout  resulting edge map
           qr_1 -> 0        0 <- q_2         qr_1 -> q_2
           qr_2 -> 2        2 <- q_1         qr_2 -> q_1
           qr_3 -> 3        3 <- q_0         qr_3 -> q_0

        The edge map is used to compose dags via, for example, compose_back.

        Args:
            another_layout (Layout): The other layout to combine.
        Returns:
            dict: A "edge map".
        Raises:
            LayoutError: another_layout can be bigger than self, but not smaller. Otherwise, raises.
        """
        edge_map = dict()

        for virtual, physical in self.get_virtual_bits().items():
            if physical not in another_layout._p2v:
                raise LayoutError(
                    'The wire_map_from_layouts() method does not support when the'
                    ' other layout (another_layout) is smaller.')
            edge_map[virtual] = another_layout[physical]

        return edge_map
예제 #4
0
 def __init__(self, input_dict=None):
     """construct a Layout from a bijective dictionary, mapping
     virtual qubits to physical qubits"""
     self._p2v = {}
     self._v2p = {}
     if input_dict is not None:
         if not isinstance(input_dict, dict):
             raise LayoutError("Layout constructor takes a dict")
         self.from_dict(input_dict)
예제 #5
0
 def __delitem__(self, key):
     if isinstance(key, int):
         del self._p2v[key]
         del self._v2p[self._p2v[key]]
     elif isinstance(key, tuple) and \
             len(key) == 2 and \
             isinstance(key[0], Register) and isinstance(key[1], int):
         del self._v2p[key]
         del self._p2v[self._v2p[key]]
     else:
         raise LayoutError('The key to remove should be of the form'
                           ' (Register, integer) or integer) and %s was provided' % (type(key),))
예제 #6
0
 def order_based_on_type(value1, value2):
     """decides which one is physical/virtual based on the type. Returns (virtual, physical)"""
     if isinstance(value1, int) and Layout.is_virtual(value2):
         physical = value1
         virtual = value2
     elif isinstance(value2, int) and Layout.is_virtual(value1):
         physical = value2
         virtual = value1
     else:
         raise LayoutError('The map (%s -> %s) has to be a ((Register, integer) -> integer)'
                           ' or the other way around.' % (type(value1), type(value2)))
     return virtual, physical
예제 #7
0
 def _checktype(thing):
     """Checks if thing is a valid type"""
     if thing is None:
         return
     if isinstance(thing, int):
         return
     if isinstance(thing, tuple) and \
             len(thing) == 2 and \
             isinstance(thing[0], Register) and isinstance(thing[1], int):
         return
     raise LayoutError(
         'The element %s should be a (Register, integer) tuple or an integer'
         % (thing, ))
예제 #8
0
 def swap(self, left, right):
     """Swaps the map between left and right.
     Args:
         left (tuple or int): Item to swap with right.
         right (tuple or int): Item to swap with left.
     Raises:
         LayoutError: If left and right have not the same type.
     """
     if type(left) is not type(right):
         raise LayoutError('The method swap only works with elements of the same type.')
     temp = self[left]
     self[left] = self[right]
     self[right] = temp
예제 #9
0
    def __setitem__(self, key, value):
        Layout._checktype(key)
        Layout._checktype(value)
        if isinstance(key, type(value)):
            raise LayoutError(
                'Key (%s) and value (%s) cannot have the same type' %
                (key, value))

        if key in self:
            del self[key]
        if value in self:
            del self[value]
        if key is not None:
            dict.__setitem__(self, key, value)
        if value is not None:
            dict.__setitem__(self, value, key)
예제 #10
0
 def set_length(self, amount_of_physical_bits):
     """
     Extends the layout length to `amount_of_physical_bits`.
     Args:
         amount_of_physical_bits (int): The amount of physical_qubits to
         set in the layout.
     Raises:
         LayoutError: If amount_of_physical_bits is used to reduced the
         length instead of extending it.
     """
     current_length = len(self)
     if amount_of_physical_bits < current_length:
         raise LayoutError(
             'Lenght setting cannot be smaller than the current amount of physical'
             ' (qu)bits.')
     for new_physical_bit in range(current_length, amount_of_physical_bits):
         self[new_physical_bit] = None
예제 #11
0
    def from_list(self, input_list):
        """
        Populates a Layout from a list.

        Args:
            input_list (list): For example,
            [(QuantumRegister(3, 'qr'), 0), None,
             (QuantumRegister(3, 'qr'), 2), (QuantumRegister(3, 'qr'), 3)]

        Raises:
            LayoutError: If the elements are not (Register, integer) or None
        """
        for physical, virtual in enumerate(input_list):
            if Layout.is_virtual(virtual):
                self._set_type_checked_item(virtual, physical)
            else:
                raise LayoutError(
                    "The list should contain elements of the form"
                    " (Register, integer) or None")