Coverage for src / cvx / risk / linalg / cholesky.py: 100%
5 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-09 03:39 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-09 03:39 +0000
1"""Cholesky decomposition utilities for covariance matrices.
3This module provides a function to compute the upper triangular Cholesky
4decomposition of a positive definite covariance matrix.
6Example:
7 Compute the Cholesky decomposition of a covariance matrix:
9 >>> import numpy as np
10 >>> from cvx.risk.linalg import cholesky
11 >>> # Create a positive definite matrix
12 >>> cov = np.array([[4.0, 2.0], [2.0, 5.0]])
13 >>> # Compute upper triangular Cholesky factor
14 >>> R = cholesky(cov)
15 >>> # Verify: R.T @ R = cov
16 >>> np.allclose(R.T @ R, cov)
17 True
19"""
21# Copyright 2023 Stanford University Convex Optimization Group
22#
23# Licensed under the Apache License, Version 2.0 (the "License");
24# you may not use this file except in compliance with the License.
25# You may obtain a copy of the License at
26#
27# http://www.apache.org/licenses/LICENSE-2.0
28#
29# Unless required by applicable law or agreed to in writing, software
30# distributed under the License is distributed on an "AS IS" BASIS,
31# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32# See the License for the specific language governing permissions and
33# limitations under the License.
34from __future__ import annotations
36import numpy as np
37from numpy.linalg import cholesky as _cholesky
40def cholesky(cov: np.ndarray) -> np.ndarray:
41 """Compute the upper triangular part of the Cholesky decomposition.
43 This function computes the Cholesky decomposition of a positive definite matrix
44 and returns the upper triangular matrix R such that R^T @ R = cov.
46 The Cholesky decomposition is useful in portfolio optimization because it
47 provides an efficient way to compute portfolio risk as ||R @ w||_2, where
48 w is the portfolio weights vector.
50 Args:
51 cov: A positive definite covariance matrix of shape (n, n).
53 Returns:
54 The upper triangular Cholesky factor R of shape (n, n).
56 Example:
57 Basic usage with a simple covariance matrix:
59 >>> import numpy as np
60 >>> from cvx.risk.linalg import cholesky
61 >>> # Identity matrix
62 >>> cov = np.eye(3)
63 >>> R = cholesky(cov)
64 >>> np.allclose(R, np.eye(3))
65 True
67 With a more complex covariance matrix:
69 >>> cov = np.array([[1.0, 0.5, 0.0],
70 ... [0.5, 1.0, 0.5],
71 ... [0.0, 0.5, 1.0]])
72 >>> R = cholesky(cov)
73 >>> np.allclose(R.T @ R, cov)
74 True
76 Verify upper triangular structure:
78 >>> R = cholesky(np.array([[4.0, 2.0], [2.0, 5.0]]))
79 >>> # R is upper triangular (zeros below diagonal)
80 >>> bool(np.allclose(R[1, 0], 0.0))
81 True
82 >>> bool(R[0, 0] > 0 and R[1, 1] > 0) # Positive diagonal
83 True
85 Portfolio risk computation via Cholesky factor:
87 >>> cov = np.array([[0.04, 0.01], [0.01, 0.09]])
88 >>> R = cholesky(cov)
89 >>> w = np.array([0.6, 0.4])
90 >>> # Risk via Cholesky: ||R @ w||_2
91 >>> risk_chol = np.linalg.norm(R @ w)
92 >>> # Risk via covariance: sqrt(w^T @ cov @ w)
93 >>> risk_cov = np.sqrt(w @ cov @ w)
94 >>> bool(np.isclose(risk_chol, risk_cov))
95 True
97 Relationship between upper (R) and lower (L) triangular factors:
99 >>> cov = np.array([[9.0, 3.0], [3.0, 5.0]])
100 >>> R = cholesky(cov)
101 >>> L = np.linalg.cholesky(cov) # numpy returns lower triangular
102 >>> # R = L^T
103 >>> np.allclose(R, L.T)
104 True
105 >>> # Both reconstruct the covariance
106 >>> np.allclose(L @ L.T, cov)
107 True
108 >>> np.allclose(R.T @ R, cov)
109 True
111 Note:
112 This function returns the upper triangular factor (R), whereas
113 numpy.linalg.cholesky returns the lower triangular factor (L).
114 The relationship is: L @ L^T = cov and R^T @ R = cov, where R = L^T.
116 """
117 return _cholesky(cov).transpose()