def test_remove_nodes_retain_edges_single_edge(self): dag = retworkx.PyDAG() node_a = dag.add_node("a") node_b = dag.add_child(node_a, "b", "Edgy") node_c = dag.add_child(node_b, "c", "Edgy_mk2") dag.remove_node_retain_edges(node_b) res = dag.nodes() self.assertEqual(["a", "c"], res) self.assertEqual([0, 2], dag.node_indexes()) self.assertTrue(dag.has_edge(node_a, node_c)) self.assertEqual(dag.get_all_edge_data(node_a, node_c), ["Edgy"])
def test_remove_nodes_retain_edges_single_edge_outgoing_weight(self): dag = retworkx.PyDAG() node_a = dag.add_node('a') node_b = dag.add_child(node_a, 'b', "Edgy") node_c = dag.add_child(node_b, 'c', "Edgy_mk2") dag.remove_node_retain_edges(node_b, use_outgoing=True) res = dag.nodes() self.assertEqual(['a', 'c'], res) self.assertEqual([0, 2], dag.node_indexes()) self.assertTrue(dag.has_edge(node_a, node_c)) self.assertEqual(dag.get_all_edge_data(node_a, node_c), ['Edgy_mk2'])
def test_deepcopy_with_holes(self): dag_a = retworkx.PyDAG() node_a = dag_a.add_node('a_1') node_b = dag_a.add_node('a_2') dag_a.add_edge(node_a, node_b, 'edge_1') node_c = dag_a.add_node('a_3') dag_a.add_edge(node_b, node_c, 'edge_2') dag_a.remove_node(node_b) dag_b = copy.deepcopy(dag_a) self.assertIsInstance(dag_b, retworkx.PyDAG) self.assertEqual([node_a, node_c], dag_b.node_indexes())
def test_isomorphic_compare_nodes_with_removals_deepcopy(self): dag_a = retworkx.PyDAG() dag_b = retworkx.PyDAG() qr_0_in = dag_a.add_node('qr[0]') qr_1_in = dag_a.add_node('qr[1]') cr_0_in = dag_a.add_node('cr[0]') qr_0_out = dag_a.add_node('qr[0]') qr_1_out = dag_a.add_node('qr[1]') cr_0_out = dag_a.add_node('qr[0]') cu1 = dag_a.add_child(qr_0_in, 'cu1', 'qr[0]') dag_a.add_edge(qr_1_in, cu1, 'qr[1]') measure_0 = dag_a.add_child(cr_0_in, 'measure', 'cr[0]') dag_a.add_edge(cu1, measure_0, 'qr[0]') measure_1 = dag_a.add_child(cu1, 'measure', 'qr[1]') dag_a.add_edge(measure_0, measure_1, 'cr[0]') dag_a.add_edge(measure_1, qr_1_out, 'qr[1]') dag_a.add_edge(measure_1, cr_0_out, 'cr[0]') dag_a.add_edge(measure_0, qr_0_out, 'qr[0]') dag_a.remove_node(cu1) dag_a.add_edge(qr_0_in, measure_0, 'qr[0]') dag_a.add_edge(qr_1_in, measure_1, 'qr[1]') qr_0_in = dag_b.add_node('qr[0]') qr_1_in = dag_b.add_node('qr[1]') cr_0_in = dag_b.add_node('cr[0]') qr_0_out = dag_b.add_node('qr[0]') qr_1_out = dag_b.add_node('qr[1]') cr_0_out = dag_b.add_node('qr[0]') measure_0 = dag_b.add_child(cr_0_in, 'measure', 'cr[0]') dag_b.add_edge(qr_0_in, measure_0, 'qr[0]') measure_1 = dag_b.add_child(qr_1_in, 'measure', 'qr[1]') dag_b.add_edge(measure_1, qr_1_out, 'qr[1]') dag_b.add_edge(measure_1, cr_0_out, 'cr[0]') dag_b.add_edge(measure_0, measure_1, 'cr[0]') dag_b.add_edge(measure_0, qr_0_out, 'qr[0]') self.assertTrue( retworkx.is_isomorphic_node_match(copy.deepcopy(dag_a), copy.deepcopy(dag_b), lambda x, y: x == y))
def test_many_children(self): dag = retworkx.PyDAG() node_a = dag.add_node("a") for i in range(10): dag.add_child(node_a, {"numeral": i}, {"edge": i}) res_even = dag.find_successors_by_edge(node_a, lambda x: x["edge"] % 2 == 0) res_odd = dag.find_successors_by_edge(node_a, lambda x: x["edge"] % 2 != 0) self.assertEqual( [ { "numeral": 8 }, { "numeral": 6 }, { "numeral": 4 }, { "numeral": 2 }, { "numeral": 0 }, ], res_even, ) self.assertEqual( [ { "numeral": 9 }, { "numeral": 7 }, { "numeral": 5 }, { "numeral": 3 }, { "numeral": 1 }, ], res_odd, )
def test_isomorphic_compare_edges_identical(self): dag_a = retworkx.PyDAG() dag_b = retworkx.PyDAG() node_a = dag_a.add_node("a_1") dag_a.add_child(node_a, "a_2", "a_1") dag_a.add_child(node_a, "a_3", "a_2") node_b = dag_b.add_node("a_1") dag_b.add_child(node_b, "a_2", "a_1") dag_b.add_child(node_b, "a_3", "a_2") for id_order in [False, True]: with self.subTest(id_order=id_order): self.assertTrue( retworkx.is_isomorphic( dag_a, dag_b, edge_matcher=lambda x, y: x == y, id_order=id_order, ) )
def test_empty_graph_with_weights(self): dag = retworkx.PyDAG() self.assertEqual( 0.0, retworkx.dag_weighted_longest_path_length( dag, lambda x: float(weight_fn(x))), ) self.assertEqual( [], retworkx.dag_weighted_longest_path(dag, lambda x: float(weight_fn(x))), )
def test_all_simple_paths_min_depth(self): dag = retworkx.PyDAG() for i in range(6): dag.add_node(i) dag.add_edges_from_no_data(self.edges) paths = retworkx.digraph_all_simple_paths(dag, 0, 5, min_depth=6) expected = [ [0, 1, 2, 3, 4, 5], [0, 1, 3, 2, 4, 5], ] for i in expected: self.assertIn(i, paths)
def test_all_simple_paths_with_cutoff(self): dag = retworkx.PyDAG() for i in range(6): dag.add_node(i) dag.add_edges_from_no_data(self.edges) paths = retworkx.digraph_all_simple_paths(dag, 0, 5, cutoff=4) expected = [ [0, 2, 4, 5], [0, 3, 4, 5]] self.assertEqual(len(expected), len(paths)) for i in expected: self.assertIn(i, paths)
def test_extend_from_weighted_edge_list(self): dag = retworkx.PyDAG() edge_list = [(0, 1, 'a'), (1, 2, 'b'), (0, 2, 'c'), (2, 3, 'd'), (0, 3, 'e')] dag.extend_from_weighted_edge_list(edge_list) self.assertEqual(len(dag), 4) self.assertEqual(['a', 'b', 'c', 'd', 'e'], dag.edges()) self.assertEqual(3, dag.out_degree(0)) self.assertEqual(0, dag.in_degree(0)) self.assertEqual(1, dag.out_degree(1)) self.assertEqual(1, dag.out_degree(2)) self.assertEqual(2, dag.in_degree(3))
def test_extend_from_edge_list(self): dag = retworkx.PyDAG() edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] dag.extend_from_edge_list(edge_list) self.assertEqual(len(dag), 4) self.assertEqual([None] * 5, dag.edges()) self.assertEqual(3, dag.out_degree(0)) self.assertEqual(0, dag.in_degree(0)) self.assertEqual(1, dag.out_degree(1)) self.assertEqual(1, dag.out_degree(2)) self.assertEqual(2, dag.in_degree(3))
def test_single_neighbor(self): dag = retworkx.PyDAG() node_a = dag.add_node('a') dag.add_child(node_a, 'b', {'a': 1}) dag.add_child(node_a, 'c', {'a': 2}) res = retworkx.digraph_adjacency_matrix(dag, lambda x: 1) self.assertIsInstance(res, np.ndarray) self.assertTrue(np.array_equal( np.array( [[0.0, 1.0, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]], dtype=np.float64), res))
def test_less_linear(self): dag = retworkx.PyDAG() node_a = dag.add_node('a') node_b = dag.add_child(node_a, 'b', {}) node_c = dag.add_child(node_b, 'c', {}) node_d = dag.add_child(node_c, 'd', {}) node_e = dag.add_child(node_d, 'e', {}) dag.add_edge(node_a, node_c, {}) dag.add_edge(node_a, node_e, {}) dag.add_edge(node_c, node_e, {}) self.assertEqual(4, retworkx.dag_longest_path_length(dag)) self.assertEqual([node_a, node_b, node_c, node_d, node_e], retworkx.dag_longest_path(dag))
def test_remove_nodes_retain_edges_multiple_out_edges(self): dag = retworkx.PyDAG() node_a = dag.add_node("a") node_d = dag.add_node("d") node_b = dag.add_child(node_a, "b", "Edgy") dag.add_edge(node_b, node_d, "Multiple out edgy") node_c = dag.add_child(node_b, "c", "Edgy_mk2") dag.remove_node_retain_edges(node_b) res = dag.nodes() self.assertEqual(["a", "d", "c"], res) self.assertEqual([0, 1, 3], dag.node_indexes()) self.assertTrue(dag.has_edge(node_a, node_c)) self.assertTrue(dag.has_edge(node_a, node_d))
def test_degenerate_graph_with_weight(self): dag = retworkx.PyDAG() dag.add_node(0) self.assertEqual( 0.0, retworkx.dag_weighted_longest_path_length( dag, lambda x: float(weight_fn(x))), ) self.assertEqual( [0], retworkx.dag_weighted_longest_path(dag, lambda x: float(weight_fn(x))), )
def test_remove_nodes_retain_edges_multiple_in_edges(self): dag = retworkx.PyDAG() node_a = dag.add_node('a') node_d = dag.add_node('d') node_b = dag.add_child(node_a, 'b', "Edgy") dag.add_edge(node_d, node_b, "Multiple in edgy") node_c = dag.add_child(node_b, 'c', "Edgy_mk2") dag.remove_node_retain_edges(node_b) res = dag.nodes() self.assertEqual(['a', 'd', 'c'], res) self.assertEqual([0, 1, 3], dag.node_indexes()) self.assertTrue(dag.has_edge(node_a, node_c)) self.assertTrue(dag.has_edge(node_d, node_c))
def test_add_edge_from_no_data(self): dag = retworkx.PyDAG() nodes = list(range(4)) dag.add_nodes_from(nodes) edge_list = [(0, 1), (1, 2), (0, 2), (2, 3), (0, 3)] res = dag.add_edges_from_no_data(edge_list) self.assertEqual(len(res), 5) self.assertEqual([None, None, None, None, None], dag.edges()) self.assertEqual(3, dag.out_degree(0)) self.assertEqual(0, dag.in_degree(0)) self.assertEqual(1, dag.out_degree(1)) self.assertEqual(1, dag.out_degree(2)) self.assertEqual(2, dag.in_degree(3))
def _sequential_allocation(block: ScheduleBlock) -> rx.PyDAG: """A helper function to create a DAG of a sequential alignment context.""" dag_instructions = rx.PyDAG() prev_node = None edges = [] for inst in block.instructions: current_node = dag_instructions.add_node(inst) if prev_node is not None: edges.append((prev_node, current_node)) prev_node = current_node dag_instructions.add_edges_from_no_data(edges) return dag_instructions
def test_add_edge_from(self): dag = retworkx.PyDAG() nodes = list(range(4)) dag.add_nodes_from(nodes) edge_list = [(0, 1, 'a'), (1, 2, 'b'), (0, 2, 'c'), (2, 3, 'd'), (0, 3, 'e')] res = dag.add_edges_from(edge_list) self.assertEqual(len(res), 5) self.assertEqual(['a', 'b', 'c', 'd', 'e'], dag.edges()) self.assertEqual(3, dag.out_degree(0)) self.assertEqual(0, dag.in_degree(0)) self.assertEqual(1, dag.out_degree(1)) self.assertEqual(1, dag.out_degree(2)) self.assertEqual(2, dag.in_degree(3))
def test_single_successor(self): dag = retworkx.PyDAG() node_a = dag.add_node("a") node_b = dag.add_child(node_a, "b", {"a": 1}) node_c = dag.add_child(node_b, "c", {"a": 2}) dag.add_child(node_c, "d", {"a": 1}) res_even = dag.find_successors_by_edge(node_b, lambda x: x["a"] % 2 == 0) res_odd = dag.find_successors_by_edge(node_b, lambda x: x["a"] % 2 != 0) self.assertEqual(["c"], res_even) self.assertEqual([], res_odd)
def test_single_predecessor_multiple_edges(self): dag = retworkx.PyDAG() node_a = dag.add_node("a") dag.add_child(node_a, "b", {"a": 1}) node_c = dag.add_child(node_a, "c", {"a": 2}) dag.add_edge(node_a, node_c, {"a": 3}) res_even = dag.find_predecessors_by_edge(node_c, lambda x: x["a"] % 2 == 0) res_odd = dag.find_predecessors_by_edge(node_c, lambda x: x["a"] % 2 == 0) self.assertEqual(["a"], res_even) self.assertEqual(["a"], res_odd)
def test_less_linear(self): dag = retworkx.PyDAG() node_a = dag.add_node("a") node_b = dag.add_child(node_a, "b", {}) node_c = dag.add_child(node_b, "c", {}) node_d = dag.add_child(node_c, "d", {}) node_e = dag.add_child(node_d, "e", {}) dag.add_edge(node_a, node_c, {}) dag.add_edge(node_a, node_e, {}) dag.add_edge(node_c, node_e, {}) self.assertEqual(4, retworkx.dag_longest_path_length(dag)) self.assertEqual( [node_a, node_b, node_c, node_d, node_e], retworkx.dag_longest_path(dag), )
def test_bfs_successors_sequence_negative_index(self): dag = retworkx.PyDAG() node_a = dag.add_node(0) node_b = dag.add_child(node_a, 1, {}) node_c = dag.add_child(node_b, 2, {}) node_d = dag.add_child(node_c, 3, {}) node_e = dag.add_child(node_d, 4, {}) node_f = dag.add_child(node_e, 5, {}) dag.add_child(node_f, 6, {}) node_h = dag.add_child(node_c, 7, {}) node_i = dag.add_child(node_h, 8, {}) node_j = dag.add_child(node_i, 9, {}) dag.add_child(node_j, 10, {}) res = retworkx.bfs_successors(dag, node_b) self.assertEqual((5, [6]), res[-1]) self.assertEqual((4, [5]), res[-3])
def test_default_weight(self): dag = retworkx.PyDAG() node_a = dag.add_node("a") dag.add_child(node_a, "b", {"a": 1}) dag.add_child(node_a, "c", {"a": 2}) res = retworkx.digraph_adjacency_matrix(dag, default_weight=4) self.assertIsInstance(res, np.ndarray) self.assertTrue( np.array_equal( np.array( [[0.0, 4.0, 4.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]], dtype=np.float64, ), res, ) )
def __init__(self): """ Create an empty DAGDependency. """ # Circuit name self.name = None # Directed multigraph whose nodes are operations(gates) and edges # represent non-commutativity between two gates. self._multi_graph = rx.PyDAG() # Map of qreg name to QuantumRegister object self.qregs = OrderedDict() # Map of creg name to ClassicalRegister object self.cregs = OrderedDict()
def test_bfs_successors_sequence_invalid_index(self): dag = retworkx.PyDAG() node_a = dag.add_node(0) node_b = dag.add_child(node_a, 1, {}) node_c = dag.add_child(node_b, 2, {}) node_d = dag.add_child(node_c, 3, {}) node_e = dag.add_child(node_d, 4, {}) node_f = dag.add_child(node_e, 5, {}) dag.add_child(node_f, 6, {}) node_h = dag.add_child(node_c, 7, {}) node_i = dag.add_child(node_h, 8, {}) node_j = dag.add_child(node_i, 9, {}) dag.add_child(node_j, 10, {}) res = retworkx.bfs_successors(dag, node_b) with self.assertRaises(IndexError): res[8]
def setup(self, num_nodes): random.seed(42) self.graph = retworkx.PyDAG() nodes = self.graph.add_nodes_from(list(range(num_nodes))) node_iter = iter(nodes) parents = [next(node_iter)] count = 0 while parents: source = parents.pop(0) try: target = next(nodes) parents.append(target) self.graph.add_edge(source, target, count) count += 1 except StopIteration: break
def _parallel_allocation(block: ScheduleBlock) -> rx.PyDAG: """A helper function to create a DAG of a parallel alignment context.""" dag_instructions = rx.PyDAG() slots = dict() edges = [] for inst in block.instructions: current_node = dag_instructions.add_node(inst) for chan in inst.channels: prev_node = slots.pop(chan, None) if prev_node is not None: edges.append((prev_node, current_node)) slots[chan] = current_node dag_instructions.add_edges_from_no_data(edges) return dag_instructions
def parse_gr_from_file(path, directed=False): """Parse a graph specification file and return a retworkx graph object :param str path: A path to the graph specification file to parse :param bool directed: Whether the returned graph is directed or not if set to True a PyDAG function is returned (with cycle_check set to False so it's a PyDiGraph) to maximize compatibility with functions that predate the PyDiGraph class :returns: A retworkx PyGraph or PyDAG object representing the input gr file """ if not directed: return_graph = retworkx.PyGraph() else: return_graph = retworkx.PyDAG() nodes_added = False if path.endswith("gz"): open_call = gzip.open else: open_call = open with open_call(path, "rt") as fd: for line in fd: if line.startswith("c"): continue if line.startswith("p"): num_nodes = int(line.split(" ")[2]) for i in range(num_nodes): return_graph.add_node(i) nodes_added = True elif line.startswith("a"): if not nodes_added: raise Exception( "Invalid gr file, program line not first non-comment " "line.") components = line.split(" ") u = int(components[1]) - 1 v = int(components[2]) - 1 weight = components[3] return_graph.add_edge(u, v, weight) else: raise Exception( "Invalid gr file line: '%s' doesn't start with a valid " "token") return return_graph
def test_extend_from_weighted_edge_list(self): dag = retworkx.PyDAG() edge_list = [ (0, 1, "a"), (1, 2, "b"), (0, 2, "c"), (2, 3, "d"), (0, 3, "e"), ] dag.extend_from_weighted_edge_list(edge_list) self.assertEqual(len(dag), 4) self.assertEqual(["a", "b", "c", "d", "e"], dag.edges()) self.assertEqual(3, dag.out_degree(0)) self.assertEqual(0, dag.in_degree(0)) self.assertEqual(1, dag.out_degree(1)) self.assertEqual(1, dag.out_degree(2)) self.assertEqual(2, dag.in_degree(3))