code: def _compute_diagonal(
      T_A,
      T_B,
      m,
      T_A_subseq_isfinite,
      T_B_subseq_isfinite,
      p,
      diags,
      diags_start_idx,
      diags_stop_idx,
      thread_idx,
      P,
      PL,
      PR,
      I,
      IL,
      IR,
      ignore_trivial,
  ):
      """
      Compute (Numba JIT-compiled) and update the (top-k) matrix profile P,
      PL, PR, I, IL, and IR sequentially along individual diagonals using a single
      thread and avoiding race conditions.
  
      Parameters
      ----------
      T_A : numpy.ndarray
          The time series or sequence for which to compute the matrix profile
  
      T_B : numpy.ndarray
          The time series or sequence that will be used to annotate T_A. For every
          subsequence in T_A, its nearest neighbor in T_B will be recorded.
  
      m : int
          Window size
  
      T_A_subseq_isfinite : numpy.ndarray
          A boolean array that indicates whether a subsequence in `T_A` contains a
          `np.nan`/`np.inf` value (False)
  
      T_B_subseq_isfinite : numpy.ndarray
          A boolean array that indicates whether a subsequence in `T_B` contains a
          `np.nan`/`np.inf` value (False)
  
      p : float
          The p-norm to apply for computing the Minkowski distance. Minkowski distance is
          typically used with `p` being 1 or 2, which correspond to the Manhattan distance
          and the Euclidean distance, respectively.
  
      diags : numpy.ndarray
          The diag of diagonals to process and compute
  
      diags_start_idx : int
          The start index for a range of diagonal diag to process and compute
  
      diags_stop_idx : int
          The (exclusive) stop index for a range of diagonal diag to process and compute
  
      thread_idx : int
          The thread index
  
      P : numpy.ndarray
          The (top-k) matrix profile, sorted in ascending order per row
  
      PL : numpy.ndarray
          The top-1 left marix profile
  
      PR : numpy.ndarray
          The top-1 right marix profile
  
      I : numpy.ndarray
          The (top-k) matrix profile indices
  
      IL : numpy.ndarray
          The top-1 left matrix profile indices
  
      IR : numpy.ndarray
          The top-1 right matrix profile indices
  
      ignore_trivial : bool
          Set to `True` if this is a self-join. Otherwise, for AB-join, set this to
          `False`. Default is `True`.
  
      Returns
      -------
      None
      """
      n_A = T_A.shape[0]
      n_B = T_B.shape[0]
      uint64_m = np.uint64(m)
      uint64_1 = np.uint64(1)
  
      for diag_idx in range(diags_start_idx, diags_stop_idx):
          g = diags[diag_idx]
  
          if g >= 0:
              iter_range = range(0, min(n_A - m + 1, n_B - m + 1 - g))
          else:
              iter_range = range(-g, min(n_A - m + 1, n_B - m + 1 - g))
  
          for i in iter_range:
              uint64_i = np.uint64(i)
              uint64_j = np.uint64(i + g)
  
              if uint64_i == 0 or uint64_j == 0:
                  p_norm = (
                      np.linalg.norm(
                          T_B[uint64_j : uint64_j + uint64_m]
                          - T_A[uint64_i : uint64_i + uint64_m],
                          ord=p,
                      )
                      ** p
                  )
              else:
                  p_norm = np.abs(
                      p_norm
                      - np.absolute(
                          T_B[uint64_j - uint64_1]
                          - T_A[uint64_i - uint64_1]
                      )
                      ** p
                      + np.absolute(
                          T_B[uint64_j + uint64_m - uint64_1]
                          - T_A[uint64_i + uint64_m - uint64_1]
                      )
                      ** p
                  )
  
              if p_norm < config.STUMPY_P_NORM_THRESHOLD:
                  p_norm = 0.0
  
              if (
                  T_A_subseq_isfinite[uint64_i]
                  and T_B_subseq_isfinite[uint64_j]
              ):
                  # Neither subsequence contains NaNs
  
                  # `P[thread_idx, i, :]` is sorted in ascending order and MUST be updated
                  # when the newly-calculated `p_norm` value becomes smaller than the
                  # last (i.e. greatest) element in this array. Note that the goal
                  # is to have top-k smallest distances for each subsequence.
                  if p_norm < P[thread_idx, uint64_i, -1]:
                      idx = np.searchsorted(
                          P[thread_idx, uint64_i], p_norm
                      )
                      core._shift_insert_at_index(
                          P[thread_idx, uint64_i],
                          idx,
                          p_norm,
                          shift="right",
                      )
                      core._shift_insert_at_index(
                          I[thread_idx, uint64_i],
                          idx,
                          uint64_j,
                          shift="right",
                      )
  
                  if ignore_trivial:  # self-joins only
                      if p_norm < P[thread_idx, uint64_j, -1]:
                          idx = np.searchsorted(
                              P[thread_idx, uint64_j], p_norm
                          )
                          core._shift_insert_at_index(
                              P[thread_idx, uint64_j],
                              idx,
                              p_norm,
                              shift="right",
                          )
                          core._shift_insert_at_index(
                              I[thread_idx, uint64_j],
                              idx,
                              uint64_i,
                              shift="right",
                          )
  
                      if uint64_i < uint64_j:
                          # left matrix profile and left matrix profile index
                          if p_norm < PL[thread_idx, uint64_j]:
                              PL[thread_idx, uint64_j] = p_norm
                              IL[thread_idx, uint64_j] = uint64_i
  
                          # right matrix profile and right matrix profile index
                          if p_norm < PR[thread_idx, uint64_i]:
                              PR[thread_idx, uint64_i] = p_norm
                              IR[thread_idx, uint64_i] = uint64_j
  
      return
  
imports: import numba
  import numpy
  from numba import njit, prange
  from .None import config, core
label_desc: Use image node_id 1 for calling a global function with example usage: _compute_diagonal(T_A, T_B, m, T_A_subseq_isfinite, T_B_subseq_isfinite, p, diags, diags_start_idx, diags_stop_idx, thread_idx, P, PL, PR, I, IL, IR, ignore_trivial) without return types