code: def _remap(K, i, j, k, Features, linc, rinc):
      """Modifies the graph K to merge nodes i and  j into nodes k
      the graph weights are modified accordingly
  
      Parameters
      ----------
      K graph instance:
        the existing graphical model
      i,j,k: int
             indexes of the nodes to be merged and of the parent respectively
      Features: list of node-per-node features
      linc: array of shape(K.V)
            left incidence matrix
      rinc: array of shape(K.V)
            right incidencematrix
      """
      # -------
      # replace i by k
      # --------
      idxi = np.array(linc[i]).astype(np.int_)
      if np.size(idxi) > 1:
          for l in idxi:
              K.weights[l] = _inertia(k, K.edges[l, 1], Features)
      elif np.size(idxi) == 1:
          K.weights[idxi] = _inertia(k, K.edges[idxi, 1], Features)
      if np.size(idxi) > 0:
          K.edges[idxi, 0] = k
  
      idxi = np.array(rinc[i]).astype(np.int_)
      if np.size(idxi) > 1:
          for l in idxi:
              K.weights[l] = _inertia(K.edges[l, 0], k, Features)
      elif np.size(idxi) == 1:
          K.weights[idxi] = _inertia(K.edges[idxi, 0], k, Features)
      if np.size(idxi) > 0:
          K.edges[idxi, 1] = k
  
      # ------
      # replace j by k
      # -------
      idxj = np.array(linc[j]).astype(np.int_)
      if np.size(idxj) > 1:
          for l in idxj:
              K.weights[l] = _inertia(k, K.edges[l, 1], Features)
      elif np.size(idxj) == 1:
          K.weights[idxj] = _inertia(k, K.edges[idxj, 1], Features)
      if np.size(idxj) > 0:
          K.edges[idxj, 0] = k
  
      idxj = np.array(rinc[j]).astype(np.int_)
      if np.size(idxj) > 1:
          for l in idxj:
              K.weights[l] = _inertia(k, K.edges[l, 0], Features)
      elif np.size(idxj) == 1:
          K.weights[idxj] = _inertia(k, K.edges[idxj, 0], Features)
      if np.size(idxj) > 0:
          K.edges[idxj, 1] = k
  
      # ------
      # update linc, rinc
      # ------
      lidxk = list(linc[j]) + list(linc[i])
      for L in lidxk:
          if K.edges[L, 1] == -1:
              lidxk.remove(L)
  
      linc[k] = lidxk
      linc[i] = []
      linc[j] = []
      ridxk = list(rinc[j]) + list(rinc[i])
      for L in ridxk:
          if K.edges[L, 0] == -1:
              ridxk.remove(L)
  
      rinc[k] = ridxk
      rinc[i] = []
      rinc[j] = []
  
      # ------
      # remove double edges
      # ------
      # left side
      idxk = np.array(linc[k]).astype(np.int_)
      if np.size(idxk) > 0:
          corr = K.edges[idxk, 1]
          scorr = np.sort(corr)
          acorr = np.argsort(corr)
          for a in range(np.size(scorr) - 1):
              if scorr[a] == scorr[a + 1]:
                  i2 = idxk[acorr[a + 1]]
                  K.weights[i2] = np.inf
                  rinc[K.edges[i2, 1]].remove(i2)
                  K.edges[i2] = -1
                  linc[k].remove(i2)
  
      # right side
      idxk = np.array(rinc[k]).astype(np.int_)
      if np.size(idxk) > 0:
          corr = K.edges[idxk, 0]
          scorr = np.sort(corr)
          acorr = np.argsort(corr)
          for a in range(np.size(scorr) - 1):
              if scorr[a] == scorr[a + 1]:
                  i2 = idxk[acorr[a + 1]]
                  K.weights[i2] = np.inf
                  linc[K.edges[i2, 0]].remove(i2)
                  K.edges[i2] = -1
                  rinc[k].remove(i2)
      return linc, rinc
  
imports: from warnings import warn
  import numpy
  from ..graph.forest import Forest
  from ..graph.graph import WeightedGraph
label_desc: Use image node_id 8 for calling a global function with example usage: _remap(K, i, j, k, Features, linc, rinc) and returns: linc,  rinc