14def masses_to_classes(array):
16 Converts mass hypotheses to classes used in cross-entropy computation.
30 array (numpy.ndarray): Array containing PDG mass codes.
33 numpy.ndarray: Array containing mass hypothese converted to classes.
35 array = -1 * np.abs(array)
36 array[array == -11] = 1
37 array[array == -13] = 2
38 array[array == -211] = 3
39 array[array == -321] = 4
40 array[array == -2212] = 5
41 array[array == -22] = 6
47def _check_undirected(adjacency_matrix):
49 Checks whether an adjacency matrix-encoded graph is undirected, i.e. symmetric.
51 n, m = adjacency_matrix.shape
55 return (adjacency_matrix == adjacency_matrix.T).all()
58def _connectedness_dfs(adjacency_matrix, index, reached):
60 Actual depth-first search of graph connectedness. Starting from the node marked by index a recursive search
is
61 performed. Visited nodes are marked
as reachable during recursion. If the graph
is not connected, the reachability
62 `reached` mask will contain zero elements.
64 n = adjacency_matrix.shape[0]
68 for column
in range(n):
70 if adjacency_matrix[index, column] != 0
and not reached[column]:
71 _connectedness_dfs(adjacency_matrix, column, reached)
74def _check_connectedness(adjacency_matrix, allow_disconnected_leaves=False):
76 Checks whether all sub-graphs of an adjacency matrix-encoded graph are connected,
77 i.e. have at least one edge linking them.
79 n, m = adjacency_matrix.shape
83 reached = t.zeros(n, dtype=t.uint8)
84 _connectedness_dfs(adjacency_matrix, 0, reached)
86 if allow_disconnected_leaves:
87 reached = t.logical_or(reached, adjacency_matrix.sum(axis=1) == 0)
92def _acyclic_dfs(adjacency_matrix, index, parent, reached):
94 Actual depth-first search of graph cycles. Starting from the node marked by index a recursive search
is performed.
95 Visited nodes are marked
as reachable during recursion. If a node
is found
in a trail that has been previously
96 marked
as already reached this indicates a cycle.
98 n = adjacency_matrix.shape[0]
107 if adjacency_matrix[index, row] != 0:
110 if not _acyclic_dfs(adjacency_matrix, row, index, reached):
118def _check_acyclic(adjacency_matrix):
120 Checks whether the graph encoded by the passed adjacency matrix is acyclic, i.e. all non-empty trails
in the graph
121 do
not contain repetitions. Node self-references are legal
and simply ignored.
123 n, m = adjacency_matrix.shape
127 reached = t.zeros(n, dtype=t.uint8)
129 return _acyclic_dfs(adjacency_matrix, 0, -1, reached)
132def is_valid_tree(adjacency_matrix):
134 Checks whether the graph encoded by the passed adjacency matrix encodes a valid tree,
135 i.e. an undirected, acyclic and connected graph.
138 adjacency_matrix (numpy.ndarray): 2-dimensional matrix (N, N) encoding the graph
's node adjacencies. Linked nodes should have value unequal to zero.
141 bool: True if the encoded graph
is a tree,
False otherwise.
143 undirected = _check_undirected(adjacency_matrix)
144 connected = _check_connectedness(adjacency_matrix)
145 acyclic = _check_acyclic(adjacency_matrix)
147 return undirected
and connected
and acyclic