code: def _simrank_similarity_numpy(
      G,
      source=None,
      target=None,
      importance_factor=0.9,
      max_iterations=1000,
      tolerance=1e-4,
  ):
      """Calculate SimRank of nodes in ``G`` using matrices with ``numpy``.
  
      The SimRank algorithm for determining node similarity is defined in
      [1]_.
  
      Parameters
      ----------
      G : NetworkX graph
          A NetworkX graph
  
      source : node
          If this is specified, the returned dictionary maps each node
          ``v`` in the graph to the similarity between ``source`` and
          ``v``.
  
      target : node
          If both ``source`` and ``target`` are specified, the similarity
          value between ``source`` and ``target`` is returned. If
          ``target`` is specified but ``source`` is not, this argument is
          ignored.
  
      importance_factor : float
          The relative importance of indirect neighbors with respect to
          direct neighbors.
  
      max_iterations : integer
          Maximum number of iterations.
  
      tolerance : float
          Error tolerance used to check convergence. When an iteration of
          the algorithm finds that no similarity value changes more than
          this amount, the algorithm halts.
  
      Returns
      -------
      similarity : numpy array or float
          If ``source`` and ``target`` are both ``None``, this returns a
          2D array containing SimRank scores of the nodes.
  
          If ``source`` is not ``None`` but ``target`` is, this returns an
          1D array containing SimRank scores of ``source`` and that
          node.
  
          If neither ``source`` nor ``target`` is ``None``, this returns
          the similarity value for the given pair of nodes.
  
      Examples
      --------
      >>> G = nx.cycle_graph(2)
      >>> nx.similarity._simrank_similarity_numpy(G)
      array([[1., 0.],
             [0., 1.]])
      >>> nx.similarity._simrank_similarity_numpy(G, source=0)
      array([1., 0.])
      >>> nx.similarity._simrank_similarity_numpy(G, source=0, target=0)
      1.0
  
      References
      ----------
      .. [1] G. Jeh and J. Widom.
             "SimRank: a measure of structural-context similarity",
             In KDD'02: Proceedings of the Eighth ACM SIGKDD
             International Conference on Knowledge Discovery and Data Mining,
             pp. 538--543. ACM Press, 2002.
      """
      # This algorithm follows roughly
      #
      #     S = max{C * (A.T * S * A), I}
      #
      # where C is the importance factor, A is the column normalized
      # adjacency matrix, and I is the identity matrix.
      import numpy as np
  
      adjacency_matrix = nx.to_numpy_array(G)
  
      # column-normalize the ``adjacency_matrix``
      s = np.array(adjacency_matrix.sum(axis=0))
      s[s == 0] = 1
      adjacency_matrix /= s  # adjacency_matrix.sum(axis=0)
  
      newsim = np.eye(len(G), dtype=np.float64)
      for its in range(max_iterations):
          prevsim = newsim.copy()
          newsim = importance_factor * (
              (adjacency_matrix.T @ prevsim) @ adjacency_matrix
          )
          np.fill_diagonal(newsim, 1.0)
  
          if np.allclose(prevsim, newsim, atol=tolerance):
              break
  
      if its + 1 == max_iterations:
          raise nx.ExceededMaxIterations(
              f"simrank did not converge after {max_iterations} iterations."
          )
  
      if source is not None and target is not None:
          return newsim[source, target]
      if source is not None:
          return newsim[source]
      return newsim
  
file_path: networkx/networkx/algorithms/similarity.py
imports: import math
  import time
  import warnings
  from dataclasses import dataclass
  from itertools import product
  import networkx
label_desc: Use image node_id 8 for calling a global function with example usage: _simrank_similarity_numpy(G, source, target, importance_factor, max_iterations, tolerance) and returns: newsim, newsim, newsim