|
| 1 | +import xobjects as xo |
| 2 | +import scipy.sparse as sp |
| 3 | +import numpy as np |
| 4 | +from xobjects.sparse._test_helpers import rel_residual |
| 5 | + |
| 6 | +''' |
| 7 | +The goal of this example is to provide a short user guide for the xo.sparse module. |
| 8 | +
|
| 9 | +The xo.sparse module can be used to solve sparse linear systems of equations: |
| 10 | + A*x = b |
| 11 | +where A is a sparse matrix. |
| 12 | +
|
| 13 | +Currently this module only supports CPU and Cupy contexts. This module contains a |
| 14 | +variety of solvers for different contexts, with consistent APIs. The intended use |
| 15 | +is to reuse the same LHS for many solves, so the solvers work as follows: |
| 16 | +
|
| 17 | +solver(A) # Performs decomposition/factorization |
| 18 | +solver.solve(b) # Solves Ax = b using precomputed factors |
| 19 | +
|
| 20 | +For optimal performance accross backends b should be a column-major (F Contiguous) |
| 21 | +array or vector. |
| 22 | +
|
| 23 | +The intended interface for this module is: |
| 24 | +
|
| 25 | +xo.sparse.factorized_sparse_solver() |
| 26 | +
|
| 27 | +The function includes detailed documentation for usage, but in short, it returns |
| 28 | +the best performing solver based on the context and available modules. If the |
| 29 | +context is not explicitly defined, it is inferred based on the input matrix. |
| 30 | +
|
| 31 | +This is how modules that build upon this functionality within xsuite should interact |
| 32 | +with the xo.sparse module, so that cross-platform compatibility is guaranteed. |
| 33 | +
|
| 34 | +For development and convenience purposes xo.sparse provides the: |
| 35 | +xo.sparse.solvers module |
| 36 | +
|
| 37 | +which provides the following options: |
| 38 | +xo.sparse.solvers.CPU. |
| 39 | + - scipysplu : Alias for scipy SuperLU |
| 40 | + - KLUSuperLU : Alias for PyKLU |
| 41 | +xo.sparse.solvers.CPU. |
| 42 | + - cuDSS : nvmath.sparse.advanced.DirectSolver Wrapper with a SuperLU-like interface |
| 43 | + - cachedSpSM : Rewrite of cupy's SuperLU to cache the SpSM analysis step |
| 44 | + offering massive speedups compared to cupy splu when the only |
| 45 | + available backend is SpSM |
| 46 | + - cupysplu : Alias for scipy SuperLU |
| 47 | +''' |
| 48 | + |
| 49 | +# Example: solve small matrix system |
| 50 | +n = 5 |
| 51 | +# Create matrix |
| 52 | +main = 2.0 + np.abs(np.random.standard_normal(n)) |
| 53 | +lower = np.random.standard_normal(n-1) |
| 54 | +upper = np.random.standard_normal(n-1) |
| 55 | +A = sp.diags( |
| 56 | + diagonals=[lower, main, upper], |
| 57 | + offsets=[-1, 0, 1], |
| 58 | + format="csc" |
| 59 | +) |
| 60 | + |
| 61 | +# Create solver: |
| 62 | +print("Solver selection process: ") |
| 63 | +solver = xo.sparse.factorized_sparse_solver(A, verbose = True) |
| 64 | + |
| 65 | +# Generate random vector to solve: |
| 66 | +b = np.random.standard_normal(n) |
| 67 | + |
| 68 | +# Solve system |
| 69 | +x = solver.solve(b) |
| 70 | + |
| 71 | +# Calculate relative residual to assess solver: |
| 72 | +res = rel_residual(A,x,b) |
| 73 | +print("Relative residual of solution ", res) |
| 74 | +print("Residual should be small (<10^-12)") |
0 commit comments