|
| 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 | +``` |
0 commit comments