Skip to content

Commit

Permalink
Merge pull request #236 from mahdiehmalekian/zephyr_layout_coords_fix
Browse files Browse the repository at this point in the history
Zephyr layout coords fix
  • Loading branch information
randomir authored Nov 20, 2024
2 parents 57e3b5e + e0ccc6f commit 1631006
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 5 deletions.
20 changes: 18 additions & 2 deletions dwave_networkx/drawing/pegasus_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
"""
Tools to visualize :term:`Pegasus` lattices and weighted :term:`graph` problems on them.
"""

import networkx as nx
from networkx import draw
import numpy as np

from dwave_networkx.drawing.qubit_layout import draw_qubit_graph, draw_embedding, draw_yield
from dwave_networkx.generators.pegasus import pegasus_graph, pegasus_coordinates
Expand Down Expand Up @@ -91,6 +91,22 @@ def xy_coords(t, y, x, u, k):
coord = pegasus_coordinates(m)
pos = {v: xy_coords(*coord.linear_to_pegasus(v)) for v in G.nodes()}

if center is None:
center = np.zeros(dim)
else:
center = np.asarray(center)

pos_arr = np.array([(pos[v]-center)[:2] for v in G.nodes()])
min_x, min_y = np.min(pos_arr, axis=0)
max_x, max_y = np.max(pos_arr, axis=0)
scale_x = max_x - min_x
scale_y = max_y - min_y
pos_arr = pos_arr - np.array([min_x , max_y]) # shift to make (0, 0) the top left corner
pos_arr = pos_arr * np.array([1/scale_x, 1/scale_y]) # scale to make (1, -1) the bottom right corner
paddims = dim - 2
zeros = np.zeros((pos_arr.shape[0], paddims))
pos_arr = np.hstack((pos_arr*np.array([scale, scale]), zeros)) + center
pos = {v: pos_arr[i] for i, v in enumerate(G.nodes())}
return pos


Expand Down Expand Up @@ -320,4 +336,4 @@ def draw_pegasus_yield(G, **kwargs):

perfect_graph = pegasus_graph(m, offset_lists=offset_lists, coordinates=coordinates, nice_coordinates=nice)

draw_yield(G, pegasus_layout(perfect_graph), perfect_graph, **kwargs)
draw_yield(G, pegasus_layout(perfect_graph), perfect_graph, **kwargs)
21 changes: 18 additions & 3 deletions dwave_networkx/drawing/zephyr_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import networkx as nx
from networkx import draw
import numpy as np

from dwave_networkx.drawing.qubit_layout import draw_qubit_graph, draw_embedding, draw_yield
from dwave_networkx.generators.zephyr import zephyr_graph, zephyr_coordinates
Expand Down Expand Up @@ -78,7 +79,24 @@ def zephyr_layout(G, scale=1., center=None, dim=2):
t = G.graph.get('tile')
coord = zephyr_coordinates(m, t)
pos = {v: xy_coords(*coord.linear_to_zephyr(v)) for v in G.nodes()}

if center is None:
center = np.zeros(dim)
else:
center = np.asarray(center)

pos_arr = np.array([(pos[v]-center)[:2] for v in G.nodes()])
min_x, min_y = np.min(pos_arr, axis=0)
max_x, max_y = np.max(pos_arr, axis=0)
scale_x = max_x - min_x
scale_y = max_y - min_y
pos_arr = pos_arr - np.array([min_x , max_y]) # shift to make (0, 0) the top left corner
pos_arr = pos_arr * np.array([1/scale_x, 1/scale_y]) # scale to make (1, -1) the bottom right corner
paddims = dim - 2
zeros = np.zeros((pos_arr.shape[0], paddims))
pos_arr = np.hstack((pos_arr*np.array([scale, scale]), zeros)) + center
pos = {v: pos_arr[i] for i, v in enumerate(G.nodes())}

return pos


Expand Down Expand Up @@ -109,7 +127,6 @@ def zephyr_node_placer_2d(G, scale=1., center=None, dim=2):
Zephyr lattice to plottable x- and y-coordinates.
"""
import numpy as np

m = G.graph.get('rows')
tile_width = G.graph.get("tile")
Expand Down Expand Up @@ -139,9 +156,7 @@ def _xy_coords(u, w, k, j, z):
else:
xy = np.array([W, -Z])


return np.hstack((xy * scale, np.zeros(paddims))) + center

return _xy_coords


Expand Down
32 changes: 32 additions & 0 deletions tests/test_pegasus_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,38 @@ def test_pegasus_layout_ints_noinfo(self):
with self.assertRaises(ValueError):
pos = dnx.pegasus_layout(badG)

def test_pegasus_layout_xrange_typical(self):
G = dnx.pegasus_graph(2)
pos = dnx.pegasus_layout(G)
x_coords = [val[0] for val in pos.values()]
min_x, max_x = min(x_coords), max(x_coords)
self.assertAlmostEqual(min_x, 0, delta=1e-5, msg="min_x should be approximately 0")
self.assertAlmostEqual(max_x, 1, delta=1e-5, msg="max_x should be approximately 1")

def test_pegasus_layout_yrange_typical(self):
G = dnx.pegasus_graph(2)
pos = dnx.pegasus_layout(G)
y_coords = [val[1] for val in pos.values()]
min_y, max_y = min(y_coords), max(y_coords)
self.assertAlmostEqual(min_y, -1, delta=1e-5, msg="min_y should be approximately -1")
self.assertAlmostEqual(max_y, 0, delta=1e-5, msg="max_y should be approximately 0")

def test_pegasus_layout_xrange(self):
G = dnx.pegasus_graph(2)
pos = dnx.pegasus_layout(G, scale=5)
x_coords = [val[0] for val in pos.values()]
min_x, max_x = min(x_coords), max(x_coords)
self.assertAlmostEqual(min_x, 0, delta=1e-5, msg="min_x should be approximately 0")
self.assertAlmostEqual(max_x, 5, delta=1e-5, msg="max_x should be approximately 5")

def test_pegasus_layout_yrange(self):
G = dnx.pegasus_graph(2)
pos = dnx.pegasus_layout(G, scale=5)
y_coords = [val[1] for val in pos.values()]
min_y, max_y = min(y_coords), max(y_coords)
self.assertAlmostEqual(min_y, -5, delta=1e-5, msg="min_y should be approximately -5")
self.assertAlmostEqual(max_y, 0, delta=1e-5, msg="max_y should be approximately 0")

@unittest.skipUnless(_display, " No display found")
def test_draw_pegasus_yield(self):
G = dnx.pegasus_graph(3, data=False)
Expand Down
32 changes: 32 additions & 0 deletions tests/test_zephyr_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,38 @@ def test_zephyr_layout_coords(self):
def test_zephyr_layout_nodata(self):
G = dnx.zephyr_graph(2, 4, data=False)
pos = dnx.zephyr_layout(G)

def test_zephyr_layout_xrange_typical(self):
G = dnx.zephyr_graph(2, 4)
pos = dnx.zephyr_layout(G)
x_coords = [val[0] for val in pos.values()]
min_x, max_x = min(x_coords), max(x_coords)
self.assertAlmostEqual(min_x, 0, delta=1e-5, msg="min_x should be approximately 0")
self.assertAlmostEqual(max_x, 1, delta=1e-5, msg="max_x should be approximately 1")

def test_zephyr_layout_yrange_typical(self):
G = dnx.zephyr_graph(2, 4)
pos = dnx.zephyr_layout(G)
y_coords = [val[1] for val in pos.values()]
min_y, max_y = min(y_coords), max(y_coords)
self.assertAlmostEqual(min_y, -1, delta=1e-5, msg="min_y should be approximately -1")
self.assertAlmostEqual(max_y, 0, delta=1e-5, msg="max_y should be approximately 0")

def test_zephyr_layout_xrange(self):
G = dnx.zephyr_graph(2, 4)
pos = dnx.zephyr_layout(G, scale=10)
x_coords = [val[0] for val in pos.values()]
min_x, max_x = min(x_coords), max(x_coords)
self.assertAlmostEqual(min_x, 0, delta=1e-5, msg="min_x should be approximately 0")
self.assertAlmostEqual(max_x, 10, delta=1e-5, msg="max_x should be approximately 10")

def test_zephyr_layout_yrange(self):
G = dnx.zephyr_graph(2, 4)
pos = dnx.zephyr_layout(G, scale=10)
y_coords = [val[1] for val in pos.values()]
min_y, max_y = min(y_coords), max(y_coords)
self.assertAlmostEqual(min_y, -10, delta=1e-5, msg="min_y should be approximately -10")
self.assertAlmostEqual(max_y, 0, delta=1e-5, msg="max_y should be approximately 0")

@unittest.skipUnless(_display, " No display found")
def test_draw_zephyr_yield(self):
Expand Down

0 comments on commit 1631006

Please sign in to comment.