{"record":{"id":"f165dffe9edd28f7","repo":"jax-ml/jax","slug":"input-array-shapes-must-match-z-z-arr-shape-vs","errorCode":null,"errorMessage":"Input array shapes must match: Z: {Z_arr.shape} vs. T: {T_arr.shape}","messagePattern":"Input array shapes must match: Z: (.+?) vs\\. T: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/linalg.py","lineNumber":2333,"sourceCode":"    By contrast, the complex form is truly upper-triangular:\n\n    >>> with jnp.printoptions(precision=2, suppress=True):\n    ...   print(Tc)\n    [[ 3.76+0.j    1.29-0.78j  2.02-0.5j ]\n     [ 0.  +0.j   -0.88+0.91j -2.02+0.j  ]\n     [ 0.  +0.j    0.  +0.j   -0.88-0.91j]]\n  \"\"\"\n  del check_finite  # unused\n\n  T_arr = jnp.asarray(T)\n  Z_arr = jnp.asarray(Z)\n\n  if T_arr.ndim < 2 or T_arr.shape[-1] != T_arr.shape[-2]:\n    raise ValueError(\"Input 'T' must be square.\")\n  if Z_arr.ndim < 2 or Z_arr.shape[-1] != Z_arr.shape[-2]:\n    raise ValueError(\"Input 'Z' must be square.\")\n  if T_arr.shape[-1] != Z_arr.shape[-1]:\n    raise ValueError(f\"Input array shapes must match: Z: {Z_arr.shape} vs. T: {T_arr.shape}\")\n\n  return jnp_vectorize.vectorize(\n      _rsf2csf_2d, signature=\"(n,n),(n,n)->(n,n),(n,n)\")(T_arr, Z_arr)\n\n@overload\ndef hessenberg(a: ArrayLike, *, calc_q: Literal[False], overwrite_a: bool = False,\n               check_finite: bool = True) -> Array: ...\n\n@overload\ndef hessenberg(a: ArrayLike, *, calc_q: Literal[True], overwrite_a: bool = False,\n               check_finite: bool = True) -> tuple[Array, Array]: ...\n\n\n@jit(static_argnames=('calc_q', 'check_finite', 'overwrite_a'))\ndef hessenberg(a: ArrayLike, *, calc_q: bool = False, overwrite_a: bool = False,\n               check_finite: bool = True) -> Array | tuple[Array, Array]:\n  \"\"\"Compute the Hessenberg form of the matrix\n","sourceCodeStart":2315,"sourceCodeEnd":2351,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/linalg.py#L2315-L2351","documentation":"rsf2csf requires T and Z to describe the same problem, so their trailing dimensions must match exactly (T.shape[-1] == Z.shape[-1]). Mismatched sizes (e.g. T is 4x4 and Z is 3x3) raise ValueError with both shapes in the message.","triggerScenarios":"Calling rsf2csf(T, Z) where T and Z come from Schur decompositions of different-sized matrices, or one was sliced/reshaped independently of the other.","commonSituations":"Caching or reusing factors across iterations where matrix size changed; mixing batch entries from different runs; off-by-one slicing of batched factors.","solutions":["Recompute both T and Z from the same schur(a, calc_q=True) call","Assert T.shape[-1] == Z.shape[-1] before calling","If batching, ensure both arrays have matching batch dims too"],"exampleFix":"# before\nT, _ = schur(a, calc_q=False)\n_, Z = schur(b, calc_q=True)  # different size than a\nTc, Zc = rsf2csf(T, Z)\n# after\nT, Z = schur(a, calc_q=True)\nTc, Zc = rsf2csf(T, Z)","handlingStrategy":"validation","validationCode":"T, Z = jnp.asarray(T), jnp.asarray(Z)\nif T.shape[-1] != Z.shape[-1]:\n    raise ValueError(f'T/Z size mismatch: {T.shape} vs {Z.shape}')\nTc, Zc = rsf2csf(T, Z)","typeGuard":null,"tryCatchPattern":"try:\n    rsf2csf(T, Z)\nexcept ValueError as e:\n    if 'shapes must match' in str(e):\n        T, Z = schur(A, calc_q=True); rsf2csf(T, Z)\n    else: raise","preventionTips":["Never cache one factor across problems of changing size","Pair T and Z atomically (return both from one function)","Assert matching trailing dims in batched pipelines"],"tags":["jax","rsf2csf","shape-mismatch"],"backgroundTag":"matrix-shape-mismatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}