jax-ml/jax · error · ValueError

n must be a positive power of 2; got {n}.

Error message

n must be a positive power of 2; got {n}.

What it means

jax.scipy.linalg.hadamard requires n to be a positive power of 2 because the matrix is built by lg2 = log2(n) recursive Sylvester blocking steps. math.log2(n).is_integer() fails for non-powers (and math.log2 of 0/negatives errors, hence the n < 1 guard).

Source

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

  construction: :math:`H_1 = [[1]]`, and
  :math:`H_{2m} = \begin{bmatrix} H_m & H_m \\ H_m & -H_m \end{bmatrix}`.

  Args:
    n: size of the matrix. Must be a positive power of 2.
    dtype: output dtype. Defaults to ``int``.

  Returns:
    A Hadamard matrix of shape ``(n, n)``.

  Examples:
    >>> jax.scipy.linalg.hadamard(4)
    Array([[ 1,  1,  1,  1],
           [ 1, -1,  1, -1],
           [ 1,  1, -1, -1],
           [ 1, -1, -1,  1]], dtype=int32)
  """
  if n < 1 or not math.log2(n).is_integer():
    raise ValueError(
        f"n must be a positive power of 2; got {n}.")
  lg2 = int(math.log2(n))
  H = jnp.ones((1, 1), dtype=dtype)
  for _ in range(lg2):
    H = jnp.block([[H, H], [H, -H]])
  return H


@jit(static_argnames=("n", "scale", "dtype"))
def dft(n: int, scale: str | None = None, *,
        dtype: DTypeLike | None = None) -> Array:
  r"""Construct an n-by-n discrete Fourier transform matrix.

  JAX implementation of :func:`scipy.linalg.dft`.

  The DFT matrix :math:`W_n` has entries :math:`W_{ij} = \omega^{ij}`, where
  :math:`\omega = e^{-2\pi i / n}` is the primitive n-th root of unity, for
  :math:`0 \le i, j < n`.

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Pad n up to the next power of two (e.g. n = 1 << (n-1).bit_length()) and slice the result if needed
  2. Fix n to a power of 2 like 2**k in experiment configs
  3. Validate n before calling

Example fix

# before
H = linalg.hadamard(x.shape[1])  # 768 -> error
# after
p = 1 << (x.shape[1] - 1).bit_length()
H = linalg.hadamard(p)[:x.shape[1], :x.shape[1]]  # or pad x instead
Defensive patterns

Strategy: validation

Validate before calling

assert n >= 1 and (n & (n - 1)) == 0, f'n={n} not a power of 2'

Type guard

def is_pow2(n: int) -> bool: return n >= 1 and (n & (n - 1)) == 0

Prevention

When it happens

Trigger: Calling hadamard(3), hadamard(12), hadamard(0), or hadamard(-4); computing n from data sizes like hadamard(num_features).

Common situations: Using Hadamard transforms in ML pipelines where the dimension is the feature count (e.g. 768) rather than a padded power of two.

Related errors


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