Skip to content

Commit efe23be

Browse files
lkdvosleburgel
andauthored
Add algorithm section in the docs (#199)
* add algorithm section in the docs * Apply suggestions from code review Co-authored-by: Lander Burgelman <39218680+leburgel@users.noreply.github.com> * array type -> input type --------- Co-authored-by: Lander Burgelman <39218680+leburgel@users.noreply.github.com>
1 parent 09715df commit efe23be

File tree

4 files changed

+151
-52
lines changed

4 files changed

+151
-52
lines changed

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ makedocs(;
5151
"User Interface" => [
5252
"user_interface/compositions.md",
5353
"user_interface/decompositions.md",
54+
"user_interface/algorithms.md",
5455
"user_interface/truncations.md",
5556
"user_interface/properties.md",
5657
"user_interface/matrix_functions.md",

docs/src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ These operations typically follow some common skeleton, and here we go into a li
2626

2727
```@contents
2828
Pages = ["user_interface/compositions.md", "user_interface/decompositions.md",
29+
"user_interface/algorithms.md",
2930
"user_interface/truncations.md", "user_interface/properties.md",
3031
"user_interface/matrix_functions.md"]
3132
Depth = 2
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
```@meta
2+
CurrentModule = MatrixAlgebraKit
3+
CollapsedDocStrings = true
4+
```
5+
6+
# [Algorithm Selection](@id sec_algorithmselection)
7+
8+
All factorization functions in MatrixAlgebraKit accept an optional `alg` keyword argument that controls which algorithm is used and how it is configured.
9+
By default, an appropriate algorithm is selected automatically based on the function and the input types.
10+
This page explains how to override that default, what algorithm types are available, and how to configure them.
11+
12+
## The `alg` Keyword
13+
14+
The `alg` keyword is interpreted by [`MatrixAlgebraKit.select_algorithm`](@ref), which accepts five different forms for specifying an algorithm and its configuration.
15+
For example, for `qr_compact` these forms look like:
16+
17+
```julia
18+
# Form 1: No alg — algorithm selected automatically based on function and input type.
19+
Q, R = qr_compact(A);
20+
21+
# Form 2: Symbol — creates Algorithm{:Householder}(; positive=false).
22+
Q, R = qr_compact(A; alg = :Householder, positive = false);
23+
24+
# Form 3: Algorithm type — calls Householder(; positive=false).
25+
Q, R = qr_compact(A; alg = Householder, positive = false);
26+
27+
# Form 4: Algorithm instance — used as-is; no additional kwargs are allowed.
28+
Q, R = qr_compact(A; alg = Householder(; positive = false));
29+
30+
# Form 5: NamedTuple — equivalent to qr_compact(A; positive=false).
31+
Q, R = qr_compact(A; alg = (; positive = false));
32+
```
33+
34+
!!! note
35+
When passing an already-constructed algorithm instance (form 4), additional keyword arguments at the call site are not permitted and will throw an `ArgumentError`.
36+
All configuration must go into the constructor in that case.
37+
38+
```@docs; canonical=false
39+
MatrixAlgebraKit.select_algorithm
40+
```
41+
42+
## Discovering the Default Algorithm
43+
44+
To check which algorithm is used by default for a given function and input type, call [`MatrixAlgebraKit.default_algorithm`](@ref).
45+
The available keyword arguments depend on the algorithm type; refer to the docstrings listed in [Available Algorithm Types](@ref) below.
46+
47+
```@docs; canonical=false
48+
MatrixAlgebraKit.default_algorithm
49+
```
50+
51+
## Configuring Algorithms
52+
53+
Each algorithm accepts keyword arguments that control its behavior.
54+
These can be provided either at the call site (forms 1–3) or inside the algorithm constructor:
55+
56+
```julia
57+
# The following four calls are all equivalent:
58+
U, S, Vᴴ = svd_compact(A; fixgauge = false)
59+
U, S, Vᴴ = svd_compact(A; alg = :SafeDivideAndConquer, fixgauge = false)
60+
U, S, Vᴴ = svd_compact(A; alg = SafeDivideAndConquer, fixgauge = false)
61+
U, S, Vᴴ = svd_compact(A; alg = SafeDivideAndConquer(; fixgauge = false))
62+
```
63+
64+
## The `DefaultAlgorithm` Sentinel
65+
66+
Package developers who want to store an algorithm configuration without committing to a specific algorithm can use `DefaultAlgorithm`.
67+
It defers algorithm selection to call time, forwarding its stored keyword arguments to [`MatrixAlgebraKit.select_algorithm`](@ref):
68+
69+
```julia
70+
# Store configuration without picking a specific algorithm:
71+
alg = DefaultAlgorithm(; positive = true)
72+
73+
# Equivalent to qr_compact(A; positive = true):
74+
Q, R = qr_compact(A; alg)
75+
```
76+
77+
```@docs; canonical=false
78+
DefaultAlgorithm
79+
```
80+
81+
## Available Algorithm Types
82+
83+
The following high-level algorithm types are available.
84+
They all accept an optional `driver` keyword to select the computational backend; see [Driver Selection](@ref sec_driverselection) for details.
85+
86+
| Algorithm | Applicable decompositions | Key keyword arguments |
87+
|:----------|:--------------------------|:----------------------|
88+
| [`Householder`](@ref) | QR, LQ | `positive`, `pivoted`, `blocksize` |
89+
| [`DivideAndConquer`](@ref) | SVD, eigh | `fixgauge` |
90+
| [`SafeDivideAndConquer`](@ref) | SVD, eigh | `fixgauge` |
91+
| [`QRIteration`](@ref) | SVD, eigh, eig, Schur | `fixgauge`, `expert`, `permute`, `scale` |
92+
| [`Bisection`](@ref) | eigh, SVD | `fixgauge` |
93+
| [`Jacobi`](@ref) | eigh, SVD | `fixgauge` |
94+
| [`RobustRepresentations`](@ref) | eigh | `fixgauge` |
95+
| [`SVDViaPolar`](@ref) | SVD | `fixgauge`, `tol` |
96+
| [`PolarViaSVD`](@ref) | polar | positional `svd_alg` argument |
97+
| [`PolarNewton`](@ref) | polar | `maxiter`, `tol` |
98+
99+
For full docstring details on each algorithm type, see the corresponding section in [Decompositions](@ref).
100+
101+
## [Driver Selection](@id sec_driverselection)
102+
103+
!!! note "Expert use case"
104+
Selecting a specific driver is an advanced feature intended for users who need to target a specific computational backend, such as a GPU.
105+
For most use cases, the default driver selection is sufficient.
106+
107+
Each algorithm in MatrixAlgebraKit can optionally accept a `driver` keyword argument to explicitly select the computational backend.
108+
By default, the driver is set to `DefaultDriver()`, which automatically selects the most appropriate backend based on the input matrix type.
109+
The available drivers are:
110+
111+
```@autodocs; canonical=false
112+
Modules = [MatrixAlgebraKit]
113+
Filter = t -> t isa Type && t <: MatrixAlgebraKit.Driver
114+
```
115+
116+
For example, to force LAPACK for a generic matrix type, or to use a GPU backend:
117+
118+
```julia
119+
using MatrixAlgebraKit
120+
using MatrixAlgebraKit: LAPACK, CUSOLVER # driver types are not exported by default
121+
122+
# Default: driver is selected automatically based on the input type
123+
U, S, Vᴴ = svd_compact(A)
124+
U, S, Vᴴ = svd_compact(A; alg = SafeDivideAndConquer())
125+
126+
# Expert: explicitly select LAPACK
127+
U, S, Vᴴ = svd_compact(A; alg = SafeDivideAndConquer(; driver = LAPACK()))
128+
129+
# Expert: use a GPU backend (requires loading the appropriate extension)
130+
U, S, Vᴴ = svd_compact(A; alg = QRIteration(; driver = CUSOLVER()))
131+
```
132+
133+
Similarly, for QR decompositions:
134+
135+
```julia
136+
using MatrixAlgebraKit: LAPACK # driver types are not exported by default
137+
138+
# Default: driver is selected automatically
139+
Q, R = qr_compact(A)
140+
Q, R = qr_compact(A; alg = Householder())
141+
142+
# Expert: explicitly select a driver
143+
Q, R = qr_compact(A; alg = Householder(; driver = LAPACK()))
144+
```

docs/src/user_interface/decompositions.md

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ f!(A, [F]; kwargs...) -> F...
1616

1717
Here, the input matrix is always the first argument, and optionally the output can be provided as well.
1818
The keywords are algorithm-specific, and can be used to influence the behavior of the algorithms.
19-
To check what algorithm is used by default for a given factorization `f` and input `A`, and by extension which keyword arguments it takes, you can call [`MatrixAlgebraKit.default_algorithm(f, A)`](@ref) and check the documentation of resulting algorithm type.
19+
For a full description of how to select and configure algorithms, see [Algorithm Selection](@ref sec_algorithmselection).
2020
Importantly, for generic code patterns it is recommended to always use the output `F` explicitly, since some implementations may not be able to reuse the provided memory.
2121
Additionally, the `f!` method typically assumes that it is allowed to destroy the input `A`, and making use of the contents of `A` afterwards should be deemed as undefined behavior.
2222

@@ -40,10 +40,11 @@ lq_full
4040
lq_compact
4141
```
4242

43-
The following algorithm is available for QR and LQ decompositions:
43+
The following algorithms are available for QR and LQ decompositions:
4444

45-
```@docs; canonical=false
46-
Householder
45+
```@autodocs; canonical=false
46+
Modules = [MatrixAlgebraKit]
47+
Filter = t -> t isa Type && (t <: MatrixAlgebraKit.QRAlgorithms || t <: MatrixAlgebraKit.LQAlgorithms)
4748
```
4849

4950
## Eigenvalue Decomposition
@@ -387,54 +388,6 @@ norm(A * N1') < 1e-14 && norm(A * N2') < 1e-14 &&
387388
true
388389
```
389390

390-
## [Driver Selection](@id sec_driverselection)
391-
392-
!!! note "Expert use case"
393-
Selecting a specific driver is an advanced feature intended for users who need to target a specific computational backend, such as a GPU. For most use cases, the default driver selection is sufficient.
394-
395-
Each algorithm in MatrixAlgebraKit can optionally accept a `driver` keyword argument to explicitly select the computational backend.
396-
By default, the driver is set to `DefaultDriver()`, which automatically selects the most appropriate backend based on the input matrix type.
397-
The available drivers are:
398-
399-
```@docs; canonical=false
400-
MatrixAlgebraKit.DefaultDriver
401-
MatrixAlgebraKit.LAPACK
402-
MatrixAlgebraKit.CUSOLVER
403-
MatrixAlgebraKit.ROCSOLVER
404-
MatrixAlgebraKit.GLA
405-
MatrixAlgebraKit.Native
406-
```
407-
408-
For example, to force LAPACK for a generic matrix type, or to use a GPU backend:
409-
410-
```julia
411-
using MatrixAlgebraKit
412-
using MatrixAlgebraKit: LAPACK, CUSOLVER # driver types are not exported by default
413-
414-
# Default: driver is selected automatically based on the input type
415-
U, S, Vᴴ = svd_compact(A)
416-
U, S, Vᴴ = svd_compact(A; alg = SafeDivideAndConquer())
417-
418-
# Expert: explicitly select LAPACK
419-
U, S, Vᴴ = svd_compact(A; alg = SafeDivideAndConquer(; driver = LAPACK()))
420-
421-
# Expert: use a GPU backend (requires loading the appropriate extension)
422-
U, S, Vᴴ = svd_compact(A; alg = QRIteration(; driver = CUSOLVER()))
423-
```
424-
425-
Similarly, for QR decompositions:
426-
427-
```julia
428-
using MatrixAlgebraKit: LAPACK # driver types are not exported by default
429-
430-
# Default: driver is selected automatically
431-
Q, R = qr_compact(A)
432-
Q, R = qr_compact(A; alg = Householder())
433-
434-
# Expert: explicitly select a driver
435-
Q, R = qr_compact(A; alg = Householder(; driver = LAPACK()))
436-
```
437-
438391
## [Gauge choices](@id sec_gaugefix)
439392

440393
Both eigenvalue and singular value decompositions have residual gauge degrees of freedom even when the eigenvalues or singular values are unique.

0 commit comments

Comments
 (0)