code: def _rref(
      M,
      iszerofunc=_iszero,
      simplify=False,
      pivots=True,
      normalize_last=True,
  ):
      """Return reduced row-echelon form of matrix and indices
      of pivot vars.
  
      Parameters
      ==========
  
      iszerofunc : Function
          A function used for detecting whether an element can
          act as a pivot.  ``lambda x: x.is_zero`` is used by default.
  
      simplify : Function
          A function used to simplify elements when looking for a pivot.
          By default SymPy's ``simplify`` is used.
  
      pivots : True or False
          If ``True``, a tuple containing the row-reduced matrix and a tuple
          of pivot columns is returned.  If ``False`` just the row-reduced
          matrix is returned.
  
      normalize_last : True or False
          If ``True``, no pivots are normalized to `1` until after all
          entries above and below each pivot are zeroed.  This means the row
          reduction algorithm is fraction free until the very last step.
          If ``False``, the naive row reduction procedure is used where
          each pivot is normalized to be `1` before row operations are
          used to zero above and below the pivot.
  
      Examples
      ========
  
      >>> from sympy import Matrix
      >>> from sympy.abc import x
      >>> m = Matrix([[1, 2], [x, 1 - 1/x]])
      >>> m.rref()
      (Matrix([
      [1, 0],
      [0, 1]]), (0, 1))
      >>> rref_matrix, rref_pivots = m.rref()
      >>> rref_matrix
      Matrix([
      [1, 0],
      [0, 1]])
      >>> rref_pivots
      (0, 1)
  
      ``iszerofunc`` can correct rounding errors in matrices with float
      values. In the following example, calling ``rref()`` leads to
      floating point errors, incorrectly row reducing the matrix.
      ``iszerofunc= lambda x: abs(x) < 1e-9`` sets sufficiently small numbers
      to zero, avoiding this error.
  
      >>> m = Matrix([[0.9, -0.1, -0.2, 0], [-0.8, 0.9, -0.4, 0], [-0.1, -0.8, 0.6, 0]])
      >>> m.rref()
      (Matrix([
      [1, 0, 0, 0],
      [0, 1, 0, 0],
      [0, 0, 1, 0]]), (0, 1, 2))
      >>> m.rref(iszerofunc=lambda x:abs(x)<1e-9)
      (Matrix([
      [1, 0, -0.301369863013699, 0],
      [0, 1, -0.712328767123288, 0],
      [0, 0,         0,          0]]), (0, 1))
  
      Notes
      =====
  
      The default value of ``normalize_last=True`` can provide significant
      speedup to row reduction, especially on matrices with symbols.  However,
      if you depend on the form row reduction algorithm leaves entries
      of the matrix, set ``normalize_last=False``
      """
      # Try to use DomainMatrix for ZZ or QQ
      dM = _to_DM_ZZ_QQ(M)
  
      if dM is not None:
          # Use DomainMatrix for ZZ or QQ
          mat, pivot_cols = _rref_dm(dM)
      else:
          # Use the generic Matrix routine.
          if isinstance(simplify, FunctionType):
              simpfunc = simplify
          else:
              simpfunc = _simplify
  
          mat, pivot_cols, _ = _row_reduce(
              M,
              iszerofunc,
              simpfunc,
              normalize_last,
              normalize=True,
              zero_above=True,
          )
  
      if pivots:
          return mat, pivot_cols
      else:
          return mat
  
file_path: sympy/sympy/matrices/reductions.py
imports: from types import FunctionType
  from sympy.polys.polyerrors import CoercionFailed
  from sympy.polys.domains import ZZ, QQ
  from .utilities import _get_intermediate_simp, _iszero, _dotprodsimp, _simplify
  from .determinant import _find_reasonable_pivot
label_desc: Use image node_id 8 for calling a global function with example usage: _rref(M, iszerofunc, simplify, pivots, normalize_last) and returns: mat,  pivot_cols, mat