code: def _pca_and_moments(
      A,
      k=10,
      num_moments=5,
      compute_loadings=False,
      q_iterations=10,
      oversampling_param=None,
      block_size=128,
      moment_samples=100,
  ):
      if not isinstance(A, TallSkinnyMatrix):
          raise_unless_entry_indexed("_spectral_moments/entry_expr", A)
          A = _make_tsm(A, block_size)
  
      if oversampling_param is None:
          oversampling_param = k
  
      # Set Parameters
      q = q_iterations
      L = k + oversampling_param
      n = A.ncols
  
      # Generate random matrix G
      G = hl.rand_norm(0, 1, size=(n, L))
      G = hl.nd.qr(G)[0]._persist()
  
      fact = _krylov_factorization(A, G, q, compute_loadings)
      info("_reduced_svd: Computing local SVD")
      U, S, V = fact.reduced_svd(k)
  
      p = min(num_moments // 2, 10)
  
      # Generate random matrix G2 for moment estimation
      G2 = hl.rand_unif(-1, 1, size=(n, moment_samples)).map(
          lambda x: hl.sign(x)
      )
      # Project out components in subspace fact.V, which we can compute exactly
      G2 = G2 - fact.V @ (fact.V.T @ G2)
      Q1, R1 = hl.nd.qr(G2)._persist()
      fact2 = _krylov_factorization(A, Q1, p, compute_U=False)
      moments_and_stdevs = fact2.spectral_moments(num_moments, R1)
      # Add back exact moments
      moments = moments_and_stdevs.moments + hl.nd.array(
          [
              fact.S.map(lambda x: x ** (2 * i)).sum()
              for i in range(1, num_moments + 1)
          ]
      )
      moments_and_stdevs = hl.eval(
          hl.struct(moments=moments, stdevs=moments_and_stdevs.stdevs)
      )
      moments = moments_and_stdevs.moments
      stdevs = moments_and_stdevs.stdevs
  
      scores = V * S
      eigens = hl.eval(S * S)
      info("blanczos_pca: SVD Complete. Computing conversion to PCs.")
  
      hail_array_scores = scores._data_array()
      cols_and_scores = hl.zip(
          A.source_table.index_globals().cols, hail_array_scores
      ).map(lambda tup: tup[0].annotate(scores=tup[1]))
      st = hl.Table.parallelize(cols_and_scores, key=A.col_key)
  
      if compute_loadings:
          lt = A.source_table.select()
          lt = lt.annotate_globals(U=U)
          idx_name = "_tmp_pca_loading_index"
          lt = lt.add_index(idx_name)
          lt = lt.annotate(
              loadings=hl.array(lt.U[lt[idx_name], :])
          ).select_globals()
          lt = lt.drop(lt[idx_name])
      else:
          lt = None
  
      return eigens, st, lt, moments, stdevs
  
imports: from typing import List, Tuple
  import hail
  import hail.expr.aggregators
  from hail.expr.expressions import construct_expr
  from hail.expr import expr_float64, expr_call, raise_unless_entry_indexed, matrix_table_source
  from hail import ir
  from hail.table import Table
  from hail.typecheck import typecheck, oneof, nullable
  from hail.utils import FatalError
  from hail.utils.java import Env, info
  from hail.experimental import mt_to_table_of_ndarray
label_desc: Use image node_id 9 for calling a global function with example usage: _pca_and_moments(A, k, num_moments, compute_loadings, q_iterations, oversampling_param, block_size, moment_samples) and returns: eigens,  st,  lt,  moments,  stdevs