{"record":{"id":"8431acd29a418e30","repo":"keras-team/keras","slug":"cholesky-decomposition-failed-e","errorCode":null,"errorMessage":"Cholesky decomposition failed: {e}","messagePattern":"Cholesky decomposition failed: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/ops/linalg.py","lineNumber":48,"sourceCode":"        upper (bool): If True, returns the upper-triangular Cholesky factor.\n            If False (default), returns the lower-triangular Cholesky factor.\n\n    Returns:\n        A tensor of shape `(..., M, M)` representing the Cholesky factor of `x`.\n    \"\"\"\n    if any_symbolic_tensors((x,)):\n        return Cholesky(upper=upper).symbolic_call(x)\n    return _cholesky(x, upper=upper)\n\n\ndef _cholesky(x, upper=False):\n    x = backend.convert_to_tensor(x)\n    _assert_2d(x)\n    _assert_square(x)\n    try:\n        return backend.linalg.cholesky(x, upper=upper)\n    except Exception as e:\n        raise ValueError(f\"Cholesky decomposition failed: {e}\")\n\n\nclass CholeskyInverse(Operation):\n    def __init__(self, upper=False, *, name=None):\n        super().__init__(name=name)\n        self.upper = upper\n\n    def call(self, x):\n        return _cholesky_inverse(x, self.upper)\n\n    def compute_output_spec(self, x):\n        _assert_2d(x)\n        _assert_square(x)\n        return KerasTensor(x.shape, x.dtype)\n\n\n@keras_export(\n    [\"keras.ops.cholesky_inverse\", \"keras.ops.linalg.cholesky_inverse\"]","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/ops/linalg.py#L30-L66","documentation":"The Cholesky op validates 2D square input, then delegates to backend.linalg.cholesky; any backend exception (typically a non-positive-definite or non-Hermitian matrix) is wrapped in this ValueError, with the backend's numeric failure text embedded.","triggerScenarios":"keras.ops.linalg.cholesky(cov) where cov has negative or zero eigenvalues; a covariance matrix estimated from fewer samples than dimensions; matrices with numerical asymmetry from float error.","commonSituations":"Gaussian-process or multivariate-normal sampling code; Cholesky-based preconditioners; a model parameterizing a matrix meant to be SPD whose eigenvalues drift to zero during training.","solutions":["Check eigenvalues: the smallest must be > 0; fix matrix construction if not.","Add jitter to the diagonal: x + eps * eye(n) with eps ~1e-6..1e-3.","If symmetry was lost numerically, symmetrize: (x + x.T) / 2.","If semi-definite is intended, use eigenvalue clipping or a sqrtm-based path instead of Cholesky."],"exampleFix":"# before\nL = keras.ops.linalg.cholesky(cov)\n\n# after\nimport numpy as np\ncov_reg = cov + 1e-6 * np.eye(cov.shape[-1])\nL = keras.ops.linalg.cholesky(cov_reg)","handlingStrategy":"try-catch","validationCode":"import numpy as np\neigvals = np.linalg.eigvalsh(np.asarray(x))\nif eigvals.min() <= 0:\n    x = x + (abs(eigvals.min()) + 1e-6) * np.eye(x.shape[-1])","typeGuard":"def is_spd(x, tol=1e-10):\n    x = np.asarray(x)\n    return x.ndim == 2 and x.shape[0] == x.shape[1] and np.allclose(x, x.T) and np.linalg.eigvalsh(x).min() > tol","tryCatchPattern":"try:\n    L = keras.ops.linalg.cholesky(x)\nexcept ValueError as e:\n    if 'Cholesky decomposition failed' in str(e):\n        L = keras.ops.linalg.cholesky(x + 1e-6 * np.eye(x.shape[-1]))\n    else:\n        raise","preventionTips":["Parameterize SPD matrices via log-diagonal plus low-rank form in models.","Always add jitter before factorizing estimated covariances.","Symmetrize with (x + x.T) / 2 before calling."],"tags":["keras","linalg","cholesky","positive-definite"],"backgroundTag":"matrix-not-positive-definite","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}