jax-ml/jax · error · ValueError

Got empty index range in select_range.

Error message

Got empty index range in select_range.

What it means

With select='i', eigh_tridiagonal requires an ascending index range; if select_range[0] > select_range[1] the range is empty and no eigenvalues would be selected, so ValueError is raised.

Source

Thrown at jax/_src/scipy/linalg.py:1837

  abs_tol = finfo.eps * t_norm
  if tol is not None:
    abs_tol = jnp.maximum(tol, abs_tol)

  # In the worst case, when the absolute tolerance is eps*lambda_est_max and
  # lambda_est_max = -lambda_est_min, we have to take as many bisection steps
  # as there are bits in the mantissa plus 1.
  # The proof is left as an exercise to the reader.
  max_it = finfo.nmant + 1

  # Determine the indices of the desired eigenvalues, based on select and
  # select_range.
  if select == 'a':
    target_counts = jnp.arange(n, dtype=np.int32)
  elif select == 'i':
    if select_range is None:
      raise ValueError("for select='i', select_range must be specified.")
    if select_range[0] > select_range[1]:
      raise ValueError('Got empty index range in select_range.')
    target_counts = jnp.arange(select_range[0], select_range[1] + 1, dtype=np.int32)
  elif select == 'v':
    # TODO(phawkins): requires dynamic shape support.
    raise NotImplementedError("eigh_tridiagonal(..., select='v') is not "
                              "implemented")
  else:
    raise ValueError("'select must have a value in {'a', 'i', 'v'}.")

  # Run binary search for all desired eigenvalues in parallel, starting from
  # the interval lightly wider than the estimated
  # [lambda_est_min, lambda_est_max].
  fudge = 2.1  # We widen starting interval the Gershgorin interval a bit.
  norm_slack = jnp.array(n, alpha.dtype) * fudge * finfo.eps * t_norm
  lower = lambda_est_min - norm_slack - 2 * fudge * pivmin
  upper = lambda_est_max + norm_slack + fudge * pivmin

  # Pre-broadcast the scalars used in the Sturm sequence for improved
  # performance.

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Swap the bounds so lo <= hi: select_range=(min(lo, hi), max(lo, hi))
  2. Validate the range before calling and clamp/skip when empty

Example fix

// before
w = jax.scipy.linalg.eigh_tridiagonal(d, e, select='i', select_range=(hi, lo))
// after
w = jax.scipy.linalg.eigh_tridiagonal(d, e, select='i', select_range=(lo, hi))
Defensive patterns

Strategy: validation

Validate before calling

if select == 'i': assert select_range[0] <= select_range[1], 'select_range must be ascending'

Type guard

null

Prevention

When it happens

Trigger: Calling eigh_tridiagonal(d, e, select='i', select_range=(5, 2)) or with swapped bounds produced by user input or a config mistake.

Common situations: Off-by-one or swapped (lo, hi) variables; ranges computed as (hi, lo) by mistake in a search routine.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/cdea75dcee188b13. Report an issue: GitHub.