class_docstr: Functions that operate element-by-element on whole arrays.
  
  This is a class for LAX-backed implementations of numpy ufuncs.
code: def _reduce_via_scan(
      self,
      arr: ArrayLike,
      axis: int = 0,
      dtype: DTypeLike | None = None,
      keepdims: bool = False,
      initial: ArrayLike | None = None,
      where: ArrayLike | None = None,
  ) -> Array:
      assert self.nin == 2 and self.nout == 1
      arr = lax_internal.asarray(arr)
      if initial is None:
          initial = self.identity
      if dtype is None:
          dtype = jax.eval_shape(
              self._func, lax_internal._one(arr), lax_internal._one(arr)
          ).dtype
      if where is not None:
          where = _broadcast_to(where, arr.shape)
      if isinstance(axis, tuple):
          axis = tuple(canonicalize_axis(a, arr.ndim) for a in axis)
          raise NotImplementedError("tuple of axes")
      elif axis is None:
          if keepdims:
              final_shape = (1,) * arr.ndim
          else:
              final_shape = ()
          arr = arr.ravel()
          if where is not None:
              where = where.ravel()
          axis = 0
      else:
          axis = canonicalize_axis(axis, arr.ndim)
          if keepdims:
              final_shape = (
                  *arr.shape[:axis],
                  1,
                  *arr.shape[axis + 1 :],
              )
          else:
              final_shape = (*arr.shape[:axis], *arr.shape[axis + 1 :])
  
      # TODO: handle without transpose?
      if axis != 0:
          arr = _moveaxis(arr, axis, 0)
          if where is not None:
              where = _moveaxis(where, axis, 0)
  
      if initial is None and arr.shape[0] == 0:
          raise ValueError(
              "zero-size array to reduction operation {self.__name__} which has no ideneity"
          )
  
      def body_fun(i, val):
          if where is None:
              return self._call(val, arr[i].astype(dtype))
          else:
              return _where(
                  where[i], self._call(val, arr[i].astype(dtype)), val
              )
  
      start_value: ArrayLike
      if initial is None:
          start_index = 1
          start_value = arr[0]
      else:
          start_index = 0
          start_value = initial
      start_value = _broadcast_to(
          lax_internal.asarray(start_value).astype(dtype), arr.shape[1:]
      )
  
      result = jax.lax.fori_loop(
          start_index, arr.shape[0], body_fun, start_value
      )
  
      if keepdims:
          result = result.reshape(final_shape)
      return result
  
imports: from __future__ import annotations
  from functools import partial
  import math
  import operator
  from typing import Any, Callable
  import jax
  from jax._src.typing import Array, ArrayLike, DTypeLike
  from jax._src.lax import lax
  from jax._src.numpy import reductions
  from jax._src.numpy.lax_numpy import _eliminate_deprecated_list_indexing, append, take
  from jax._src.numpy.reductions import _moveaxis
  from jax._src.numpy.util import _wraps, check_arraylike, _broadcast_to, _where
  from jax._src.numpy.vectorize import vectorize
  from jax._src.util import canonicalize_axis, set_module
  import numpy
label_desc: Use image node_id 7 for calling the ufunc obj's underlying member method code with example usage: obj._reduce_via_scan(arr, axis, dtype, keepdims, initial, where) and returns: result, self, _where