24static void lmmc_swap_rows(
lmmc_mat_t* a,
size_t r0,
size_t r1) {
29 for (j = 0; j < a->
cols; ++j) {
42 size_t swap_count = 0;
44 if (a == NULL || pivots == NULL || a->
data == NULL) {
52 for (k = 0; k < n; ++k) {
61 lmmc_abs_to(&maxv, &a->
data[k * a->
stride + k]);
63 for (i = k + 1; i < n; ++i) {
87 lmmc_swap_rows(a, p, k);
95 for (i = k + 1; i < n; ++i) {
102 for (j = k + 1; j < n; ++j) {
120 if (out_swap_count != NULL) {
121 *out_swap_count = swap_count;
130 for (i = 0; i < n; ++i) {
137 for (i = 0; i < n; ++i) {
138 size_t p = pivots[i];
149 for (i = 0; i < n; ++i) {
151 for (j = 0; j < i; ++j) {
170 if (lu == NULL || pivots == NULL || b == NULL || x == NULL || lu->
data == NULL || b->
data == NULL || x->
data == NULL) {
183 for (i = n; i-- > 0;) {
185 for (j = i + 1; j < n; ++j) {
220 if (a == NULL || a->
data == NULL) {
231 for (i = 0; i < n; ++i) {
232 for (j = 0; j <= i; ++j) {
236 for (k = 0; k < j; ++k) {
267 for (j = i + 1; j < n; ++j) {
285 if (l == NULL || b == NULL || x == NULL || l->
data == NULL || b->
data == NULL || x->
data == NULL) {
294 for (i = 0; i < n; ++i) {
298 for (j = 0; j < i; ++j) {
309 for (i = n; i-- > 0;) {
313 for (j = i + 1; j < n; ++j) {
327static void lmmc_qr_update_trailing(
lmmc_mat_t* a,
332 for (j = k + 1; j < n; ++j) {
336 for (i = k + 1; i < m; ++i) {
346 for (i = k + 1; i < m; ++i) {
387 for (i = k + 1; i < m; ++i) {
394 lmmc_qr_update_trailing(a, tau, k);
408 if (a == NULL || tau == NULL || a->
data == NULL) {
414 if (m == 0 || n == 0) {
417 if (tau_size < (m < n ? m : n)) {
421 for (k = 0; k < (m < n ? m : n); ++k) {
432 for (i = k + 1; i < m; ++i) {
454 lmmc_qr_reflector(a, tau, k, alpha, sigma);
468 for (k = 0; k < m; ++k) {
473 for (k = 0; k < n; ++k) {
484 for (i = k + 1; i < m; ++i) {
502 for (i = k + 1; i < m; ++i) {
524 for (k = n; k-- > 0;) {
530 for (j = k + 1; j < n; ++j) {
568 if (qr == NULL || tau == NULL || b == NULL || x == NULL || qr->
data == NULL || b->
data == NULL || x->
data == NULL) {
573 if (m < n || b->size != m || x->
size != n) {
582 for (k = 0; k < m; ++k) {
588 status = lmmc_qr_back_substitute(qr, y, x);
590 for (k = 0; k < m; ++k) {
LMMC binary real type and arithmetic spelling.
#define LMMC_REAL_CLEAR(x)
释放一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_INIT(x)
初始化一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_ADD(res, a, b)
计算 *res = *a + *b 。
#define LMMC_REAL_DIV(res, a, b)
计算 *res = *a / *b 。
#define LMMC_REAL_SUB(res, a, b)
计算 *res = *a - *b 。
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
#define LMMC_REAL_MUL(res, a, b)
计算 *res = *a * *b 。
#define LMMC_REAL_SQRT(res, a)
计算平方根,*res = sqrt(*a) 。
#define LMMC_REAL_CMP(a, b)
比较 *a 与 *b ,返回 -1/0/1 。
#define LMMC_REAL_NEG(res, a)
取相反数,*res = -*a 。
#define LMMC_REAL_SET_D(dst, dbl)
将一个 double 字面量赋值到 lmmc_real_t 。
#define LMMC_REAL_IS_FINITE(x)
判断 *x 是否为有限数。
稠密矩阵直接分解接口(LU、Cholesky、QR)。
lmmc_status_t lmmc_qr_solve(const lmmc_mat_t *qr, const lmmc_real_t *tau, const lmmc_vec_t *b, lmmc_vec_t *x)
利用 QR 分解结果求解线性系统或最小二乘问题。
lmmc_status_t lmmc_qr_decompose_inplace(lmmc_mat_t *a, lmmc_real_t *tau, size_t tau_size)
就地 Householder QR 分解。
lmmc_status_t lmmc_lu_solve(const lmmc_mat_t *lu, const size_t *pivots, const lmmc_vec_t *b, lmmc_vec_t *x)
利用 LU 分解结果求解线性系统 A*x = b。
lmmc_status_t lmmc_cholesky_decompose_inplace(lmmc_mat_t *a)
就地 Cholesky 分解:A = L*L^T,要求 A 对称正定。
lmmc_status_t lmmc_lu_decompose_inplace(lmmc_mat_t *a, size_t *pivots, size_t *out_swap_count)
就地 LU 分解(带部分主元选取):P*A = L*U。
lmmc_status_t lmmc_cholesky_solve(const lmmc_mat_t *l, const lmmc_vec_t *b, lmmc_vec_t *x)
利用 Cholesky 因子求解 A*x = b(A = L*L^T)。
void * lmmc_memory_alloc_array(size_t count, size_t element_size)
void lmmc_memory_free(void *pointer)
Private recoverable allocator for persistent LMMC ownership.
#define LMMC_DEFAULT_REL_TOL
库默认的相对容差.
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_NOT_POSITIVE_DEFINITE
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_SINGULAR_MATRIX
@ LMMC_STATUS_INVALID_ARGUMENT