code: def _onenormest_core(A, AT, t, itmax):
      """
      Compute a lower bound of the 1-norm of a sparse matrix.
  
      Parameters
      ----------
      A : ndarray or other linear operator
          A linear operator that can produce matrix products.
      AT : ndarray or other linear operator
          The transpose of A.
      t : int, optional
          A positive parameter controlling the tradeoff between
          accuracy versus time and memory usage.
      itmax : int, optional
          Use at most this many iterations.
  
      Returns
      -------
      est : float
          An underestimate of the 1-norm of the sparse matrix.
      v : ndarray, optional
          The vector such that ||Av||_1 == est*||v||_1.
          It can be thought of as an input to the linear operator
          that gives an output with particularly large norm.
      w : ndarray, optional
          The vector Av which has relatively large 1-norm.
          It can be thought of as an output of the linear operator
          that is relatively large in norm compared to the input.
      nmults : int, optional
          The number of matrix products that were computed.
      nresamples : int, optional
          The number of times a parallel column was observed,
          necessitating a re-randomization of the column.
  
      Notes
      -----
      This is algorithm 2.4.
  
      """
      # This function is a more or less direct translation
      # of Algorithm 2.4 from the Higham and Tisseur (2000) paper.
      A_linear_operator = aslinearoperator(A)
      AT_linear_operator = aslinearoperator(AT)
      if itmax < 2:
          raise ValueError("at least two iterations are required")
      if t < 1:
          raise ValueError("at least one column is required")
      n = A.shape[0]
      if t >= n:
          raise ValueError("t should be smaller than the order of A")
      # Track the number of big*small matrix multiplications
      # and the number of resamplings.
      nmults = 0
      nresamples = 0
      # "We now explain our choice of starting matrix.  We take the first
      # column of X to be the vector of 1s [...] This has the advantage that
      # for a matrix with nonnegative elements the algorithm converges
      # with an exact estimate on the second iteration, and such matrices
      # arise in applications [...]"
      X = np.ones((n, t), dtype=float)
      # "The remaining columns are chosen as rand{-1,1},
      # with a check for and correction of parallel columns,
      # exactly as for S in the body of the algorithm."
      if t > 1:
          for i in range(1, t):
              # These are technically initial samples, not resamples,
              # so the resampling count is not incremented.
              resample_column(i, X)
          for i in range(t):
              while column_needs_resampling(i, X):
                  resample_column(i, X)
                  nresamples += 1
      # "Choose starting matrix X with columns of unit 1-norm."
      X /= float(n)
      # "indices of used unit vectors e_j"
      ind_hist = np.zeros(0, dtype=np.intp)
      est_old = 0
      S = np.zeros((n, t), dtype=float)
      k = 1
      ind = None
      while True:
          Y = np.asarray(A_linear_operator.matmat(X))
          nmults += 1
          mags = _sum_abs_axis0(Y)
          est = np.max(mags)
          best_j = np.argmax(mags)
          if est > est_old or k == 2:
              if k >= 2:
                  ind_best = ind[best_j]
              w = Y[:, best_j]
          # (1)
          if k >= 2 and est <= est_old:
              est = est_old
              break
          est_old = est
          S_old = S
          if k > itmax:
              break
          S = sign_round_up(Y)
          del Y
          # (2)
          if every_col_of_X_is_parallel_to_a_col_of_Y(S, S_old):
              break
          if t > 1:
              # "Ensure that no column of S is parallel to another column of S
              # or to a column of S_old by replacing columns of S by rand{-1,1}."
              for i in range(t):
                  while column_needs_resampling(i, S, S_old):
                      resample_column(i, S)
                      nresamples += 1
          del S_old
          # (3)
          Z = np.asarray(AT_linear_operator.matmat(S))
          nmults += 1
          h = _max_abs_axis1(Z)
          del Z
          # (4)
          if k >= 2 and max(h) == h[ind_best]:
              break
          # "Sort h so that h_first >= ... >= h_last
          # and re-order ind correspondingly."
          #
          # Later on, we will need at most t+len(ind_hist) largest
          # entries, so drop the rest
          ind = np.argsort(h)[::-1][: t + len(ind_hist)].copy()
          del h
          if t > 1:
              # (5)
              # Break if the most promising t vectors have been visited already.
              if np.isin(ind[:t], ind_hist).all():
                  break
              # Put the most promising unvisited vectors at the front of the list
              # and put the visited vectors at the end of the list.
              # Preserve the order of the indices induced by the ordering of h.
              seen = np.isin(ind, ind_hist)
              ind = np.concatenate((ind[~seen], ind[seen]))
          for j in range(t):
              X[:, j] = elementary_vector(n, ind[j])
  
          new_ind = ind[:t][~np.isin(ind[:t], ind_hist)]
          ind_hist = np.concatenate((ind_hist, new_ind))
          k += 1
      v = elementary_vector(n, ind_best)
      return est, v, w, nmults, nresamples
  
file_path: scipy/scipy/sparse/linalg/_onenormest.py
imports: import numpy
  from scipy.sparse.linalg import aslinearoperator
label_desc: Use image node_id 13 for calling a global function with example usage: _onenormest_core(A, AT, t, itmax) and returns: est,  v,  w,  nmults,  nresamples