LAPACK drivers¶
This tutorial tours the LAPACK` context — direct access to the
machine-precision LAPACK driver routines for solving systems, factoring
matrices, computing the SVD, and solving eigenproblems. It builds on the
BLAS tutorial; the same conventions apply (arrays as lists or
NDArray, dimensions inferred, real results as NDArray).
Every transcript below was produced by the actual Mathilda binary.
Solving linear systems¶
dgesv solves the square system A.X == B by LU factorisation. The
right-hand side can be a vector or a matrix; the result matches its shape.
For a rectangular A, dgels gives the least-squares (tall A) or
minimum-norm (wide A) solution:
That is the best fit of x to the three equations x1 = 1, x2 = 2,
x1 + x2 = 4 in the least-squares sense.
Factorizations¶
dgetrf returns the LU factorisation as {LU, pivots} — the combined
unit-lower/upper factors and the 1-based row pivots:
dgetri inverts a matrix (factoring internally):
dgeqrf gives the economy QR factorisation {Q, R} with A == Q.R. Apply
Normal to the factors before recombining them, then Chop to drop the tiny
rounding residue:
In[5]:= Module[{q, r},
{q, r} = Normal /@ LAPACK`dgeqrf[{{1, 2}, {3, 4}}];
Chop[q . r]]
Out[5]= {{1.0, 2.0}, {3.0, 4.0}}
dpotrf gives the lower Cholesky factor L of a symmetric
positive-definite matrix, with A == L.Transpose[L]:
Singular value decomposition¶
dgesdd (divide-and-conquer) and dgesvd (QR iteration) both return
{U, S, VT} with A == U.DiagonalMatrix[S].VT:
In[7]:= Module[{u, d, vt},
{u, d, vt} = Normal /@ LAPACK`dgesdd[{{1, 2}, {3, 4}}];
Chop[u . DiagonalMatrix[d] . vt]]
Out[7]= {{1.0, 2.0}, {3.0, 4.0}}
The singular values S come out in descending order.
Eigenproblems¶
dsyev handles the real symmetric case, returning ascending eigenvalues and
orthonormal eigenvectors:
In[8]:= LAPACK`dsyev[{{2, 1}, {1, 2}}]
Out[8]= {{1.0, 3.0}, {NDArray[{-0.707107, 0.707107}], NDArray[{0.707107, 0.707107}]}}
dgeev handles a general matrix; its eigenvalues (and eigenvectors) may be
complex. A rotation matrix has purely imaginary eigenvalues:
In[9]:= LAPACK`dgeev[{{0, -1}, {1, 0}}]
Out[9]= {{0.0 + 1.0*I, 0.0 - 1.0*I},
{{0.707107, 0.0 - 0.707107*I}, {0.707107, 0.0 + 0.707107*I}}}
The result is {values, vectors}, with vectors[[i]] the right eigenvector for
values[[i]] (so A.vectors[[i]] == values[[i]] vectors[[i]]).
For a complex Hermitian matrix, zheev returns real ascending eigenvalues:
In[10]:= LAPACK`zheev[{{2, Complex[0, 1]}, {Complex[0, -1], 2}}]
Out[10]= {{1.0, 3.0},
{{-0.0 + 0.707107*I, -0.707107}, {0.0 + 0.707107*I, 0.707107}}}
Matrix norm¶
dlange gives the Frobenius norm:
Complex counterparts and failures¶
Every real driver has a z* complex counterpart (zgesv, zgetri, zgeqrf,
zgesdd, zgeev, …). A singular system, a non-positive-definite Cholesky
input, or a symbolic entry leaves the call unevaluated rather than returning a
wrong answer:
(The matrix {{1,2},{2,4}} is singular.)
Where to go next¶
The full reference is in
builtins/lapack.md; for the
lower-level BLAS kernels see the BLAS tutorial.