LMMC
Lamina Mathematic core
Toggle main menu visibility
载入中...
搜索中...
未找到
precond.c
浏览该文件的文档.
1
#include "
precond_internal.h
"
2
3
lmmc_status_t
lmmc_precond_validate_spd
(
const
lmmc_precond_t
* precond,
size_t
size) {
4
if
(precond == NULL) {
5
return
LMMC_STATUS_OK
;
6
}
7
if
(precond->
size
!= size) {
8
return
LMMC_STATUS_DIMENSION_MISMATCH
;
9
}
10
if
(precond->
type
==
LMMC_PRECOND_NONE
) {
11
return
LMMC_STATUS_OK
;
12
}
13
if
(precond->
type
!=
LMMC_PRECOND_JACOBI
|| precond->
impl
== NULL) {
14
return
LMMC_STATUS_INVALID_ARGUMENT
;
15
}
16
const
lmmc_real_t
* inverse = precond->
impl
;
17
for
(
size_t
i = 0; i < size; ++i) {
18
if
(!isfinite(inverse[i])) {
19
return
LMMC_STATUS_NUMERICAL_FAILURE
;
20
}
21
if
(inverse[i] <= 0.0) {
22
return
LMMC_STATUS_NOT_POSITIVE_DEFINITE
;
23
}
24
}
25
return
LMMC_STATUS_OK
;
26
}
27
28
lmmc_status_t
lmmc_precond_create_none
(
size_t
size,
lmmc_precond_t
* out_precond) {
29
if
(out_precond == NULL || size == 0) {
30
return
LMMC_STATUS_INVALID_ARGUMENT
;
31
}
32
out_precond->
type
=
LMMC_PRECOND_NONE
;
33
out_precond->
size
= size;
34
out_precond->
impl
= NULL;
35
out_precond->
owns_data
= 0;
36
return
LMMC_STATUS_OK
;
37
}
38
39
static
lmmc_status_t
lmmc_jacobi_diagonals(
const
lmmc_sparse_mat_t
* a,
40
lmmc_real_t
* inverse) {
41
for
(
size_t
i = 0; i < a->
rows
; ++i) {
42
size_t
pos;
43
if
(!
lmmc_find_col_pos
(a->
col_idx
, a->
row_ptr
[i], a->
row_ptr
[i + 1], i, &pos)) {
44
return
LMMC_STATUS_SINGULAR_MATRIX
;
45
}
46
lmmc_real_t
diag = a->
values
[pos];
47
if
(!isfinite(diag) || fabs(diag) <= 1e-15) {
48
return
LMMC_STATUS_SINGULAR_MATRIX
;
49
}
50
inverse[i] = 1.0 / diag;
51
if
(!isfinite(inverse[i])) {
52
return
LMMC_STATUS_NUMERICAL_FAILURE
;
53
}
54
}
55
return
LMMC_STATUS_OK
;
56
}
57
58
lmmc_status_t
lmmc_precond_create_jacobi
(
const
lmmc_sparse_mat_t
* a,
59
lmmc_precond_t
* out_precond) {
60
lmmc_status_t
st = lmmc_sparse_validate(a);
61
if
(out_precond == NULL || st !=
LMMC_STATUS_OK
|| a->
format
!=
LMMC_SPARSE_CSR
) {
62
return
LMMC_STATUS_INVALID_ARGUMENT
;
63
}
64
if
(a->
rows
!= a->
cols
) {
65
return
LMMC_STATUS_DIMENSION_MISMATCH
;
66
}
67
if
(a->
rows
> (
size_t
)-1 /
sizeof
(
lmmc_real_t
)) {
68
return
LMMC_STATUS_INVALID_ARGUMENT
;
69
}
70
lmmc_real_t
* inverse =
lmmc_memory_alloc
(a->
rows
*
sizeof
(
lmmc_real_t
));
71
if
(inverse == NULL) {
72
return
LMMC_STATUS_ALLOCATION_FAILED
;
73
}
74
st = lmmc_jacobi_diagonals(a, inverse);
75
if
(st !=
LMMC_STATUS_OK
) {
76
lmmc_memory_free
(inverse);
77
return
st;
78
}
79
out_precond->
type
=
LMMC_PRECOND_JACOBI
;
80
out_precond->
size
= a->
rows
;
81
out_precond->
impl
= inverse;
82
out_precond->
owns_data
= 1;
83
return
LMMC_STATUS_OK
;
84
}
85
86
void
lmmc_precond_destroy
(
lmmc_precond_t
* precond) {
87
if
(precond == NULL) {
88
return
;
89
}
90
if
(precond->
owns_data
&& precond->
impl
!= NULL) {
91
if
(precond->
type
==
LMMC_PRECOND_ILU0
|| precond->
type
==
LMMC_PRECOND_ILUT
) {
92
lmmc_ilu_impl_destroy
(precond->
impl
);
93
}
94
else
{
95
lmmc_memory_free
(precond->
impl
);
96
}
97
}
98
precond->
type
=
LMMC_PRECOND_NONE
;
99
precond->
size
= 0;
100
precond->
impl
= NULL;
101
precond->
owns_data
= 0;
102
}
103
104
static
lmmc_status_t
lmmc_jacobi_apply(
const
lmmc_precond_t
* precond,
105
const
lmmc_vec_t
* rhs,
lmmc_vec_t
* out) {
106
if
(precond->
impl
== NULL) {
107
return
LMMC_STATUS_INVALID_ARGUMENT
;
108
}
109
const
lmmc_real_t
* inverse = precond->
impl
;
110
for
(
size_t
i = 0; i < rhs->
size
; ++i) {
111
lmmc_real_t
value = rhs->
data
[i] * inverse[i];
112
if
(!isfinite(rhs->
data
[i]) || !isfinite(value)) {
113
return
LMMC_STATUS_NUMERICAL_FAILURE
;
114
}
115
out->
data
[i] = value;
116
}
117
return
LMMC_STATUS_OK
;
118
}
119
120
lmmc_status_t
lmmc_precond_apply
(
const
lmmc_precond_t
* precond,
121
const
lmmc_vec_t
* rhs,
lmmc_vec_t
* out) {
122
if
(precond == NULL || rhs == NULL || out == NULL || rhs->
data
== NULL || out->
data
== NULL) {
123
return
LMMC_STATUS_INVALID_ARGUMENT
;
124
}
125
if
(rhs->
size
!= precond->
size
|| out->
size
!= precond->
size
) {
126
return
LMMC_STATUS_DIMENSION_MISMATCH
;
127
}
128
switch
(precond->
type
) {
129
case
LMMC_PRECOND_NONE
:
130
return
lmmc_vec_copy
(rhs, out);
131
case
LMMC_PRECOND_JACOBI
:
132
return
lmmc_jacobi_apply(precond, rhs, out);
133
case
LMMC_PRECOND_ILU0
:
134
case
LMMC_PRECOND_ILUT
:
135
return
lmmc_ilu_apply
(precond, rhs, out);
136
default
:
137
return
LMMC_STATUS_NOT_IMPLEMENTED
;
138
}
139
}
lmmc_real_t
double lmmc_real_t
Public and internal LMMC real type.
定义
config.h:28
lmmc_vec_copy
lmmc_status_t lmmc_vec_copy(const lmmc_vec_t *src, lmmc_vec_t *dst)
逐元素复制向量内容:dst = src。
定义
dense_storage.c:210
lmmc_vec_t::size
size_t size
定义
dense_types.h:32
lmmc_vec_t::data
lmmc_real_t * data
定义
dense_types.h:33
lmmc_vec_t
一维稠密向量。
定义
dense_types.h:31
lmmc_memory_alloc
void * lmmc_memory_alloc(size_t size)
定义
memory_bridge.c:46
lmmc_memory_free
void lmmc_memory_free(void *pointer)
定义
memory_bridge.c:75
lmmc_precond_validate_spd
lmmc_status_t lmmc_precond_validate_spd(const lmmc_precond_t *precond, size_t size)
定义
precond.c:3
lmmc_precond_t::impl
void * impl
定义
precond.h:39
lmmc_precond_create_none
lmmc_status_t lmmc_precond_create_none(size_t size, lmmc_precond_t *out_precond)
创建恒等预处理子(仅记录尺寸,apply 时直接复制)。
定义
precond.c:28
lmmc_precond_create_jacobi
lmmc_status_t lmmc_precond_create_jacobi(const lmmc_sparse_mat_t *a, lmmc_precond_t *out_precond)
由稀疏矩阵的对角线创建 Jacobi 预处理子:M = diag(A)。
定义
precond.c:58
lmmc_precond_apply
lmmc_status_t lmmc_precond_apply(const lmmc_precond_t *precond, const lmmc_vec_t *rhs, lmmc_vec_t *out)
应用预处理子:求解 M*out = rhs。
定义
precond.c:120
lmmc_precond_t::owns_data
int owns_data
定义
precond.h:40
lmmc_precond_t::type
lmmc_precond_type_t type
定义
precond.h:37
lmmc_precond_destroy
void lmmc_precond_destroy(lmmc_precond_t *precond)
销毁预处理子,释放内部资源。
定义
precond.c:86
LMMC_PRECOND_NONE
@ LMMC_PRECOND_NONE
定义
precond.h:21
LMMC_PRECOND_JACOBI
@ LMMC_PRECOND_JACOBI
定义
precond.h:22
LMMC_PRECOND_ILU0
@ LMMC_PRECOND_ILU0
定义
precond.h:23
LMMC_PRECOND_ILUT
@ LMMC_PRECOND_ILUT
定义
precond.h:24
lmmc_precond_t::size
size_t size
定义
precond.h:38
lmmc_precond_t
通用预处理子句柄。
定义
precond.h:36
lmmc_ilu_apply
lmmc_status_t lmmc_ilu_apply(const lmmc_precond_t *precond, const lmmc_vec_t *rhs, lmmc_vec_t *out)
定义
precond_apply.c:48
precond_internal.h
lmmc_ilu_impl_destroy
void lmmc_ilu_impl_destroy(lmmc_precond_ilu_impl_t *impl)
定义
precond_workspace.c:25
lmmc_find_col_pos
int lmmc_find_col_pos(const size_t *cols, size_t start, size_t end, size_t col, size_t *pos)
定义
precond_workspace.c:3
LMMC_SPARSE_CSR
@ LMMC_SPARSE_CSR
定义
sparse_types.h:14
lmmc_sparse_mat_t::rows
size_t rows
定义
sparse_types.h:35
lmmc_sparse_mat_t::row_ptr
size_t * row_ptr
定义
sparse_types.h:38
lmmc_sparse_mat_t::col_idx
size_t * col_idx
定义
sparse_types.h:39
lmmc_sparse_mat_t::values
lmmc_real_t * values
定义
sparse_types.h:40
lmmc_sparse_mat_t::format
lmmc_sparse_format_t format
定义
sparse_types.h:41
lmmc_sparse_mat_t::cols
size_t cols
定义
sparse_types.h:36
lmmc_sparse_mat_t
通用稀疏矩阵(CSR / CSC 共用同一结构)。
定义
sparse_types.h:34
lmmc_status_t
lmmc_status_t
LMMC 库统一返回的状态码.
定义
status.h:22
LMMC_STATUS_OK
@ LMMC_STATUS_OK
定义
status.h:23
LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_NUMERICAL_FAILURE
定义
status.h:29
LMMC_STATUS_NOT_POSITIVE_DEFINITE
@ LMMC_STATUS_NOT_POSITIVE_DEFINITE
定义
status.h:30
LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_DIMENSION_MISMATCH
定义
status.h:25
LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_ALLOCATION_FAILED
定义
status.h:26
LMMC_STATUS_SINGULAR_MATRIX
@ LMMC_STATUS_SINGULAR_MATRIX
定义
status.h:27
LMMC_STATUS_NOT_IMPLEMENTED
@ LMMC_STATUS_NOT_IMPLEMENTED
定义
status.h:28
LMMC_STATUS_INVALID_ARGUMENT
@ LMMC_STATUS_INVALID_ARGUMENT
定义
status.h:24
src
precond.c
生成于
, 为 LMMC使用
1.18.0