Skip to main content

A Python implementation for sparse Cholesky decomposition of covariance matrices.

Project description

pyKoLesky

pyKoLesky is a PyTorch implementation of the sparse Cholesky decomposition algorithm, building upon the algorithms and concepts presented in the Julia package KoLesky.jl. It implements the sparse Cholesky decomposition algorithm described in the paper "Sparse Cholesky Factorization by Kullback-Leibler Minimization" by Florian Schäfer, Matthias Katzfuss, and Houman Owhadi.

The sparse Cholesky algorithm computes a sparse approximation of the inverse Cholesky upper triangular factor $U$ for a dense covariance matrix $\Theta$. It achieves this by minimizing the Kullback-Leibler divergence between the Gaussian distributions $\mathcal{N}(0, \Theta)$ and $\mathcal{N}(0, (UU^T)^{-1})$, while enforcing a sparsity constraint. This method is a generalization of the Vecchia approximation commonly used in spatial statistics. It enables the computation of $\epsilon$-approximate inverse Cholesky factors of $\Theta$ with a space complexity of $\mathcal{O}(N \log(N/\epsilon)^d)$ and a time complexity of $\mathcal{O}(N \log(N/\epsilon)^{2d})$.

Upcoming Features in Development

  • Parallel computing capabilities
  • Supernode functionality, as explored in the paper "Sparse Cholesky Factorization by Kullback--Leibler Minimization."

Development Status

pyKoLesky is currently under active development, and new features are being added regularly. While we strive to maintain stability, there may be occasional bugs or incomplete features.

We greatly appreciate your feedback! If you encounter any issues, please report them by opening an issue on GitHub. Your contributions and suggestions are welcome!

Related Papers

  • Schäfer, Florian, Matthias Katzfuss, and Houman Owhadi. "Sparse Cholesky Factorization by Kullback--Leibler Minimization." SIAM Journal on scientific computing 43.3 (2021): A2019-A2046.
  • Chen, Yifan, Houman Owhadi, and Florian Schäfer. "Sparse Cholesky factorization for solving nonlinear PDEs via Gaussian processes." Mathematics of Computation (2024).

Installation

You can install pyKoLesky from PyPI using pip:

pip install pyKoLesky

Usage

Basic Usage

Here’s a simple example of how to use pyKoLesky to verify the results of maxmin ordering and validate its correctness by labeling the order of reordered points:

from pyKoLesky.ordering import maximin
import torch
import matplotlib.pyplot as plt

torch.set_default_dtype(torch.float64)


n_points = 20
torch.manual_seed(44)  # For reproducibility
x = torch.rand(n_points, 2)  # 10 points in 2D space

# Perform reverse maximin ordering
indexes, _ = maximin(x)

# Plotting the points with their ordering labels
fig, ax = plt.subplots()
plt.scatter(x[:, 0].numpy(), x[:, 1].numpy(), color='gray', alpha=0.3)

# Label each point with its order
for i, idx in enumerate(indexes):
    plt.text(x[idx, 0].item() + 0.01, x[idx, 1].item(), f'{i + 1}',
             fontsize=12, ha='right', color='red')

plt.show()

The following example demonstrates a process for creating a maxmin ordering, generating the sparse pattern, and performing sparse Cholesky decomposition.

from pyKoLesky.cholesky import *
import torch
import math

torch.set_default_dtype(torch.float64)

if __name__ == '__main__':
    nu = 5/2
    lengthscale = 0.3  # Lengthscale
    h = 0.05  # Grid spacing
    grid_size = int(1 / h)  # Number of points along one dimension

    # Generate equidistributed points in [0, 1]^2
    x = torch.linspace(0, 1, grid_size)
    x= torch.cartesian_prod(x, x)

    def matern_kernel(X1, X2, nu, lengthscale, sigma=1.0):
        # Compute pairwise distances
        dist = torch.cdist(X1, X2, p=2)  # Euclidean distance
        # Common term sqrt(2p+1) / rho
        p = int(nu - 1 / 2)  # Get p from nu = p + 1/2
        sqrt_term = math.sqrt(2 * p + 1) / lengthscale
        exp_term = torch.exp(-sqrt_term * dist)

        block = sqrt_term * dist

        term1 = 1
        term2 = block
        term3 = block ** 2 / 3
        polynomial = term1 + term2 + term3
        K = sigma ** 2 * polynomial * exp_term
        return K

    # Formulate the covariance matrix K
    Theta = matern_kernel(x, x, nu, lengthscale)

    # Sparsity control parameter
    rho = 8

    Perm, lengths = maximin(x)                              #   Maxmin ordering
    sparsity = sparsity_pattern(x[Perm], lengths, rho)      #   Create Sparsity Pattern
    U_sparse = sparse_cholesky(Theta, Perm, sparsity)       #   torch.sparse_coo_tensor structure sparse matrix

    # Convert sparse tensor to dense for validation
    U_dense = U_sparse.to_dense()

    invPerm = torch.argsort(Perm)                           # Compute the inverse ordering

    Theta_ordered = Theta[Perm][:, Perm]
    mtx = U_dense.T @ Theta_ordered @ U_dense
    klerror = 1 / 2 * (-torch.log(torch.linalg.det(mtx)) + torch.trace(mtx) - len(mtx))

    # Output results
    print("\nSparse Cholesky Factor (U):\n", U_dense)
    print("\nReconstruction KL error of Theta^-1:", klerror)

License

pyKoLesky is licensed under the CC-BY-NC 4.0 License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pykolesky-0.1.6.tar.gz (6.2 kB view details)

Uploaded Source

Built Distribution

pykolesky-0.1.6-py2.py3-none-any.whl (7.2 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file pykolesky-0.1.6.tar.gz.

File metadata

  • Download URL: pykolesky-0.1.6.tar.gz
  • Upload date:
  • Size: 6.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.5 CPython/3.13.1 Darwin/24.1.0

File hashes

Hashes for pykolesky-0.1.6.tar.gz
Algorithm Hash digest
SHA256 e022530b04f0593e58013d96516aab0790285e66815cd8e23cd6a17f48a525ce
MD5 b8534ecc2f579084f678746226acb0c3
BLAKE2b-256 9c6da63b13cecf3b1200a9156ca6688c5dc20b7f14a88b607b2d2467bd9f02e4

See more details on using hashes here.

File details

Details for the file pykolesky-0.1.6-py2.py3-none-any.whl.

File metadata

  • Download URL: pykolesky-0.1.6-py2.py3-none-any.whl
  • Upload date:
  • Size: 7.2 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.5 CPython/3.13.1 Darwin/24.1.0

File hashes

Hashes for pykolesky-0.1.6-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 c6d0189c2dd6f1cc34c54df1d26f95a7cbae1d3280c0c3655ef20a98ca428f79
MD5 e241c26fe32b20efc49944d8053a3efb
BLAKE2b-256 604aade2c59a6e7a9bf6dec7bee800d1e6caef10a2fd22a2b1c8e60f745fab8b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page