blocksolver 0.8.1__py3-none-any.whl → 0.8.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,509 @@
1
+ Metadata-Version: 2.4
2
+ Name: blocksolver
3
+ Version: 0.8.5
4
+ Summary: Block Quasi-Minimal-Residual sparse linear solver
5
+ Home-page: https://blit.sourceforge.net
6
+ Author: Qianqian Fang
7
+ Author-email: Qianqian Fang <q.fang@neu.edu>
8
+ License: BSD-3-Clause OR LGPL-3.0-or-later OR GPL-3.0-or-later
9
+ Project-URL: Homepage, https://blit.sourceforge.net
10
+ Project-URL: Repository, https://github.com/fangq/blocksolver
11
+ Project-URL: Documentation, https://blit.sourceforge.net
12
+ Project-URL: Bug Tracker, https://github.com/fangq/blocksolver/issues
13
+ Keywords: sparse,linear-algebra,iterative-solver,qmr,fortran,umfpack
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: BSD License
17
+ Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
18
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Operating System :: MacOS
22
+ Classifier: Operating System :: Microsoft :: Windows
23
+ Classifier: Programming Language :: Fortran
24
+ Classifier: Programming Language :: Python :: 3
25
+ Classifier: Programming Language :: Python :: 3.8
26
+ Classifier: Programming Language :: Python :: 3.9
27
+ Classifier: Programming Language :: Python :: 3.10
28
+ Classifier: Programming Language :: Python :: 3.11
29
+ Classifier: Programming Language :: Python :: 3.12
30
+ Classifier: Programming Language :: Python :: 3.13
31
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
32
+ Requires-Python: >=3.8
33
+ Description-Content-Type: text/markdown
34
+ Requires-Dist: numpy>=1.20
35
+ Requires-Dist: scipy>=1.0
36
+ Provides-Extra: fast
37
+ Requires-Dist: numba>=0.50; extra == "fast"
38
+ Provides-Extra: test
39
+ Requires-Dist: pytest>=6.0; extra == "test"
40
+ Provides-Extra: dev
41
+ Requires-Dist: pytest>=6.0; extra == "dev"
42
+ Requires-Dist: build; extra == "dev"
43
+ Requires-Dist: twine; extra == "dev"
44
+ Dynamic: author
45
+ Dynamic: home-page
46
+ Dynamic: requires-python
47
+
48
+ # BlockSolver - Block Quasi-Minimal Residual (BLQMR) Sparse Linear Solver
49
+
50
+ **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.
51
+
52
+ ## Features
53
+
54
+ - **Block QMR Algorithm**: Efficiently solves multiple right-hand sides simultaneously
55
+ - **Complex Symmetric Support**: Designed for complex symmetric matrices (A = Aᵀ, not A = A†)
56
+ - **Dual Backend**: Fortran extension for speed, Python fallback for portability
57
+ - **Flexible Preconditioning**: ILU, diagonal (Jacobi), and split preconditioners
58
+ - **SciPy Integration**: Works seamlessly with SciPy sparse matrices
59
+ - **Optional Numba Acceleration**: JIT-compiled kernels for the Python backend
60
+
61
+ ## Algorithm
62
+
63
+ ### Block Quasi-Minimal Residual (BLQMR)
64
+
65
+ The BLQMR algorithm is an iterative Krylov subspace method specifically designed for:
66
+
67
+ 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.
68
+
69
+ 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.
70
+
71
+ 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.
72
+
73
+ ### Key Components
74
+
75
+ - **Quasi-QR Decomposition**: A modified Gram-Schmidt process using the quasi inner product ⟨x,y⟩ = Σ xₖyₖ (without conjugation) for complex symmetric systems.
76
+
77
+ - **Three-term Lanczos Recurrence**: Builds an orthonormal basis for the Krylov subspace with short recurrences, minimizing memory usage.
78
+
79
+ - **Block Updates**: Processes m right-hand sides simultaneously, with typical block sizes of 1-64.
80
+
81
+ ### When to Use BLQMR
82
+
83
+ | Use Case | Recommendation |
84
+ |----------|----------------|
85
+ | Complex symmetric matrix (A = Aᵀ) | ✅ Ideal |
86
+ | Multiple right-hand sides | ✅ Ideal |
87
+ | Real symmetric positive definite | Consider CG first |
88
+ | General non-symmetric | Consider GMRES or BiCGSTAB |
89
+ | Very large systems (>10⁶ unknowns) | ✅ Good with preconditioning |
90
+
91
+ ## Installation
92
+
93
+ ### From PyPI
94
+
95
+ ```bash
96
+ pip install blocksolver
97
+ ```
98
+
99
+ ### From Source
100
+
101
+ Prerequisites:
102
+ - Python ≥ 3.8
103
+ - NumPy ≥ 1.20
104
+ - SciPy ≥ 1.0
105
+ - (Optional) Fortran compiler + UMFPACK for the accelerated backend
106
+ - (Optional) Numba for accelerated Python backend
107
+
108
+ ```bash
109
+ # Ubuntu/Debian
110
+ sudo apt install gfortran libsuitesparse-dev libblas-dev liblapack-dev
111
+
112
+ # macOS
113
+ brew install gcc suite-sparse openblas
114
+
115
+ # Install
116
+ cd python
117
+ pip install .
118
+ ```
119
+
120
+ ## Quick Start
121
+
122
+ ```python
123
+ import numpy as np
124
+ from scipy.sparse import csc_matrix
125
+ from blocksolver import blqmr
126
+
127
+ # Create a sparse matrix
128
+ A = csc_matrix([
129
+ [4, 1, 0, 0],
130
+ [1, 4, 1, 0],
131
+ [0, 1, 4, 1],
132
+ [0, 0, 1, 4]
133
+ ], dtype=float)
134
+
135
+ b = np.array([1., 2., 3., 4.])
136
+
137
+ # Solve Ax = b
138
+ result = blqmr(A, b, tol=1e-10)
139
+
140
+ print(f"Solution: {result.x}")
141
+ print(f"Converged: {result.converged}")
142
+ print(f"Iterations: {result.iter}")
143
+ print(f"Relative residual: {result.relres:.2e}")
144
+ ```
145
+
146
+ ## Usage
147
+
148
+ ### Main Interface: `blqmr()`
149
+
150
+ The primary function `blqmr()` automatically selects the best available backend (Fortran if available, otherwise Python).
151
+
152
+ ```python
153
+ from blocksolver import blqmr, BLQMR_EXT
154
+
155
+ # Check which backend is active
156
+ print(f"Using Fortran backend: {BLQMR_EXT}")
157
+
158
+ # Basic usage
159
+ result = blqmr(A, b)
160
+
161
+ # With options
162
+ result = blqmr(A, b,
163
+ tol=1e-8, # Convergence tolerance
164
+ maxiter=1000, # Maximum iterations
165
+ precond_type='ilu', # Preconditioner: 'ilu', 'diag', or None
166
+ )
167
+ ```
168
+
169
+ ### Multiple Right-Hand Sides
170
+
171
+ BLQMR excels when solving the same system with multiple right-hand sides:
172
+
173
+ ```python
174
+ import numpy as np
175
+ from blocksolver import blqmr
176
+
177
+ # 100 different right-hand sides
178
+ B = np.random.randn(n, 100)
179
+
180
+ # Solve all systems at once (much faster than solving individually)
181
+ result = blqmr(A, B, tol=1e-8)
182
+
183
+ # result.x has shape (n, 100)
184
+ ```
185
+
186
+ ### Complex Symmetric Systems
187
+
188
+ BLQMR is specifically designed for complex symmetric matrices (common in frequency-domain wave problems):
189
+
190
+ ```python
191
+ import numpy as np
192
+ from blocksolver import blqmr
193
+
194
+ # Complex symmetric matrix (A = A.T, NOT A.conj().T)
195
+ A = create_helmholtz_matrix(frequency=1000) # Your application
196
+ b = np.complex128(source_term)
197
+
198
+ result = blqmr(A, b, tol=1e-8, precond_type='diag')
199
+ ```
200
+
201
+ ### Preconditioning
202
+
203
+ BlockSolver supports multiple preconditioner types for both backends:
204
+
205
+ ```python
206
+ from blocksolver import blqmr, make_preconditioner
207
+
208
+ # Using precond_type parameter (works with both backends)
209
+ result = blqmr(A, b, precond_type='ilu') # Incomplete LU
210
+ result = blqmr(A, b, precond_type='diag') # Diagonal (Jacobi)
211
+ result = blqmr(A, b, precond_type=None) # No preconditioning
212
+
213
+ # Custom preconditioner (Python backend only)
214
+ M1 = make_preconditioner(A, 'ilu', drop_tol=1e-4, fill_factor=10)
215
+ result = blqmr(A, b, M1=M1, precond_type=None)
216
+
217
+ # Split preconditioning for symmetric systems (Python backend)
218
+ # Preserves symmetry: M1^{-1} A M2^{-1}
219
+ M = make_preconditioner(A, 'diag', split=True) # Returns sqrt(D)
220
+ result = blqmr(A, b, M1=M, M2=M, precond_type=None)
221
+ ```
222
+
223
+ ### SciPy-Compatible Interface
224
+
225
+ For drop-in replacement in existing code:
226
+
227
+ ```python
228
+ from blocksolver import blqmr_scipy
229
+
230
+ # Returns (x, flag) like scipy.sparse.linalg solvers
231
+ x, flag = blqmr_scipy(A, b, tol=1e-10)
232
+ ```
233
+
234
+ ### Low-Level CSC Interface
235
+
236
+ For maximum control, use the CSC component interface:
237
+
238
+ ```python
239
+ from blocksolver import blqmr_solve
240
+
241
+ # CSC format components (0-based indexing)
242
+ Ap = np.array([0, 2, 5, 9, 10, 12], dtype=np.int32) # Column pointers
243
+ Ai = np.array([0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4], dtype=np.int32) # Row indices
244
+ Ax = np.array([2., 3., 3., -1., 4., 4., -3., 1., 2., 2., 6., 1.]) # Values
245
+ b = np.array([8., 45., -3., 3., 19.])
246
+
247
+ result = blqmr_solve(Ap, Ai, Ax, b,
248
+ tol=1e-8,
249
+ droptol=0.001, # ILU drop tolerance (Fortran backend only)
250
+ precond_type='ilu', # Preconditioner type
251
+ zero_based=True, # 0-based indexing (default)
252
+ )
253
+ ```
254
+
255
+ ## API Reference
256
+
257
+ ### `blqmr(A, B, **kwargs) -> BLQMRResult`
258
+
259
+ Main solver interface.
260
+
261
+ **Parameters:**
262
+ | Parameter | Type | Default | Description |
263
+ |-----------|------|---------|-------------|
264
+ | `A` | sparse matrix or ndarray | required | System matrix (n × n) |
265
+ | `B` | ndarray | required | Right-hand side (n,) or (n × m) |
266
+ | `tol` | float | 1e-6 | Convergence tolerance |
267
+ | `maxiter` | int | n | Maximum iterations |
268
+ | `M1`, `M2` | preconditioner | None | Custom preconditioners (Python backend) |
269
+ | `x0` | ndarray | None | Initial guess |
270
+ | `precond_type` | str or None | 'ilu' | Preconditioner: 'ilu', 'diag', or None |
271
+ | `droptol` | float | 0.001 | ILU drop tolerance (Fortran backend) |
272
+ | `residual` | bool | False | Use true residual for convergence (Python) |
273
+ | `workspace` | BLQMRWorkspace | None | Pre-allocated workspace (Python) |
274
+
275
+ **Returns:** `BLQMRResult` object with:
276
+ | Attribute | Type | Description |
277
+ |-----------|------|-------------|
278
+ | `x` | ndarray | Solution vector(s) |
279
+ | `flag` | int | 0=converged, 1=maxiter, 2=precond fail, 3=stagnation |
280
+ | `iter` | int | Iterations performed |
281
+ | `relres` | float | Final relative residual |
282
+ | `converged` | bool | True if flag == 0 |
283
+ | `resv` | ndarray | Residual history (Python backend only) |
284
+
285
+ ### `blqmr_solve(Ap, Ai, Ax, b, **kwargs) -> BLQMRResult`
286
+
287
+ Low-level CSC interface for single RHS.
288
+
289
+ ### `blqmr_solve_multi(Ap, Ai, Ax, B, **kwargs) -> BLQMRResult`
290
+
291
+ Low-level CSC interface for multiple right-hand sides.
292
+
293
+ ### `blqmr_scipy(A, b, **kwargs) -> Tuple[ndarray, int]`
294
+
295
+ SciPy-compatible interface returning `(x, flag)`.
296
+
297
+ ### `make_preconditioner(A, precond_type, **kwargs) -> Preconditioner`
298
+
299
+ Create a preconditioner for the Python backend.
300
+
301
+ **Parameters:**
302
+ | Parameter | Type | Default | Description |
303
+ |-----------|------|---------|-------------|
304
+ | `A` | sparse matrix | required | System matrix |
305
+ | `precond_type` | str | required | 'diag', 'jacobi', 'ilu', 'ilu0', 'ilut', 'lu', 'ssor' |
306
+ | `split` | bool | False | Return sqrt(D) for split preconditioning |
307
+ | `drop_tol` | float | 1e-4 | Drop tolerance for ILUT |
308
+ | `fill_factor` | float | 10 | Fill factor for ILUT |
309
+ | `omega` | float | 1.0 | Relaxation parameter for SSOR |
310
+
311
+ ### Utility Functions
312
+
313
+ ```python
314
+ from blocksolver import (
315
+ BLQMR_EXT, # True if Fortran backend available
316
+ HAS_NUMBA, # True if Numba acceleration available
317
+ get_backend_info, # Returns dict with backend details
318
+ test, # Run built-in tests
319
+ )
320
+ ```
321
+
322
+ ## Benchmarks
323
+
324
+ ### BLQMR vs Direct Solver (mldivide)
325
+
326
+ Complex symmetric FEM matrices, 4 right-hand sides, tolerance 10⁻⁸, split Jacobi preconditioner:
327
+
328
+ | Grid | Nodes | NNZ | mldivide | BLQMR | Speedup |
329
+ |------|-------|-----|----------|-------|---------|
330
+ | 20³ | 8,000 | 110K | 135ms | 115ms | **1.2×** |
331
+ | 30³ | 27,000 | 384K | 1.36s | 373ms | **3.6×** |
332
+ | 40³ | 64,000 | 922K | 6.40s | 947ms | **6.8×** |
333
+ | 50³ | 125,000 | 1.8M | 25.9s | 1.76s | **14.7×** |
334
+
335
+ ### Block Size Efficiency
336
+
337
+ With 64 RHS on a 8,000-node complex symmetric system:
338
+
339
+ | Block Size | Iterations | Speedup vs Single |
340
+ |------------|------------|-------------------|
341
+ | 1 (point) | 10,154 | 1.0× |
342
+ | 4 | 2,220 | 1.8× |
343
+ | 8 | 956 | 2.0× |
344
+ | 16 | 361 | 2.1× |
345
+ | 32 | 178 | 2.2× |
346
+
347
+ **Optimal block size**: 8-16 for most problems. Larger blocks have diminishing returns due to increased per-iteration cost.
348
+
349
+ ### Iteration Efficiency
350
+
351
+ With 4 RHS, BLQMR uses only ~24% of total iterations compared to 4 separate single-RHS solves — achieving **super-linear block acceleration**.
352
+
353
+ ## Performance Tips
354
+
355
+ 1. **Use the Fortran backend** when available (faster for large systems)
356
+
357
+ 2. **Enable preconditioning** for ill-conditioned systems:
358
+ ```python
359
+ result = blqmr(A, b, precond_type='ilu')
360
+ ```
361
+
362
+ 3. **Batch multiple right-hand sides** instead of solving one at a time:
363
+ ```python
364
+ # Fast: single call with all RHS
365
+ result = blqmr(A, B_matrix)
366
+
367
+ # Slow: multiple calls
368
+ for b in B_columns:
369
+ result = blqmr(A, b)
370
+ ```
371
+
372
+ 4. **Install Numba** for faster Python backend:
373
+ ```bash
374
+ pip install numba
375
+ ```
376
+
377
+ 5. **Reuse workspace** for repeated solves with the same dimensions:
378
+ ```python
379
+ from blocksolver import BLQMRWorkspace
380
+ ws = BLQMRWorkspace(n, m, dtype=np.complex128)
381
+ for b in many_rhs:
382
+ result = blqmr(A, b, workspace=ws)
383
+ ```
384
+
385
+ 6. **Use split Jacobi for complex symmetric systems**:
386
+ ```python
387
+ # Preserves symmetry of preconditioned system
388
+ M = make_preconditioner(A, 'diag', split=True)
389
+ result = blqmr(A, b, M1=M, M2=M, precond_type=None)
390
+ ```
391
+
392
+ ## Examples
393
+
394
+ ### Diffuse Optical Tomography
395
+
396
+ ```python
397
+ import numpy as np
398
+ from scipy.sparse import diags, kron, eye
399
+ from blocksolver import blqmr
400
+
401
+ def create_diffusion_matrix(nx, ny, D=1.0, mu_a=0.01, omega=1e9):
402
+ """Create 2D diffusion matrix for DOT."""
403
+ n = nx * ny
404
+ h = 1.0 / nx
405
+
406
+ # Laplacian
407
+ Lx = diags([-1, 2, -1], [-1, 0, 1], shape=(nx, nx)) / h**2
408
+ Ly = diags([-1, 2, -1], [-1, 0, 1], shape=(ny, ny)) / h**2
409
+ L = kron(eye(ny), Lx) + kron(Ly, eye(nx))
410
+
411
+ # Diffusion equation: (-D∇² + μ_a + iω/c) φ = q
412
+ c = 3e10 # speed of light in tissue (cm/s)
413
+ A = -D * L + mu_a * eye(n) + 1j * omega / c * eye(n)
414
+
415
+ return A.tocsc()
416
+
417
+ # Setup problem
418
+ A = create_diffusion_matrix(100, 100, omega=2*np.pi*100e6)
419
+ sources = np.random.randn(10000, 16) + 0j # 16 source positions
420
+
421
+ # Solve for all sources at once
422
+ result = blqmr(A, sources, tol=1e-8, precond_type='diag')
423
+ print(f"Solved {sources.shape[1]} systems in {result.iter} iterations")
424
+ ```
425
+
426
+ ### Frequency-Domain Acoustics
427
+
428
+ ```python
429
+ import numpy as np
430
+ from blocksolver import blqmr
431
+
432
+ # Helmholtz equation: (∇² + k²)p = f
433
+ # Results in complex symmetric matrix
434
+
435
+ def solve_helmholtz(K, M, f, frequencies):
436
+ """Solve Helmholtz at multiple frequencies."""
437
+ solutions = []
438
+ for omega in frequencies:
439
+ # A = K - ω²M (complex symmetric if K, M are symmetric)
440
+ A = K - omega**2 * M
441
+ result = blqmr(A, f, tol=1e-10, precond_type='diag')
442
+ solutions.append(result.x)
443
+ return np.array(solutions)
444
+ ```
445
+
446
+ ## Troubleshooting
447
+
448
+ ### "No Fortran backend available"
449
+
450
+ Install the package with Fortran support:
451
+ ```bash
452
+ # Install dependencies first
453
+ sudo apt install gfortran libsuitesparse-dev # Linux
454
+ brew install gcc suite-sparse # macOS
455
+
456
+ # Reinstall blocksolver
457
+ pip install --no-cache-dir blocksolver
458
+ ```
459
+
460
+ ### Check backend status
461
+
462
+ ```python
463
+ from blocksolver import get_backend_info
464
+ print(get_backend_info())
465
+ # {'backend': 'binary', 'has_fortran': True, 'has_numba': True}
466
+ ```
467
+
468
+ ### Slow convergence
469
+
470
+ 1. Enable preconditioning: `precond_type='ilu'` or `precond_type='diag'`
471
+ 2. Reduce ILU drop tolerance: `droptol=1e-4` (Fortran backend)
472
+ 3. Check matrix conditioning with `np.linalg.cond(A.toarray())`
473
+
474
+ ### ILU factorization fails
475
+
476
+ For indefinite or complex symmetric matrices, ILU may fail:
477
+ ```python
478
+ # Fall back to diagonal preconditioner
479
+ result = blqmr(A, b, precond_type='diag')
480
+ ```
481
+
482
+ ### Memory issues with large systems
483
+
484
+ 1. Use the Fortran backend (more memory efficient)
485
+ 2. Reduce block size for multiple RHS
486
+ 3. Use iterative refinement instead of tighter tolerance
487
+
488
+ ## License
489
+
490
+ BSD-3-Clause or GPL-3.0+ (dual-licensed)
491
+
492
+ ## Citation
493
+
494
+ If you use BlockSolver in your research, please cite:
495
+
496
+ ```bibtex
497
+ @software{blocksolver,
498
+ author = {Qianqian Fang},
499
+ title = {BlockSolver: Block Quasi-Minimal Residual Sparse Linear Solver},
500
+ url = {https://github.com/fangq/blit},
501
+ year = {2024}
502
+ }
503
+ ```
504
+
505
+ ## See Also
506
+
507
+ - [BLIT](https://github.com/fangq/blit) - The underlying Fortran library
508
+ - [SciPy sparse.linalg](https://docs.scipy.org/doc/scipy/reference/sparse.linalg.html) - Other iterative solvers
509
+ - [PyAMG](https://github.com/pyamg/pyamg) - Algebraic multigrid solvers
@@ -0,0 +1,6 @@
1
+ blocksolver/__init__.py,sha256=42r9UA1Cv5xbOzzQvUhvvmkI7a3_Vh6X3md3vY3qnRE,1899
2
+ blocksolver/blqmr.py,sha256=bu_JBg6oNtYPnfOAZVgyGCb_QTc-27J_ahGWrfHVPaw,45067
3
+ blocksolver-0.8.5.dist-info/METADATA,sha256=qgzptdsPzZZL3cd2gUAOL_zfht6yJwuPZpShp1-lsVE,16108
4
+ blocksolver-0.8.5.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
5
+ blocksolver-0.8.5.dist-info/top_level.txt,sha256=R5OAf1b8tkdMHqg8VgcfGMg6vbYt25p9JNq2Pk_VlbA,12
6
+ blocksolver-0.8.5.dist-info/RECORD,,
@@ -1,162 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: blocksolver
3
- Version: 0.8.1
4
- Summary: Block Quasi-Minimal-Residual sparse linear solver
5
- Home-page: https://blit.sourceforge.net
6
- Author: Qianqian Fang
7
- Author-email: Qianqian Fang <q.fang@neu.edu>
8
- License: BSD-3-Clause OR LGPL-3.0-or-later OR GPL-3.0-or-later
9
- Project-URL: Homepage, https://blit.sourceforge.net
10
- Project-URL: Repository, https://github.com/fangq/blocksolver
11
- Project-URL: Documentation, https://blit.sourceforge.net
12
- Project-URL: Bug Tracker, https://github.com/fangq/blocksolver/issues
13
- Keywords: sparse,linear-algebra,iterative-solver,qmr,fortran,umfpack
14
- Classifier: Development Status :: 4 - Beta
15
- Classifier: Intended Audience :: Science/Research
16
- Classifier: License :: OSI Approved :: BSD License
17
- Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
18
- Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
19
- Classifier: Operating System :: OS Independent
20
- Classifier: Operating System :: POSIX :: Linux
21
- Classifier: Operating System :: MacOS
22
- Classifier: Operating System :: Microsoft :: Windows
23
- Classifier: Programming Language :: Fortran
24
- Classifier: Programming Language :: Python :: 3
25
- Classifier: Programming Language :: Python :: 3.8
26
- Classifier: Programming Language :: Python :: 3.9
27
- Classifier: Programming Language :: Python :: 3.10
28
- Classifier: Programming Language :: Python :: 3.11
29
- Classifier: Programming Language :: Python :: 3.12
30
- Classifier: Programming Language :: Python :: 3.13
31
- Classifier: Topic :: Scientific/Engineering :: Mathematics
32
- Requires-Python: >=3.8
33
- Description-Content-Type: text/markdown
34
- Requires-Dist: numpy>=1.20
35
- Requires-Dist: scipy>=1.0
36
- Provides-Extra: fast
37
- Requires-Dist: numba>=0.50; extra == "fast"
38
- Provides-Extra: test
39
- Requires-Dist: pytest>=6.0; extra == "test"
40
- Provides-Extra: dev
41
- Requires-Dist: pytest>=6.0; extra == "dev"
42
- Requires-Dist: build; extra == "dev"
43
- Requires-Dist: twine; extra == "dev"
44
- Dynamic: author
45
- Dynamic: home-page
46
- Dynamic: requires-python
47
-
48
- # BLIT Python Bindings
49
-
50
- Python interface for the BLIT (Block Iterative) sparse linear solver library.
51
-
52
- ## Installation
53
-
54
- ### Prerequisites
55
-
56
- - Python >= 3.8
57
- - NumPy
58
- - Fortran compiler (gfortran, ifort)
59
- - UMFPACK/SuiteSparse library
60
- - BLAS/LAPACK
61
-
62
- On Ubuntu/Debian:
63
- ```bash
64
- sudo apt install gfortran libsuitesparse-dev libblas-dev liblapack-dev
65
- ```
66
-
67
- On macOS (Homebrew):
68
- ```bash
69
- brew install gcc suite-sparse openblas
70
- ```
71
-
72
- ### Install
73
-
74
- ```bash
75
- cd python
76
- pip install .
77
- ```
78
-
79
- For development:
80
- ```bash
81
- pip install -e .
82
- ```
83
-
84
- ## Usage
85
-
86
- ### Basic Usage
87
-
88
- ```python
89
- import numpy as np
90
- from blocksolver import blqmr_solve
91
-
92
- # Define sparse matrix in CSC format (0-based indexing)
93
- Ap = np.array([0, 2, 5, 9, 10, 12], dtype=np.int32)
94
- Ai = np.array([0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4], dtype=np.int32)
95
- Ax = np.array([2., 3., 3., -1., 4., 4., -3., 1., 2., 2., 6., 1.])
96
- b = np.array([8.0, 45.0, -3.0, 3.0, 19.0])
97
-
98
- # Solve
99
- result = blqmr_solve(Ap, Ai, Ax, b, tol=1e-8)
100
-
101
- print(f"Solution: {result.x}")
102
- print(f"Converged: {result.converged}")
103
- print(f"Iterations: {result.iter}")
104
- ```
105
-
106
- ### With SciPy Sparse Matrices
107
-
108
- ```python
109
- from scipy.sparse import csc_matrix
110
- from blocksolver import blqmr_scipy
111
-
112
- A = csc_matrix([[4, 1, 0], [1, 3, 1], [0, 1, 2]])
113
- b = np.array([1., 2., 3.])
114
-
115
- x, flag = blqmr_scipy(A, b, tol=1e-10)
116
- ```
117
-
118
- ### Multiple Right-Hand Sides
119
-
120
- ```python
121
- from blocksolver import blqmr_solve_multi
122
-
123
- B = np.column_stack([b1, b2, b3]) # n x nrhs
124
- result = blqmr_solve_multi(Ap, Ai, Ax, B)
125
- # result.x is n x nrhs
126
- ```
127
-
128
- ## API Reference
129
-
130
- ### `blqmr_solve(Ap, Ai, Ax, b, **kwargs) -> BLQMRResult`
131
-
132
- Solve sparse system Ax = b.
133
-
134
- **Parameters:**
135
- - `Ap`: Column pointers (int32, length n+1)
136
- - `Ai`: Row indices (int32, length nnz)
137
- - `Ax`: Non-zero values (float64, length nnz)
138
- - `b`: Right-hand side (float64, length n)
139
- - `tol`: Convergence tolerance (default: 1e-6)
140
- - `maxiter`: Maximum iterations (default: n)
141
- - `droptol`: ILU drop tolerance (default: 0.001)
142
- - `use_precond`: Use ILU preconditioner (default: True)
143
- - `zero_based`: Input uses 0-based indexing (default: True)
144
-
145
- **Returns:** `BLQMRResult` with attributes:
146
- - `x`: Solution vector
147
- - `flag`: 0=converged, 1=maxiter, 2=precond fail, 3=stagnation
148
- - `iter`: Iterations performed
149
- - `relres`: Relative residual
150
- - `converged`: Boolean property
151
-
152
- ## Testing
153
-
154
- ```bash
155
- make test
156
- # or
157
- pytest tests/ -v
158
- ```
159
-
160
- ## License
161
-
162
- BSD / LGPL / GPL - see LICENSE files in parent directory.
@@ -1,6 +0,0 @@
1
- blocksolver/__init__.py,sha256=ddfrZdsGFpV3Dqhe-t7U8SqkrjWWcS58XJJQv2BWEzw,1899
2
- blocksolver/blqmr.py,sha256=n5QXKs4izQGj25uKFIzaXUA4yFfA6v18evte5R25Apk,31765
3
- blocksolver-0.8.1.dist-info/METADATA,sha256=lqbeHjgwgD3ZeFXUIxTjlWzleIdji4AvneCy9r8js10,4408
4
- blocksolver-0.8.1.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
5
- blocksolver-0.8.1.dist-info/top_level.txt,sha256=R5OAf1b8tkdMHqg8VgcfGMg6vbYt25p9JNq2Pk_VlbA,12
6
- blocksolver-0.8.1.dist-info/RECORD,,