code: def linear_regression_rows(
      y, x, covariates, block_size=16, pass_through=(), *, weights=None
  ) -> hail.Table:
      r"""For each row, test an input variable for association with
      response variables using linear regression.
  
      Examples
      --------
  
      >>> result_ht = hl.linear_regression_rows(
      ...     y=dataset.pheno.height,
      ...     x=dataset.GT.n_alt_alleles(),
      ...     covariates=[1, dataset.pheno.age, dataset.pheno.is_female])
  
      Warning
      -------
      As in the example, the intercept covariate ``1`` must be
      included **explicitly** if desired.
  
      Warning
      -------
      If `y` is a single value or a list, :func:`.linear_regression_rows`
      considers the same set of columns (i.e., samples, points) for every response
      variable and row, namely those columns for which **all** response variables
      and covariates are defined.
  
      If `y` is a list of lists, then each inner list is treated as an
      independent group, subsetting columns for missingness separately.
  
      Notes
      -----
      With the default root and `y` a single expression, the following row-indexed
      fields are added.
  
      - **<row key fields>** (Any) -- Row key fields.
      - **<pass_through fields>** (Any) -- Row fields in `pass_through`.
      - **n** (:py:data:`.tint32`) -- Number of columns used.
      - **sum_x** (:py:data:`.tfloat64`) -- Sum of input values `x`.
      - **y_transpose_x** (:py:data:`.tfloat64`) -- Dot product of response
        vector `y` with the input vector `x`.
      - **beta** (:py:data:`.tfloat64`) --
        Fit effect coefficient of `x`, :math:`\hat\beta_1` below.
      - **standard_error** (:py:data:`.tfloat64`) --
        Estimated standard error, :math:`\widehat{\mathrm{se}}_1`.
      - **t_stat** (:py:data:`.tfloat64`) -- :math:`t`-statistic, equal to
        :math:`\hat\beta_1 / \widehat{\mathrm{se}}_1`.
      - **p_value** (:py:data:`.tfloat64`) -- :math:`p`-value.
  
      If `y` is a list of expressions, then the last five fields instead have type
      :class:`.tarray` of :py:data:`.tfloat64`, with corresponding indexing of
      the list and each array.
  
      If `y` is a list of lists of expressions, then `n` and `sum_x` are of type
      ``array<float64>``, and the last five fields are of type
      ``array<array<float64>>``. Index into these arrays with
      ``a[index_in_outer_list, index_in_inner_list]``. For example, if
      ``y=[[a], [b, c]]`` then the p-value for ``b`` is ``p_value[1][0]``.
  
  
      In the statistical genetics example above, the input variable `x` encodes
      genotype as the number of alternate alleles (0, 1, or 2). For each variant
      (row), genotype is tested for association with height controlling for age
      and sex, by fitting the linear regression model:
  
      .. math::
  
          \mathrm{height} = \beta_0 + \beta_1 \, \mathrm{genotype}
              + \beta_2 \, \mathrm{age}
              + \beta_3 \, \mathrm{is\_female}
              + \varepsilon,
              \quad
              \varepsilon \sim \mathrm{N}(0, \sigma^2)
  
      Boolean covariates like :math:`\mathrm{is\_female}` are encoded as 1 for
      ``True`` and 0 for ``False``. The null model sets :math:`\beta_1 = 0`.
  
      The standard least-squares linear regression model is derived in Section
      3.2 of `The Elements of Statistical Learning, 2nd Edition
      <http://statweb.stanford.edu/~tibs/ElemStatLearn/printings/ESLII_print10.pdf>`__.
      See equation 3.12 for the t-statistic which follows the t-distribution with
      :math:`n - k - 1` degrees of freedom, under the null hypothesis of no
      effect, with :math:`n` samples and :math:`k` covariates in addition to
      ``x``.
  
      Note
      ----
      Use the `pass_through` parameter to include additional row fields from
      matrix table underlying ``x``. For example, to include an "rsid" field, set
      ``pass_through=['rsid']`` or ``pass_through=[mt.rsid]``.
  
      Parameters
      ----------
      y : :class:`.Float64Expression` or :obj:`list` of :class:`.Float64Expression`
          One or more column-indexed response expressions.
      x : :class:`.Float64Expression`
          Entry-indexed expression for input variable.
      covariates : :obj:`list` of :class:`.Float64Expression`
          List of column-indexed covariate expressions.
      block_size : :obj:`int`
          Number of row regressions to perform simultaneously per core. Larger blocks
          require more memory but may improve performance.
      pass_through : :obj:`list` of :class:`str` or :class:`.Expression`
          Additional row fields to include in the resulting table.
      weights : :class:`.Float64Expression` or :obj:`list` of :class:`.Float64Expression`
          Optional column-indexed weighting for doing weighted least squares regression. Specify a single weight if a
          single y or list of ys is specified. If a list of lists of ys is specified, specify one weight per inner list.
  
      Returns
      -------
      :class:`.Table`
      """
      if (
          not isinstance(Env.backend(), SparkBackend)
          or weights is not None
      ):
          return _linear_regression_rows_nd(
              y, x, covariates, block_size, weights, pass_through
          )
  
      mt = matrix_table_source("linear_regression_rows/x", x)
      raise_unless_entry_indexed("linear_regression_rows/x", x)
  
      y_is_list = isinstance(y, list)
      if y_is_list and len(y) == 0:
          raise ValueError(
              "'linear_regression_rows': found no values for 'y'"
          )
      is_chained = y_is_list and isinstance(y[0], list)
      if is_chained and any(len(lst) == 0 for lst in y):
          raise ValueError(
              "'linear_regression_rows': found empty inner list for 'y'"
          )
  
      y = [
          raise_unless_column_indexed("linear_regression_rows_nd/y", y)
          or ys
          for ys in wrap_to_list(y)
          for y in (ys if is_chained else [ys])
      ]
  
      for e in itertools.chain.from_iterable(y) if is_chained else y:
          analyze("linear_regression_rows/y", e, mt._col_indices)
  
      for e in covariates:
          analyze(
              "linear_regression_rows/covariates", e, mt._col_indices
          )
  
      _warn_if_no_intercept("linear_regression_rows", covariates)
  
      x_field_name = Env.get_uid()
      if is_chained:
          y_field_names = [
              [f"__y_{i}_{j}" for j in range(len(y[i]))]
              for i in range(len(y))
          ]
          y_dict = dict(
              zip(
                  itertools.chain.from_iterable(y_field_names),
                  itertools.chain.from_iterable(y),
              )
          )
          func = "LinearRegressionRowsChained"
  
      else:
          y_field_names = list(f"__y_{i}" for i in range(len(y)))
          y_dict = dict(zip(y_field_names, y))
          func = "LinearRegressionRowsSingle"
  
      cov_field_names = list(
          f"__cov{i}" for i in range(len(covariates))
      )
  
      row_fields = _get_regression_row_fields(
          mt, pass_through, "linear_regression_rows"
      )
  
      # FIXME: selecting an existing entry field should be emitted as a SelectFields
      mt = mt._select_all(
          col_exprs=dict(
              **y_dict, **dict(zip(cov_field_names, covariates))
          ),
          row_exprs=row_fields,
          col_key=[],
          entry_exprs={x_field_name: x},
      )
  
      config = {
          "name": func,
          "yFields": y_field_names,
          "xField": x_field_name,
          "covFields": cov_field_names,
          "rowBlockSize": block_size,
          "passThrough": [x for x in row_fields if x not in mt.row_key],
      }
      ht_result = Table(ir.MatrixToTableApply(mt._mir, config))
  
      if not y_is_list:
          fields = [
              "y_transpose_x",
              "beta",
              "standard_error",
              "t_stat",
              "p_value",
          ]
          ht_result = ht_result.annotate(
              **{f: ht_result[f][0] for f in fields}
          )
  
      return ht_result.persist()
  
imports: import builtins
  import itertools
  import math
  from typing import Dict, Callable, Optional, Union, Tuple, List
  import hail
  import hail
  import hail.expr.aggregators
  from hail import ir
  from hail.expr import Expression, ExpressionException, expr_float64, expr_call, expr_any, expr_numeric, expr_locus, analyze, raise_unless_entry_indexed, raise_unless_row_indexed, matrix_table_source, table_source, raise_unless_column_indexed
  from hail.expr.types import tbool, tarray, tfloat64, tint32
  from hail.genetics.reference_genome import reference_genome_type
  from hail.linalg import BlockMatrix
  from hail.matrixtable import MatrixTable
  from hail.methods.misc import require_biallelic, require_row_key_variant
  from hail.stats import LinearMixedModel
  from hail.table import Table
  from hail.typecheck import typecheck, nullable, numeric, oneof, sized_tupleof, sequenceof, enumeration, anytype
  from hail.utils import wrap_to_list, new_temp_file, FatalError
  from hail.utils.java import Env, info, warning
  from .None import pca
  from .None import relatedness
  from ..backend.spark_backend import SparkBackend
label_desc: Use image node_id 3 for calling a global function with example usage: linear_regression_rows(y, x, covariates, block_size, pass_through) and returns: ht_result, _linear_regression_rows_nd