jax-ml/jax · error · ValueError

jnp.linalg.cond: input array must not be empty; got {arr.sha

Error message

jnp.linalg.cond: input array must not be empty; got {arr.shape=}

What it means

For an (at least 2-D) matrix whose last or second-to-last dimension is 0, the condition number is undefined (svd of an empty matrix yields no singular values to ratio). jnp.linalg.cond explicitly rejects empty matrices with this check instead of producing NaN or crashing in SVD.

Source

Thrown at jax/_src/numpy/linalg.py:2293

    Well-conditioned matrix:

    >>> x = jnp.array([[1, 2],
    ...                [2, 1]])
    >>> jnp.linalg.cond(x)
    Array(3., dtype=float32)

    Ill-conditioned matrix:

    >>> x = jnp.array([[1, 2],
    ...                [0, 0]])
    >>> jnp.linalg.cond(x)
    Array(inf, dtype=float32)
  """
  arr = ensure_arraylike("cond", x)
  if arr.ndim < 2:
    raise ValueError(f"jnp.linalg.cond: input array must be at least 2D; got {arr.shape=}")
  if arr.shape[-1] == 0 or arr.shape[-2] == 0:
    raise ValueError(f"jnp.linalg.cond: input array must not be empty; got {arr.shape=}")
  if p is None or p == 2:
    s = svdvals(x)
    return s[..., 0] / s[..., -1]
  elif p == -2:
    s = svdvals(x)
    r = s[..., -1] / s[..., 0]
  else:
    if arr.shape[-2] != arr.shape[-1]:
      raise ValueError(f"jnp.linalg.cond: for {p=}, array must be square; got {arr.shape=}")
    r = norm(x, ord=p, axis=(-2, -1)) * norm(inv(x), ord=p, axis=(-2, -1))
  # Convert NaNs to infs where original array has no NaNs.
  return jnp.where(ufuncs.isnan(r) & ~ufuncs.isnan(x).any(axis=(-2, -1)), np.inf, r)


@export
def trace(x: ArrayLike, /, *,
          offset: int = 0, dtype: DTypeLike | None = None) -> Array:
  """Compute the trace of a matrix.

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Filter out or skip empty matrices before calling cond.
  2. Check arr.shape[-1] and arr.shape[-2] are non-zero beforehand.
  3. Guard with a jnp.where on batch size if operating on variable-size batches.

Example fix

// before
c = jnp.linalg.cond(mats[valid])  # valid may be all-False -> shape (0, n, n)
// after
if valid.sum() > 0:
    c = jnp.linalg.cond(mats[valid])
else:
    c = jnp.full((), jnp.nan)
Defensive patterns

Strategy: validation

Validate before calling

if arr.shape[-1] == 0 or arr.shape[-2] == 0:
    c = jnp.nan
else:
    c = jnp.linalg.cond(arr)

Type guard

def nonempty_matrix(x) -> bool:
    return x.ndim >= 2 and x.shape[-1] > 0 and x.shape[-2] > 0

Prevention

When it happens

Trigger: jnp.linalg.cond(jnp.zeros((0, 3))) or jnp.zeros((3, 0)); slicing a batch with an empty selection then calling cond on the result.

Common situations: Empty batches after filtering/masking; code that worked on non-empty data hitting a degenerate edge case at runtime (e.g. zero valid rows).

Related errors


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