Linear Algebra
Matrix Multiplication
For general matrix multiplication, use slap_MatMulAdd().
It is a 5-argument matrix multiplication of the form:
where any of the matrices can be transposed, and \(A\) and \(B\) can be aliased.
Here are some examples:
1// C = A * B
2slap_MatMulAdd(C, A, B, 1, 0);
3
4// C = A' * B
5slap_MatMulAdd(C, slap_Transpose(A), B, 1, 0);
6
7// C = A * A' + C
8slap_MatMulAdd(C, A, slap_Transpose(A), 1, 1);
Additionally, the following methods are specializations for performance, and are meant to be used
ONLY WITH DENSE ARRAYS that are NOT TRANSPOSED. Since the general indexing
functions (like slap_Cart2Index()) take both striding and transposes into
account they bring some overhead. For maximum performance, the following methods
discard the information from slap_IsTransposed() and slap_Stride()
and should be used with caution:
Method |
Description |
|---|---|
Dense matrix multiplication |
|
Dense matrix-transposed multiplication |
Solving Linear Systems
Currently the following linear system solves are supported:
Positive-definite systems via
slap_Cholesky()General square systems via
slap_QR()Least-squares problems via
slap_QR()and/orslap_LeastSquares()
Here’s a summary of the relevant methods provided by slap:
Method |
Description |
|---|---|
Solve a system with a triangular matrix, using back-substitution |
|
Cholesky decomposition |
|
Solve a system with a Cholesky decomposition |
|
“Q-less” QR decomposition via Householder reflections |
|
Compute the “Q” matrix from a QR decomposition |
|
|
Calculate \(Q^T b\) from a QR decomposition, without forming \(Q\). |
Solve a linear system using a QR decomposition, with support for “skinny” matrices. |
Cholesky Example
The following example shows the basic flow for solving a linear system using Cholesky:
// Make a positive-definite matrix
Matrix A2 = slap_NewMatrix(3, 3);
slap_MatMulAtB(A2, A, A); // make it positive semi-definite
slap_AddIdentity(A2, 1e-6); // make it positive-definite
slap_MatrixCopy(A, A2); // copy back to A (used later)
// Cholesky Decomposition
slap_ErrorCode err;
err = slap_Cholesky(A);
if (err == SLAP_CHOLESKY_FAIL) {
printf("Matrix is not Positive-Definite!\n");
}
// Solve linear system
Matrix x = slap_NewMatrix(3, 1);
slap_Copy(x, b); // copy rhs vector to solution
slap_CholeskySolve(A, x);
// Check Solution
Matrix y = slap_NewMatrix(3, 1);
slap_MatMulAB(y, A, x);
double err = slap_NormedDifference(y, b);
Least Squares Example
1// Initialize arrays
2int m = 10;
3int n = 5;
4Matrix A = slap_NewMatrix(m, n);
5Matrix b = slap_NewMatrix(m, 1);
6Matrix betas = slap_NewMatrix(m, 1);
7Matrix temp = slap_NewMatrix(m, 1);
8
9// Set data for A and b here...
10
11// Calculate QR decomposition
12// Stores R in the upper-triangular portion of A
13// Stores the Householder reflection vectors below the diagonal
14slap_QR(A, betas, temp);
15
16// Form Q (not usually recommended or needed)
17Matrix Q = slap_NewMatrix(m, m);
18Matrix Q_work = slap_NewMatrix(m, m); // extra memory needed to form Q
19slap_ComputeQ(Q, A, beta, Q_work);
20
21// Solve for b
22// Result is stored in the top n rows of b
23slap_Qtb(A, beta, b); // Calculate Q'b, directly from QR factorization
24slap_TriSolve(slap_UpperTri(A), b);