code: def compute_perm(parents):
      """
      Return a list of indices to reorder the adjacency and data matrices so
      that the union of two neighbors from layer to layer forms a binary tree.
      """
  
      # Order of last layer is random (chosen by the clustering algorithm).
      indices = []
      if len(parents) > 0:
          M_last = max(parents[-1]) + 1
          indices.append(list(range(M_last)))
  
      for parent in parents[::-1]:
          # Fake nodes go after real ones.
          pool_singeltons = len(parent)
  
          indices_layer = []
          for i in indices[-1]:
              indices_node = list(np.where(parent == i)[0])
              assert 0 <= len(indices_node) <= 2
  
              # Add a node to go with a singelton.
              if len(indices_node) == 1:
                  indices_node.append(pool_singeltons)
                  pool_singeltons += 1
  
              # Add two nodes as children of a singelton in the parent.
              elif len(indices_node) == 0:
                  indices_node.append(pool_singeltons + 0)
                  indices_node.append(pool_singeltons + 1)
                  pool_singeltons += 2
  
              indices_layer.extend(indices_node)
          indices.append(indices_layer)
  
      # Sanity checks.
      for i, indices_layer in enumerate(indices):
          M = M_last * 2**i
          # Reduction by 2 at each layer (binary tree).
          assert len(indices[0] == M)
          # The new ordering does not omit an indice.
          assert sorted(indices_layer) == list(range(M))
  
      return indices[::-1]
  
file_path: dgl/examples/pytorch/model_zoo/geometric/coarsening.py
imports: import numpy
  import scipy.sparse
  import sklearn.metrics
label_desc: Use image node_id 7 for calling a global function with example usage: compute_perm(parents) and returns: indices