LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
eigen_svd_bidiagonal.c
浏览该文件的文档.
1
5#include "internal.h"
6#include "eigen_internal.h"
7#include "memory_bridge.h"
8
9
10static void accumulate_reflector(lmmc_mat_t *factor, size_t start,
11 size_t length, const lmmc_real_t *vector,
12 lmmc_real_t tau)
13{
14 if (tau == 0.0) return;
15 for (size_t row = 0; row < factor->rows; ++row) {
16 lmmc_real_t sum = MAT_ELEM(factor, row, start);
17 for (size_t i = 1; i < length; ++i) {
18 sum += vector[i] * MAT_ELEM(factor, row, start + i);
19 }
20 sum *= tau;
21 MAT_ELEM(factor, row, start) -= sum;
22 for (size_t i = 1; i < length; ++i) {
23 MAT_ELEM(factor, row, start + i) -= sum * vector[i];
24 }
25 }
26}
27
28static lmmc_real_t reduce_column(lmmc_mat_t *work, lmmc_mat_t *u,
29 size_t k, lmmc_real_t *vector)
30{
31 const size_t length = work->rows - k;
32 lmmc_real_t tau, beta;
33 for (size_t i = 0; i < length; ++i) {
34 vector[i] = MAT_ELEM(work, k + i, k);
35 }
36 householder_make(vector, length, &tau, &beta);
37 if (k + 1 < work->cols) {
38 householder_apply_left(work, k, length, k + 1, work->cols, vector, tau);
39 }
40 accumulate_reflector(u, k, length, vector, tau);
41 return beta;
42}
43
44static lmmc_real_t reduce_row(lmmc_mat_t *work, lmmc_mat_t *v,
45 size_t k, lmmc_real_t *vector)
46{
47 const size_t length = work->cols - k - 1;
48 lmmc_real_t tau, beta;
49 for (size_t j = 0; j < length; ++j) {
50 vector[j] = MAT_ELEM(work, k, k + 1 + j);
51 }
52 householder_make(vector, length, &tau, &beta);
53 if (k + 1 < work->rows) {
54 householder_apply_right(work, k + 1, work->rows, k + 1,
55 length, vector, tau);
56 }
57 accumulate_reflector(v, k + 1, length, vector, tau);
58 return beta;
59}
60
62 lmmc_real_t input_scale,
65{
66 lmmc_mat_t work;
67 lmmc_status_t status = lmmc_mat_create(a->rows, a->cols, &work);
68 if (status != LMMC_STATUS_OK) return status;
69 for (size_t i = 0; i < a->rows; ++i) {
70 for (size_t j = 0; j < a->cols; ++j) {
71 MAT_ELEM(&work, i, j) = MAT_ELEM(a, i, j) / input_scale;
72 }
73 }
74 lmmc_fill_identity_unchecked(u);
75 lmmc_fill_identity_unchecked(v);
76 lmmc_real_t *vector = lmmc_memory_alloc_array(a->rows, sizeof(*vector));
77 if (!vector) {
78 lmmc_mat_destroy(&work);
80 }
81 for (size_t k = 0; k < a->cols; ++k) {
82 d[k] = reduce_column(&work, u, k, vector);
83 e[k] = (k + 1 < a->cols) ? reduce_row(&work, v, k, vector) : 0.0;
84 }
85 lmmc_memory_free(vector);
86 lmmc_mat_destroy(&work);
87 return LMMC_STATUS_OK;
88}
double lmmc_real_t
Public and internal LMMC real type.
lmmc_status_t lmmc_mat_create(size_t rows, size_t cols, lmmc_mat_t *out_mat)
创建 rows x cols 的零矩阵。
void lmmc_mat_destroy(lmmc_mat_t *mat)
销毁矩阵,释放其拥有的缓冲区并清零结构体字段。
行优先存储的稠密矩阵。
void householder_apply_left(lmmc_mat_t *M, size_t i0, size_t len, size_t j0, size_t j1, const lmmc_real_t *v, lmmc_real_t tau)
void householder_make(lmmc_real_t *x, size_t len, lmmc_real_t *tau_out, lmmc_real_t *beta_out)
void householder_apply_right(lmmc_mat_t *M, size_t i0, size_t i1, size_t j0, size_t len, const lmmc_real_t *v, lmmc_real_t tau)
特征值 / SVD 模块内部共享的缩放、Householder 与 Givens 辅助接口(仅源文件可见)。
#define MAT_ELEM(mat, i, j)
lmmc_status_t lmmc_svd_bidiagonalize(const lmmc_mat_t *a, lmmc_real_t input_scale, lmmc_real_t *d, lmmc_real_t *e, lmmc_mat_t *u, lmmc_mat_t *v)
LMMC 内部使用的公共工具(仅源文件可见).
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.
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_ALLOCATION_FAILED