LMMC
Lamina Mathematic core
Toggle main menu visibility
载入中...
搜索中...
未找到
eigen_svd_factorization.c
浏览该文件的文档.
1
4
#include "
internal/eigen_svd_internal.h
"
5
#include "
eigen_internal.h
"
6
#include "
memory_bridge.h
"
7
8
typedef
struct
{
9
lmmc_mat_t
v
;
10
lmmc_real_t
*
d
;
11
lmmc_real_t
*
e
;
12
}
svd_workspace_t
;
13
14
static
void
destroy_workspace(
svd_workspace_t
*work)
15
{
16
lmmc_mat_destroy
(&work->
v
);
17
lmmc_memory_free
(work->
d
);
18
lmmc_memory_free
(work->
e
);
19
}
20
21
static
lmmc_status_t
create_factors(
size_t
m,
size_t
n,
22
lmmc_svd_result_t
*result)
23
{
24
lmmc_status_t
status =
lmmc_mat_create
(m, m, &result->
U
);
25
if
(status !=
LMMC_STATUS_OK
)
return
status;
26
status =
lmmc_vec_create
(n, &result->
sigma
);
27
if
(status !=
LMMC_STATUS_OK
)
return
status;
28
return
lmmc_mat_create
(n, n, &result->
Vt
);
29
}
30
31
static
lmmc_status_t
create_workspace(
size_t
n,
svd_workspace_t
*work)
32
{
33
lmmc_status_t
status =
lmmc_mat_create
(n, n, &work->
v
);
34
if
(status !=
LMMC_STATUS_OK
)
return
status;
35
work->
d
=
lmmc_memory_alloc_array
(n,
sizeof
(*work->
d
));
36
work->
e
=
lmmc_memory_alloc_array
(n,
sizeof
(*work->
e
));
37
if
(!work->
d
|| !work->
e
)
return
LMMC_STATUS_ALLOCATION_FAILED
;
38
return
LMMC_STATUS_OK
;
39
}
40
41
static
void
normalize_signs(
lmmc_real_t
*d,
lmmc_mat_t
*v)
42
{
43
for
(
size_t
i = 0; i < v->
cols
; ++i) {
44
if
(d[i] < 0.0) {
45
d[i] = -d[i];
46
for
(
size_t
k = 0; k < v->
rows
; ++k) {
47
MAT_ELEM
(v, k, i) = -
MAT_ELEM
(v, k, i);
48
}
49
}
50
}
51
}
52
53
static
void
descending_order(
const
lmmc_real_t
*d,
size_t
n,
size_t
*order)
54
{
55
for
(
size_t
i = 0; i < n; ++i) order[i] = i;
56
for
(
size_t
i = 0; i + 1 < n; ++i) {
57
size_t
maximum = i;
58
for
(
size_t
j = i + 1; j < n; ++j) {
59
if
(d[order[j]] > d[order[maximum]]) maximum = j;
60
}
61
if
(maximum != i) {
62
size_t
tmp = order[i];
63
order[i] = order[maximum];
64
order[maximum] = tmp;
65
}
66
}
67
}
68
69
static
lmmc_status_t
reorder_left_vectors(
lmmc_mat_t
*u,
size_t
n,
70
const
size_t
*order)
71
{
72
const
size_t
m = u->
rows
;
73
lmmc_real_t
*columns =
lmmc_memory_alloc_array_2d
(m, n,
sizeof
(*columns));
74
if
(!columns)
return
LMMC_STATUS_ALLOCATION_FAILED
;
75
for
(
size_t
j = 0; j < n; ++j) {
76
for
(
size_t
i = 0; i < m; ++i) {
77
columns[j * m + i] =
MAT_ELEM
(u, i, j);
78
}
79
}
80
for
(
size_t
j = 0; j < n; ++j) {
81
for
(
size_t
i = 0; i < m; ++i) {
82
MAT_ELEM
(u, i, j) = columns[order[j] * m + i];
83
}
84
}
85
lmmc_memory_free
(columns);
86
return
LMMC_STATUS_OK
;
87
}
88
89
static
lmmc_status_t
assemble_factors(
svd_workspace_t
*work,
90
lmmc_svd_result_t
*result)
91
{
92
const
size_t
n = result->
sigma
.
size
;
93
normalize_signs(work->
d
, &work->
v
);
94
size_t
*order =
lmmc_memory_alloc_array
(n,
sizeof
(*order));
95
if
(!order)
return
LMMC_STATUS_ALLOCATION_FAILED
;
96
descending_order(work->
d
, n, order);
97
for
(
size_t
i = 0; i < n; ++i) {
98
result->
sigma
.
data
[i] = work->
d
[order[i]];
99
for
(
size_t
k = 0; k < n; ++k) {
100
MAT_ELEM
(&result->
Vt
, i, k) =
MAT_ELEM
(&work->
v
, k, order[i]);
101
}
102
}
103
lmmc_status_t
status = reorder_left_vectors(&result->
U
, n, order);
104
lmmc_memory_free
(order);
105
return
status;
106
}
107
108
lmmc_status_t
lmmc_svd_tall
(
const
lmmc_mat_t
*a,
lmmc_real_t
input_scale,
109
lmmc_svd_result_t
*result)
110
{
111
svd_workspace_t
work = {0};
112
lmmc_svd_result_t
factors = {0};
113
lmmc_status_t
status = create_factors(a->
rows
, a->
cols
, &factors);
114
if
(status !=
LMMC_STATUS_OK
)
goto
cleanup;
115
status = create_workspace(a->
cols
, &work);
116
if
(status !=
LMMC_STATUS_OK
)
goto
cleanup;
117
status =
lmmc_svd_bidiagonalize
(a, input_scale, work.
d
, work.
e
,
118
&factors.
U
, &work.
v
);
119
if
(status !=
LMMC_STATUS_OK
)
goto
cleanup;
120
status =
lmmc_svd_diagonalize
(work.
d
, work.
e
, a->
cols
, &factors.
U
, &work.
v
);
121
if
(status !=
LMMC_STATUS_OK
)
goto
cleanup;
122
status = assemble_factors(&work, &factors);
123
cleanup:
124
destroy_workspace(&work);
125
if
(status ==
LMMC_STATUS_OK
) {
126
*result = factors;
127
}
else
{
128
lmmc_svd_result_destroy
(&factors);
129
}
130
return
status;
131
}
lmmc_real_t
double lmmc_real_t
Public and internal LMMC real type.
定义
config.h:28
lmmc_mat_create
lmmc_status_t lmmc_mat_create(size_t rows, size_t cols, lmmc_mat_t *out_mat)
创建 rows x cols 的零矩阵。
定义
dense_storage.c:14
lmmc_vec_create
lmmc_status_t lmmc_vec_create(size_t size, lmmc_vec_t *out_vec)
创建长度为 size 的零向量。
定义
dense_storage.c:144
lmmc_mat_destroy
void lmmc_mat_destroy(lmmc_mat_t *mat)
销毁矩阵,释放其拥有的缓冲区并清零结构体字段。
定义
dense_storage.c:62
lmmc_mat_t::cols
size_t cols
定义
dense_types.h:20
lmmc_vec_t::size
size_t size
定义
dense_types.h:32
lmmc_mat_t::rows
size_t rows
定义
dense_types.h:19
lmmc_vec_t::data
lmmc_real_t * data
定义
dense_types.h:33
lmmc_mat_t
行优先存储的稠密矩阵。
定义
dense_types.h:18
lmmc_svd_result_t::sigma
lmmc_vec_t sigma
定义
eigen.h:54
lmmc_svd_result_t::Vt
lmmc_mat_t Vt
定义
eigen.h:55
lmmc_svd_result_t::U
lmmc_mat_t U
定义
eigen.h:53
lmmc_svd_result_destroy
void lmmc_svd_result_destroy(lmmc_svd_result_t *result)
释放 lmmc_svd 输出结果.
定义
eigen_svd.c:262
lmmc_svd_result_t
奇异值分解结果: .
定义
eigen.h:52
eigen_internal.h
特征值 / SVD 模块内部共享的缩放、Householder 与 Givens 辅助接口(仅源文件可见)。
MAT_ELEM
#define MAT_ELEM(mat, i, j)
定义
eigen_internal.h:15
lmmc_svd_bidiagonalize
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)
定义
eigen_svd_bidiagonal.c:61
svd_workspace_t::e
lmmc_real_t * e
定义
eigen_svd_factorization.c:11
svd_workspace_t::d
lmmc_real_t * d
定义
eigen_svd_factorization.c:10
svd_workspace_t::v
lmmc_mat_t v
定义
eigen_svd_factorization.c:9
lmmc_svd_tall
lmmc_status_t lmmc_svd_tall(const lmmc_mat_t *a, lmmc_real_t input_scale, lmmc_svd_result_t *result)
定义
eigen_svd_factorization.c:108
svd_workspace_t
定义
eigen_svd_factorization.c:8
eigen_svd_internal.h
lmmc_svd_diagonalize
lmmc_status_t lmmc_svd_diagonalize(lmmc_real_t *d, lmmc_real_t *e, size_t n, lmmc_mat_t *u, lmmc_mat_t *v)
定义
eigen_svd_iteration.c:97
lmmc_memory_alloc_array
void * lmmc_memory_alloc_array(size_t count, size_t element_size)
定义
memory_bridge.c:55
lmmc_memory_alloc_array_2d
void * lmmc_memory_alloc_array_2d(size_t rows, size_t cols, size_t element_size)
定义
memory_bridge.c:68
lmmc_memory_free
void lmmc_memory_free(void *pointer)
定义
memory_bridge.c:75
memory_bridge.h
Private recoverable allocator for persistent LMMC ownership.
lmmc_status_t
lmmc_status_t
LMMC 库统一返回的状态码.
定义
status.h:22
LMMC_STATUS_OK
@ LMMC_STATUS_OK
定义
status.h:23
LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_ALLOCATION_FAILED
定义
status.h:26
src
eigen_svd_factorization.c
生成于
, 为 LMMC使用
1.18.0