Skip to main content

Block Quasi-Minimal-Residual sparse linear solver

Project description

BlockSolver - Block Quasi-Minimal Residual (BLQMR) Sparse Linear Solver

BlockSolver is a Python package for solving large sparse linear systems using the Block Quasi-Minimal Residual (BLQMR) algorithm. It provides both a high-performance Fortran backend and a pure Python/NumPy implementation for maximum portability.

Features

  • Block QMR Algorithm: Efficiently solves multiple right-hand sides simultaneously
  • Complex Symmetric Support: Designed for complex symmetric matrices (A = Aᵀ, not A = A†)
  • Dual Backend: Fortran extension for speed, Python fallback for portability
  • Flexible Preconditioning: ILU, diagonal (Jacobi), and split preconditioners
  • SciPy Integration: Works seamlessly with SciPy sparse matrices
  • Optional Numba Acceleration: JIT-compiled kernels for the Python backend

Algorithm

Block Quasi-Minimal Residual (BLQMR)

The BLQMR algorithm is an iterative Krylov subspace method specifically designed for:

  1. Complex symmetric systems: Unlike standard methods that assume Hermitian (A = A†) or general matrices, BLQMR exploits complex symmetry (A = Aᵀ) which arises in electromagnetics, acoustics, and diffuse optical tomography.

  2. Multiple right-hand sides: Instead of solving each system independently, BLQMR processes all right-hand sides together in a block fashion, sharing Krylov subspace information and reducing total computation.

  3. Quasi-minimal residual: The algorithm minimizes a quasi-residual norm at each iteration, providing smooth convergence without the erratic behavior of some Krylov methods.

Key Components

  • Quasi-QR Decomposition: A modified Gram-Schmidt process using the quasi inner product ⟨x,y⟩ = Σ xₖyₖ (without conjugation) for complex symmetric systems.

  • Three-term Lanczos Recurrence: Builds an orthonormal basis for the Krylov subspace with short recurrences, minimizing memory usage.

  • Block Updates: Processes m right-hand sides simultaneously, with typical block sizes of 1-64.

When to Use BLQMR

Use Case Recommendation
Complex symmetric matrix (A = Aᵀ) ✅ Ideal
Multiple right-hand sides ✅ Ideal
Real symmetric positive definite Consider CG first
General non-symmetric Consider GMRES or BiCGSTAB
Very large systems (>10⁶ unknowns) ✅ Good with preconditioning

Installation

From PyPI

pip install blocksolver

From Source

Prerequisites:

  • Python ≥ 3.8
  • NumPy ≥ 1.20
  • SciPy ≥ 1.0
  • (Optional) Fortran compiler + UMFPACK for the accelerated backend
  • (Optional) Numba for accelerated Python backend
# Ubuntu/Debian
sudo apt install gfortran libsuitesparse-dev libblas-dev liblapack-dev

# macOS
brew install gcc suite-sparse openblas

# Install
cd python
pip install .

Quick Start

import numpy as np
from scipy.sparse import csc_matrix
from blocksolver import blqmr

# Create a sparse matrix
A = csc_matrix([
    [4, 1, 0, 0],
    [1, 4, 1, 0],
    [0, 1, 4, 1],
    [0, 0, 1, 4]
], dtype=float)

b = np.array([1., 2., 3., 4.])

# Solve Ax = b
result = blqmr(A, b, tol=1e-10)

print(f"Solution: {result.x}")
print(f"Converged: {result.converged}")
print(f"Iterations: {result.iter}")
print(f"Relative residual: {result.relres:.2e}")

Usage

Main Interface: blqmr()

The primary function blqmr() automatically selects the best available backend (Fortran if available, otherwise Python).

from blocksolver import blqmr, BLQMR_EXT

# Check which backend is active
print(f"Using Fortran backend: {BLQMR_EXT}")

# Basic usage
result = blqmr(A, b)

# With options
result = blqmr(A, b, 
    tol=1e-8,              # Convergence tolerance
    maxiter=1000,          # Maximum iterations
    precond_type='ilu',    # Preconditioner: 'ilu', 'diag', or None
)

Multiple Right-Hand Sides

BLQMR excels when solving the same system with multiple right-hand sides:

import numpy as np
from blocksolver import blqmr

# 100 different right-hand sides
B = np.random.randn(n, 100)

# Solve all systems at once (much faster than solving individually)
result = blqmr(A, B, tol=1e-8)

# result.x has shape (n, 100)

Complex Symmetric Systems

BLQMR is specifically designed for complex symmetric matrices (common in frequency-domain wave problems):

import numpy as np
from blocksolver import blqmr

# Complex symmetric matrix (A = A.T, NOT A.conj().T)
A = create_helmholtz_matrix(frequency=1000)  # Your application
b = np.complex128(source_term)

result = blqmr(A, b, tol=1e-8, precond_type='diag')

Preconditioning

BlockSolver supports multiple preconditioner types for both backends:

from blocksolver import blqmr, make_preconditioner

# Using precond_type parameter (works with both backends)
result = blqmr(A, b, precond_type='ilu')    # Incomplete LU
result = blqmr(A, b, precond_type='diag')   # Diagonal (Jacobi)
result = blqmr(A, b, precond_type=None)     # No preconditioning

# Custom preconditioner (Python backend only)
M1 = make_preconditioner(A, 'ilu', drop_tol=1e-4, fill_factor=10)
result = blqmr(A, b, M1=M1, precond_type=None)

# Split preconditioning for symmetric systems (Python backend)
# Preserves symmetry: M1^{-1} A M2^{-1}
M = make_preconditioner(A, 'diag', split=True)  # Returns sqrt(D)
result = blqmr(A, b, M1=M, M2=M, precond_type=None)

SciPy-Compatible Interface

For drop-in replacement in existing code:

from blocksolver import blqmr_scipy

# Returns (x, flag) like scipy.sparse.linalg solvers
x, flag = blqmr_scipy(A, b, tol=1e-10)

Low-Level CSC Interface

For maximum control, use the CSC component interface:

from blocksolver import blqmr_solve

# CSC format components (0-based indexing)
Ap = np.array([0, 2, 5, 9, 10, 12], dtype=np.int32)  # Column pointers
Ai = np.array([0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4], dtype=np.int32)  # Row indices
Ax = np.array([2., 3., 3., -1., 4., 4., -3., 1., 2., 2., 6., 1.])  # Values
b = np.array([8., 45., -3., 3., 19.])

result = blqmr_solve(Ap, Ai, Ax, b, 
    tol=1e-8,
    droptol=0.001,         # ILU drop tolerance (Fortran backend only)
    precond_type='ilu',    # Preconditioner type
    zero_based=True,       # 0-based indexing (default)
)

API Reference

blqmr(A, B, **kwargs) -> BLQMRResult

Main solver interface.

Parameters:

Parameter Type Default Description
A sparse matrix or ndarray required System matrix (n × n)
B ndarray required Right-hand side (n,) or (n × m)
tol float 1e-6 Convergence tolerance
maxiter int n Maximum iterations
M1, M2 preconditioner None Custom preconditioners (Python backend)
x0 ndarray None Initial guess
precond_type str or None 'ilu' Preconditioner: 'ilu', 'diag', or None
droptol float 0.001 ILU drop tolerance (Fortran backend)
residual bool False Use true residual for convergence (Python)
workspace BLQMRWorkspace None Pre-allocated workspace (Python)

Returns: BLQMRResult object with:

Attribute Type Description
x ndarray Solution vector(s)
flag int 0=converged, 1=maxiter, 2=precond fail, 3=stagnation
iter int Iterations performed
relres float Final relative residual
converged bool True if flag == 0
resv ndarray Residual history (Python backend only)

blqmr_solve(Ap, Ai, Ax, b, **kwargs) -> BLQMRResult

Low-level CSC interface for single RHS.

blqmr_solve_multi(Ap, Ai, Ax, B, **kwargs) -> BLQMRResult

Low-level CSC interface for multiple right-hand sides.

blqmr_scipy(A, b, **kwargs) -> Tuple[ndarray, int]

SciPy-compatible interface returning (x, flag).

make_preconditioner(A, precond_type, **kwargs) -> Preconditioner

Create a preconditioner for the Python backend.

Parameters:

Parameter Type Default Description
A sparse matrix required System matrix
precond_type str required 'diag', 'jacobi', 'ilu', 'ilu0', 'ilut', 'lu', 'ssor'
split bool False Return sqrt(D) for split preconditioning
drop_tol float 1e-4 Drop tolerance for ILUT
fill_factor float 10 Fill factor for ILUT
omega float 1.0 Relaxation parameter for SSOR

Utility Functions

from blocksolver import (
    BLQMR_EXT,        # True if Fortran backend available
    HAS_NUMBA,        # True if Numba acceleration available
    get_backend_info, # Returns dict with backend details
    test,             # Run built-in tests
)

Benchmarks

BLQMR vs Direct Solver (mldivide)

Complex symmetric FEM matrices, 4 right-hand sides, tolerance 10⁻⁸, split Jacobi preconditioner:

Grid Nodes NNZ mldivide BLQMR Speedup
20³ 8,000 110K 135ms 115ms 1.2×
30³ 27,000 384K 1.36s 373ms 3.6×
40³ 64,000 922K 6.40s 947ms 6.8×
50³ 125,000 1.8M 25.9s 1.76s 14.7×

Block Size Efficiency

With 64 RHS on a 8,000-node complex symmetric system:

Block Size Iterations Speedup vs Single
1 (point) 10,154 1.0×
4 2,220 1.8×
8 956 2.0×
16 361 2.1×
32 178 2.2×

Optimal block size: 8-16 for most problems. Larger blocks have diminishing returns due to increased per-iteration cost.

Iteration Efficiency

With 4 RHS, BLQMR uses only ~24% of total iterations compared to 4 separate single-RHS solves — achieving super-linear block acceleration.

Performance Tips

  1. Use the Fortran backend when available (faster for large systems)

  2. Enable preconditioning for ill-conditioned systems:

    result = blqmr(A, b, precond_type='ilu')
    
  3. Batch multiple right-hand sides instead of solving one at a time:

    # Fast: single call with all RHS
    result = blqmr(A, B_matrix)
    
    # Slow: multiple calls
    for b in B_columns:
        result = blqmr(A, b)
    
  4. Install Numba for faster Python backend:

    pip install numba
    
  5. Reuse workspace for repeated solves with the same dimensions:

    from blocksolver import BLQMRWorkspace
    ws = BLQMRWorkspace(n, m, dtype=np.complex128)
    for b in many_rhs:
        result = blqmr(A, b, workspace=ws)
    
  6. Use split Jacobi for complex symmetric systems:

    # Preserves symmetry of preconditioned system
    M = make_preconditioner(A, 'diag', split=True)
    result = blqmr(A, b, M1=M, M2=M, precond_type=None)
    

Examples

Diffuse Optical Tomography

import numpy as np
from scipy.sparse import diags, kron, eye
from blocksolver import blqmr

def create_diffusion_matrix(nx, ny, D=1.0, mu_a=0.01, omega=1e9):
    """Create 2D diffusion matrix for DOT."""
    n = nx * ny
    h = 1.0 / nx
    
    # Laplacian
    Lx = diags([-1, 2, -1], [-1, 0, 1], shape=(nx, nx)) / h**2
    Ly = diags([-1, 2, -1], [-1, 0, 1], shape=(ny, ny)) / h**2
    L = kron(eye(ny), Lx) + kron(Ly, eye(nx))
    
    # Diffusion equation: (-D∇² + μ_a + iω/c) φ = q
    c = 3e10  # speed of light in tissue (cm/s)
    A = -D * L + mu_a * eye(n) + 1j * omega / c * eye(n)
    
    return A.tocsc()

# Setup problem
A = create_diffusion_matrix(100, 100, omega=2*np.pi*100e6)
sources = np.random.randn(10000, 16) + 0j  # 16 source positions

# Solve for all sources at once
result = blqmr(A, sources, tol=1e-8, precond_type='diag')
print(f"Solved {sources.shape[1]} systems in {result.iter} iterations")

Frequency-Domain Acoustics

import numpy as np
from blocksolver import blqmr

# Helmholtz equation: (∇² + k²)p = f
# Results in complex symmetric matrix

def solve_helmholtz(K, M, f, frequencies):
    """Solve Helmholtz at multiple frequencies."""
    solutions = []
    for omega in frequencies:
        # A = K - ω²M (complex symmetric if K, M are symmetric)
        A = K - omega**2 * M
        result = blqmr(A, f, tol=1e-10, precond_type='diag')
        solutions.append(result.x)
    return np.array(solutions)

Troubleshooting

"No Fortran backend available"

Install the package with Fortran support:

# Install dependencies first
sudo apt install gfortran libsuitesparse-dev  # Linux
brew install gcc suite-sparse                  # macOS

# Reinstall blocksolver
pip install --no-cache-dir blocksolver

Check backend status

from blocksolver import get_backend_info
print(get_backend_info())
# {'backend': 'binary', 'has_fortran': True, 'has_numba': True}

Slow convergence

  1. Enable preconditioning: precond_type='ilu' or precond_type='diag'
  2. Reduce ILU drop tolerance: droptol=1e-4 (Fortran backend)
  3. Check matrix conditioning with np.linalg.cond(A.toarray())

ILU factorization fails

For indefinite or complex symmetric matrices, ILU may fail:

# Fall back to diagonal preconditioner
result = blqmr(A, b, precond_type='diag')

Memory issues with large systems

  1. Use the Fortran backend (more memory efficient)
  2. Reduce block size for multiple RHS
  3. Use iterative refinement instead of tighter tolerance

License

BSD-3-Clause or GPL-3.0+ (dual-licensed)

Citation

If you use BlockSolver in your research, please cite:

@software{blocksolver,
  author = {Qianqian Fang},
  title = {BlockSolver: Block Quasi-Minimal Residual Sparse Linear Solver},
  url = {https://github.com/fangq/blit},
  year = {2024}
}

See Also

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

blocksolver-0.9.1-cp314-cp314-win_amd64.whl (11.4 MB view details)

Uploaded CPython 3.14Windows x86-64

blocksolver-0.9.1-cp314-cp314-macosx_15_0_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.14macOS 15.0+ x86-64

blocksolver-0.9.1-cp314-cp314-macosx_14_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.14macOS 14.0+ ARM64

blocksolver-0.9.1-cp313-cp313-win_amd64.whl (11.2 MB view details)

Uploaded CPython 3.13Windows x86-64

blocksolver-0.9.1-cp313-cp313-macosx_15_0_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.13macOS 15.0+ x86-64

blocksolver-0.9.1-cp313-cp313-macosx_14_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.13macOS 14.0+ ARM64

blocksolver-0.9.1-cp312-cp312-win_amd64.whl (11.2 MB view details)

Uploaded CPython 3.12Windows x86-64

blocksolver-0.9.1-cp312-cp312-macosx_15_0_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.12macOS 15.0+ x86-64

blocksolver-0.9.1-cp312-cp312-macosx_14_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.12macOS 14.0+ ARM64

blocksolver-0.9.1-cp311-cp311-win_amd64.whl (11.2 MB view details)

Uploaded CPython 3.11Windows x86-64

blocksolver-0.9.1-cp311-cp311-macosx_15_0_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.11macOS 15.0+ x86-64

blocksolver-0.9.1-cp311-cp311-macosx_14_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.11macOS 14.0+ ARM64

blocksolver-0.9.1-cp310-cp310-win_amd64.whl (11.2 MB view details)

Uploaded CPython 3.10Windows x86-64

blocksolver-0.9.1-cp310-cp310-macosx_15_0_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.10macOS 15.0+ x86-64

blocksolver-0.9.1-cp310-cp310-macosx_14_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.10macOS 14.0+ ARM64

blocksolver-0.9.1-cp39-cp39-win_amd64.whl (11.2 MB view details)

Uploaded CPython 3.9Windows x86-64

blocksolver-0.9.1-cp39-cp39-macosx_15_0_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.9macOS 15.0+ x86-64

blocksolver-0.9.1-cp39-cp39-macosx_14_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.9macOS 14.0+ ARM64

blocksolver-0.9.1-cp38-cp38-win_amd64.whl (11.2 MB view details)

Uploaded CPython 3.8Windows x86-64

blocksolver-0.9.1-cp38-cp38-macosx_15_0_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.8macOS 15.0+ x86-64

blocksolver-0.9.1-cp38-cp38-macosx_14_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.8macOS 14.0+ ARM64

File details

Details for the file blocksolver-0.9.1-cp314-cp314-win_amd64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 4dedfe04e05b2b6fb0ed1c9cae75b80587cdf0c88c5aa83aa3b1d832b3c73e52
MD5 295752496c3654e4691d274b05d8a238
BLAKE2b-256 1e4cfc721c24087eeb72ab92d1440041260436e1def971f7ddff7923b705b8f9

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp314-cp314-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp314-cp314-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 bab5de2a503a22554649cd0aaf714be46a72c5f03556e55ab6ff546e574c6577
MD5 5c6165fc8c08bda759c6d34fbb96960d
BLAKE2b-256 41f3f672804dd4be0225f430836f45951096b3d9448ac20529990fec10d1a967

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp314-cp314-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp314-cp314-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 2c5063bf01964d062ab803da002ec7e347cda4f25d1c7dfb6857cd44c5c583e6
MD5 bbb7d29e5f2b58ee5a6e114207799c59
BLAKE2b-256 5414355076ea5ccbf110958306d0065bff15635463ccc86a90def73bf0f18858

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 e7af78fd85d5dc5f76cb354c3a555cdd2b67f796bddc92d30fba6170c855a15a
MD5 0cf6d247f37d985d7310c31691e520fc
BLAKE2b-256 3b7978ac5c01c0d2ce311686864fbbd460015a1ac276ad2b743d2013aeba963e

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp313-cp313-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp313-cp313-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 a79c1facacf71e456c1658ca85525e0070aa18328586d196549ccf78f1dd3a37
MD5 82c96b88ef12be3fc5972a515c56c7d5
BLAKE2b-256 3c139354214d84e955ab2e2f498fc3eb71ff824c4abb67aa51b03feebc6115c6

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp313-cp313-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp313-cp313-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 b7ddaada81a0b1f3cef5ee85acaec4e5ab4f51c516e77070eed3ab116fb022d3
MD5 e5ce0bfd643de6ee024b68837f3109ca
BLAKE2b-256 407630a705157874195113228244ab1bcb8b3c3115d3641d1da5aeaa2f344823

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 bb85d617b3eeb4e2cef0e1fb7e74e5fe523f07dda80eda2cc9d250ff9a51409c
MD5 1e5988a9424a8919d640da81bce4cfe8
BLAKE2b-256 ea2c78b4b45085b07e32082823ffd520d483df6b5835f32bd3acc48bd8c710a2

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp312-cp312-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp312-cp312-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 66575b03ad84ab8780bcda762774ab02e58ac6b7089b7db423cf4cbff7cde21f
MD5 25ec39d1d806b7e40d51b2d424a28ec3
BLAKE2b-256 2c22acf42bdfa31a6b60981f0f646581735b0210a95c20f7a546aed521cd7757

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 832d5ff2cf19b705b6bb6ccfa0100122012431a4fdaf90a940614b6cb9a8690f
MD5 fccb3fc8eed193b451ad3ba864e56c2f
BLAKE2b-256 68fec0701b4debf89ff55bebd1ca26eab82d6aa27976acd513707bf924fafad0

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 c3830d5d6b0710e027f818a40d18b8e9744aca76966abe34dbdd8afe8248fa70
MD5 c69c731d83157bbc12497bc3744a7595
BLAKE2b-256 056f1c969b1a44dba2dc484389307e535d2310f2cddb2a0919ae44c8d921cf27

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp311-cp311-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp311-cp311-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 62340870a9ff9a1f0835d7ef49cd4016eaf87b3ef6b98ce8dfa2249653178571
MD5 553da30edd5bb1541b21a3d9a303b99e
BLAKE2b-256 cfc0685046f61c34e411c1382c293b852e5c0457ae062c9bcc7d27079bd75c50

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp311-cp311-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp311-cp311-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 7ba786baf5e2f7b95b4b4de4cfec2f4b912080d22034053cee510d00854e78fa
MD5 944a2f74dee6156dace18e42c7706b40
BLAKE2b-256 dbcf1b25fb0fd8b6170ad53154ecaeb5d9b98bdbb87c62ceee7d9e601b99c930

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 55943375ae395b5c714978c3d47962eccf4e7afd16adc1256ded31a717a55b5e
MD5 e1b3722fc186bfa09db8409028391186
BLAKE2b-256 c85de7e71370945dd36e9b921b41ffb461714e187c4146db89611ef4d45310f6

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp310-cp310-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp310-cp310-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 3c1f99bd9f412adb806a9df6182ea96153e5f372611b20ed2e58e1ad6090b79f
MD5 2d876ef24b4c1eeefbde219bd59174d8
BLAKE2b-256 87351c5c90e76606de00e85834e89b01180f76b34fa12e38e5464aaaa25ef67a

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp310-cp310-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp310-cp310-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 23e6fb4cd364c2a50384bcb35863580084f97133940c9526ef9724a6131b3b1c
MD5 ba9ce6d6193d4af364e460a66fee53c7
BLAKE2b-256 8b4e6e8e51f911cc356b1d81be25282d51e99b8d8281c5b296bee0896c17cb56

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: blocksolver-0.9.1-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 11.2 MB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for blocksolver-0.9.1-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 3da6f51d5e6f6e5366a574ce139fe575767f8ad6fefed4ed47aecb656f202872
MD5 53619d662d1f72beef00a3f5b7f48e94
BLAKE2b-256 d88facf9f021af7e2bc89932e3535e75795f5564e8e5b5d0c5aa83bdd61f9302

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp39-cp39-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp39-cp39-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 e0f71ae9cb2e702fc974c406b698bb4089186028610ff2c213d8ae10aa735485
MD5 61a95ba8dcb21f4cbcf9be9dfb7cacfe
BLAKE2b-256 cdfc2753fbed7873897ca6b1aead0c10bf716e71b0f041b9c119ed1e1e28f9b3

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp39-cp39-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp39-cp39-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 fce8b47dbe7e1a4b88a8d95425f12552700d0ea20fc081b2f21f6c17a36b5dce
MD5 71588824e28137a618935aeb604c7ef7
BLAKE2b-256 2db6d6929b14f31a18c8fdc304f8dfad7555113538b5bf806a2ef8e3dfda7e43

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: blocksolver-0.9.1-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 11.2 MB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for blocksolver-0.9.1-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 60e9b82187af6f9dbbe8e0f1b32acdb18d96ddaedf1e8a7116e2c45f66d393df
MD5 32a325f9ea5334a09fdde94aa0749aed
BLAKE2b-256 2287ed37230c3d8184acdaab7792e15264075ff61c14b49dc40753e5bcbca48d

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp38-cp38-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp38-cp38-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 87114129540400dd30e4026c660317d5e52f39f332234a9fe24a0cadbbb65b15
MD5 db8f80b3b9d75fa543a29651386b9ebe
BLAKE2b-256 33492b43851eb04ff6d8d89a536272a758ad09252a98155a9e8e5cdc9d92436e

See more details on using hashes here.

File details

Details for the file blocksolver-0.9.1-cp38-cp38-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for blocksolver-0.9.1-cp38-cp38-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 960d64ebbb6e1e0bee01430a1be054a3e4d7a22a21c58a30311172ef33643101
MD5 0ce7a2bf85ba3659d158b356bcb5511a
BLAKE2b-256 1f41e131c9d9dbd7a6eaf4535eed69abe132db5ee243f30c033e9b96d96d008b

See more details on using hashes here.

Supported by

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