{"record":{"id":"faef98206a737161","repo":"jax-ml/jax","slug":"incompatible-shapes-for-sylvester-equation-a-a","errorCode":null,"errorMessage":"Incompatible shapes for Sylvester equation:\nA: {A.shape}\nB: {B.shape}\nC: {C.shape}","messagePattern":"Incompatible shapes for Sylvester equation:\nA: (.+?)\nB: (.+?)\nC: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/linalg.py","lineNumber":3364,"sourceCode":"    the eigen decomposition method because you need to perform a Schur decomposition and then scan the entire solution matrix.\n    Second, it requires more system memory compared to the eigen decomposition method.\n\n    The eigen decomposition method is the fastest method to solve a sylvester equation. However, this speed brings with it a couple of drawbacks.\n    First, A and B must be diagonalizable otherwise the eigenvectors will be linearly dependent and ill-conditioned leading to accuracy issues.\n    Second, when the eigenvectors are not orthogonal roundoff errors are amplified.\n\n    Additionally, for complex types as the size of the matrix increases the accuracy of the results degrades. Float64 types are most robust to degradation.\n\n    The tol argument allows you to specify how ill-conditioned a matrix can be and still estimate a solution.\n    For matrices that are ill-conditioned we recommend using float64 instead of the default float32 dtype. The solver\n    can still return good estimates for ill-conditioned matrices depending on how close to zero the sums of the eigenvalues of A and B\n    are.\n  \"\"\"\n  A, B, C = promote_dtypes_inexact(jnp.asarray(A), jnp.asarray(B), jnp.asarray(C))\n\n  m, n = C.shape[-2:]\n  if A.shape[-2:] != (m, m) or B.shape[-2:] != (n, n):\n    raise ValueError(f\"Incompatible shapes for Sylvester equation:\\nA: {A.shape}\\nB: {B.shape}\\nC: {C.shape}\")\n\n  return jnp_vectorize.vectorize(\n      partial(_solve_sylvester_2d, method=method, tol=tol),\n      signature=\"(m,m),(n,n),(m,n)->(m,n)\")(A, B, C)\n","sourceCodeStart":3346,"sourceCodeEnd":3369,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/linalg.py#L3346-L3369","documentation":"For the Sylvester equation AX + XB = C, C's last two dims (m, n) dictate that A be (m, m) and B be (n, n). JAX validates these trailing shapes after dtype promotion and before vectorizing over batch dims.","triggerScenarios":"Passing A of shape (m, k), B of shape (k, n), or C with shape not matching A/B sizes, e.g. transposed C.","commonSituations":"Building equation data from training batches where matrices got flattened or transposed; assuming B is (m, m) like A.","solutions":["Check C.shape[-2:] == (m, n), A.shape[-2:] == (m, m), B.shape[-2:] == (n, n) and transpose/reshape inputs accordingly","Verify you are not confusing the row/column dimensions of C with A vs B","Add an assert before calling in test code"],"exampleFix":"# before\nX = linalg.solve_sylvester(A, B, C.T)  # wrong orientation\n# after\nm, n = C.shape[-2:]\nassert A.shape[-2:] == (m, m) and B.shape[-2:] == (n, n)\nX = linalg.solve_sylvester(A, B, C)","handlingStrategy":"validation","validationCode":"m, n = C.shape[-2:]\nassert A.shape[-2:] == (m, m) and B.shape[-2:] == (n, n)","typeGuard":"def sylvester_shapes_ok(A, B, C) -> bool:\n    m, n = C.shape[-2:]\n    return A.shape[-2:] == (m, m) and B.shape[-2:] == (n, n)","tryCatchPattern":null,"preventionTips":["Write a shape precondition helper for solver wrappers"],"tags":["jax","scipy","linalg","shape-mismatch","sylvester"],"backgroundTag":"matrix-shape-mismatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}