Example #1
0
def spread_out(T, embedding, sheer=None):
    """ Transform the tile assignment to spread out the embedding starting from
        tile (0,0) and placing originally adjacent tiles 1 extra tile away.

        Optional arguments:

            sheer: {None,0, 1}
                Perform a translation of every odd column (sheer=0) or row
                (sheer=1)

        Example:
            >>> import embera
            >>> import networkx as nx
            >>> import dwave_networkx as dnx
            >>> S = nx.complete_graph(17)
            >>> T = dnx.chimera_graph(8)
            >>> embedding = minorminer.find_embedding(S,T)
            >>> dnx.draw_chimera_embedding(T,embedding, node_size=10)
            >>> new_embedding = embera.transform.embedding.spread_out(T,embedding)
            >>> dnx.draw_chimera_embedding(T,new_embedding,node_size=10)
    """
    tiling = DWaveNetworkXTiling(T)
    shape = np.array(tiling.shape)
    # Initialize edges
    origin = shape
    end = (0, ) * len(origin)
    # Find edges
    for v, chain in embedding.items():
        for q in chain:
            tile = np.array(tiling.get_tile(q))
            origin = [min(t, o) for t, o in zip(tile, origin)]
            end = [max(t, e) for t, e in zip(tile, end)]
    # Make sure it fits
    if tuple((np.array(end) - np.array(origin)) * 2) > tiling.shape:
        raise RuntimeError("Can't spread out")
    # Spread out all qubits by chain
    new_embedding = {}
    if sheer is None:
        shift = lambda tile, origin: (tile - origin) * 2
    elif sheer == 0:
        shift = lambda tile, origin: (tile - origin) * 2 + np.flip(
            (tile - origin) % [2, 1])
    elif sheer == 1:
        shift = lambda tile, origin: (tile - origin) * 2 + np.flip(
            (tile - origin) % [1, 2])

    for v, chain in embedding.items():
        new_chain = []
        for q in chain:
            tile = np.array(tiling.get_tile(q))
            new_tile = tuple(shift(tile, origin))
            new_q = tiling.set_tile(q, new_tile)
            new_chain.append(new_q)
        new_embedding[v] = new_chain

    return new_embedding
Example #2
0
def open_seam(T, embedding, seam, direction):
    """
        Arguments (continued):
            seam: (int)
                If direction is 'left' or 'right', seam corresponds to the
                column number. If direction is 'up' or 'down', seam corresponds
                to the row number.

            direction: (None or str:{'left','right','up','down'})
                Given a seam index, that column/row is cleared and all utilized
                qubits in the embedding are shifted in this direction.

        Example:
            >>> import embera
            >>> import networkx as nx
            >>> import dwave_networkx as dnx
            >>> S = nx.complete_graph(10)
            >>> T = dnx.chimera_graph(8)
            >>> embedding = minorminer.find_embedding(S,T,random_seed=10)
            >>> dnx.draw_chimera_embedding(T,embedding,node_size=10)
            >>> seam = 2
            >>> direction = 'right'
            >>> new_embedding = embera.transform.embedding.open_seam(T,embedding,seam,direction)
            >>> dnx.draw_chimera_embedding(T,new_embedding,node_size=10)
    """
    tiling = DWaveNetworkXTiling(T)

    if direction is 'left':
        shift = lambda tile: tile[1] <= seam
        offset = np.array([0, -1])
    elif direction is 'right':
        shift = lambda tile: tile[1] >= seam
        offset = np.array([0, +1])
    elif direction is 'up':
        shift = lambda tile: tile[0] <= seam
        offset = np.array([-1, 0])
    elif direction is 'down':
        shift = lambda tile: tile[0] >= seam
        offset = np.array([+1, 0])
    else:
        raise ValueError("Direction not in {'left','right','up','down'}")

    new_embedding = {}
    for v, chain in embedding.items():
        new_chain = []
        for q in chain:
            tile = np.array(tiling.get_tile(q))
            new_tile = tuple(tile + offset) if shift(tile) else tuple(tile)
            new_q = tiling.set_tile(q, new_tile)
            new_chain.append(new_q)
        new_embedding[v] = new_chain

    return new_embedding
Example #3
0
def translate(T, embedding, origin=(0, 0)):
    """ Transport the embedding on the same graph to re-distribute qubit
        assignments.

        Optional arguments:
            origin: (tuple)
                A tuple of tile coordinates pointing to where the left-uppermost
                occupied tile in the embedding should move to. All other tiles
                are moved relative to the origin.

        Example:
            >>> import embera
            >>> import networkx as nx
            >>> import dwave_networkx as dnx
            >>> S = nx.complete_graph(11)
            >>> T = dnx.chimera_graph(7)
            >>> embedding = minorminer.find_embedding(S,T)
            >>> dnx.draw_chimera_embedding(T,embedding,node_size=10)
            >>> origin = (2,3)
            >>> new_embedding = embera.transform.embedding.translate(T,embedding,origin)
            >>> dnx.draw_chimera_embedding(T,new_embedding,node_size=10)
    """
    tiling = DWaveNetworkXTiling(T)
    shape = tiling.shape
    # Initialize offset
    offset = shape
    # Find margins
    for v, chain in embedding.items():
        for q in chain:
            tile = np.array(tiling.get_tile(q))
            offset = [min(t, o) for t, o in zip(tile, offset)]
    # Define flips
    m, n = tiling.shape
    t = tiling.graph['tile']
    new_embedding = {}
    for v, chain in embedding.items():
        new_chain = []
        for q in chain:
            k = tiling.get_k(q)
            tile = tiling.get_tile(q)
            shore = tiling.get_shore(q)
            new_tile = tuple(
                np.array(tile) - np.array(offset) + np.array(origin))
            new_q = tiling.set_tile(q, new_tile)
            new_chain.append(new_q)
        new_embedding[v] = new_chain

    return new_embedding
Example #4
0
def iter_sliding_window(T, embedding):
    """ Use a sliding window approach to iteratively transport the embedding
        from one region of the Chimera graph to another.

        Example:
            >>> import embera
            >>> import networkx as nx
            >>> import dwave_networkx as dnx
            >>> import matplotlib.pyplot as plt
            >>> S = nx.complete_graph(11)
            >>> T = dnx.chimera_graph(7)
            >>> embedding = minorminer.find_embedding(S,T)
            >>> dnx.draw_chimera_embedding(T,embedding,node_size=10)
            >>> slide = embera.transform.embedding.sliding_window(T,embedding)
            >>> for new_embedding in slide:
            ...     dnx.draw_chimera_embedding(T,new_embedding,node_size=10)
            ...     plt.pause(0.2)
    """
    tiling = DWaveNetworkXTiling(T)
    shape = np.array(tiling.shape)
    # Initialize edges
    origin = shape
    end = (0, ) * len(origin)
    # Find edges
    for v, chain in embedding.items():
        for q in chain:
            tile = np.array(tiling.get_tile(q))
            origin = [min(t, o) for t, o in zip(tile, origin)]
            end = [max(t, e) for t, e in zip(tile, end)]

    # Move tiles to origin and translate to try and find valid embedding
    size = np.array(end) - np.array(origin)
    interactions = lambda u, v, E: ((s, t) for s in E[u] for t in E[v])
    is_connected = lambda edges: any(T.has_edge(s, t) for s, t in edges)
    for x in range(shape[1] - size[1]):
        for y in range(shape[0] - size[0]):
            slide = {}
            offset = np.array([x, y])
            # Translate all qubits
            for v, chain in embedding.items():
                new_chain = []
                for q in chain:
                    tile = np.array(tiling.get_tile(q))
                    new_tile = tuple(tile - np.array(origin) + offset)
                    new_q = tiling.set_tile(q, new_tile)
                    new_chain.append(new_q)
                slide[v] = new_chain
            yield slide