code: def _top_eigen(
      H: Tensor,
      k: Optional[int],
      hessian_reg: float,
      hessian_inverse_tol: float,
  ) -> Tuple[Tensor, Tensor]:
      """
      This is a wrapper around `torch.linalg.eig` that performs some pre /
      post-processing to make it suitable for computing the low-rank
      "square root" of a matrix, i.e. given square matrix H, find tall and
      skinny L such that LL' approximates H. This function returns eigenvectors (as the
      columns of a matrix Q) and corresponding eigenvectors (as diagonal entries in
      a matrix V), and we can then let L=QV^{1/2}Q'.  However, doing so requires the
      eigenvalues in V to be positive.  Thus, this function does pre-processing (adds
      an entry to the diagonal of H) and post-processing (returns only the top-k
      eigenvectors / eigenvalues where the eigenvalues are above a positive tolerance)
      to encourage and guarantee, respectively, that the returned eigenvalues be
      positive.  The pre-processing shifts the eigenvalues up by a constant, and the
      post-processing effectively replaces H with the most similar matrix (in terms of
      Frobenius norm) whose eigenvalues are above the tolerance, see
      https://nhigham.com/2021/01/26/what-is-the-nearest-positive-semidefinite-matrix/.
  
      Args:
          H (Tensor): a 2D square Tensor for which the top eigenvectors / eigenvalues
                  will be computed.
          k (int): how many eigenvectors / eigenvalues to return (before dropping pairs
                  whose eigenvalue is below the tolerance).
          hessian_reg (float): We add an entry to the diagonal of `H` to encourage it to
                  be positive definite. This is that entry.
          hessian_inverse_tol (float): To compute the "square root" of `H` using the top
                  eigenvectors / eigenvalues, the eigenvalues should be positive, and
                  furthermore if above a tolerance, the inversion will be more
                  numerically stable. Therefore, we only return eigenvectors /
                  eigenvalues where the eigenvalue is above a tolerance. This argument
                  specifies that tolerance.
  
      Returns:
          (eigenvalues, eigenvectors) (tuple of tensors): Mimicking the output of
                  `torch.linalg.eigh`, `eigenvalues` is a 1D tensor of the top-k
                  eigenvalues of the regularized `H` that are additionally above
                  `hessian_inverse_tol`, and `eigenvectors` is a 2D tensor whose columns
                  contain the corresponding eigenvectors. The eigenvalues are in
                  ascending order.
      """
      # add regularization to hopefully make H positive definite
      H = H + (torch.eye(len(H)).to(device=H.device) * hessian_reg)
  
      # find eigvectors / eigvals of H
      # ls are eigenvalues, in ascending order
      # columns of vs are corresponding eigenvectors
      ls, vs = _eig_helper(H)
  
      # despite adding regularization to the hessian, it may still not be positive
      # definite. we can get rid of negative eigenvalues, but for numerical stability
      # can get rid of eigenvalues below a tolerance
      keep = ls > hessian_inverse_tol
  
      ls = ls[keep]
      vs = vs[:, keep]
  
      # only keep the top `k` eigvals / eigvectors
      if not (k is None):
          ls = ls[-k:]
          vs = vs[:, -k:]
  
      # `torch.linalg.eig` is not deterministic in that you can multiply an eigenvector
      # by -1, and it is still an eigenvector. to make eigenvectors deterministic,
      # we multiply an eigenvector according to some rule that flips if you multiply
      # the eigenvector by -1. in this case, that rule is whether the sum of the
      # entries of the eigenvector are > 0
      rule = torch.sum(vs, dim=0) > 0  # entries are 0/1
      rule_multiplier = (2 * rule) - 1  # entries are -1/1
      vs = vs * rule_multiplier.unsqueeze(0)
  
      return ls, vs
  
imports: import warnings
  from functools import reduce
  from typing import Any, Callable, Iterable, List, NamedTuple, Optional, Tuple, TYPE_CHECKING, Union
  import torch
  import torch.nn
  from captum._utils.common import _get_module_from_name, _parse_version
  from captum._utils.gradient import _compute_jacobian_wrt_params, _compute_jacobian_wrt_params_with_sample_wise_trick
  from captum._utils.progress import progress
  from torch import Tensor
  from torch.nn import Module
  from torch.utils.data import DataLoader, Dataset
label_desc: Use image node_id 18 for calling a global function with example usage: _top_eigen(H, k, hessian_reg, hessian_inverse_tol) and returns: ls,  vs