LMMC
Lamina Mathematic core
Toggle main menu visibility
载入中...
搜索中...
未找到
precond_ilu0.c
浏览该文件的文档.
1
#include "
precond_internal.h
"
2
3
static
lmmc_status_t
lmmc_ilu0_clone(
const
lmmc_sparse_mat_t
* a,
4
lmmc_precond_ilu_impl_t
** out) {
5
size_t
idx_bytes, val_bytes;
6
if
(!lmmc_safe_mul_size(a->
nnz
,
sizeof
(
size_t
), &idx_bytes) ||
7
!lmmc_safe_mul_size(a->
nnz
,
sizeof
(
lmmc_real_t
), &val_bytes)) {
8
return
LMMC_STATUS_INVALID_ARGUMENT
;
9
}
10
lmmc_precond_ilu_impl_t
* impl = NULL;
11
lmmc_status_t
st =
lmmc_ilu_impl_create
(a->
rows
, &impl);
12
if
(st !=
LMMC_STATUS_OK
) {
13
return
st;
14
}
15
impl->
nnz
= impl->
capacity
= a->
nnz
;
16
if
(a->
nnz
> 0) {
17
impl->
col_idx
=
lmmc_memory_alloc
(idx_bytes);
18
impl->
lu_values
=
lmmc_memory_alloc
(val_bytes);
19
if
(impl->
col_idx
== NULL || impl->
lu_values
== NULL) {
20
lmmc_ilu_impl_destroy
(impl);
21
return
LMMC_STATUS_ALLOCATION_FAILED
;
22
}
23
memcpy(impl->
col_idx
, a->
col_idx
, idx_bytes);
24
memcpy(impl->
lu_values
, a->
values
, val_bytes);
25
}
26
memcpy(impl->
row_ptr
, a->
row_ptr
, (a->
rows
+ 1) *
sizeof
(
size_t
));
27
*out = impl;
28
return
LMMC_STATUS_OK
;
29
}
30
31
static
lmmc_status_t
lmmc_ilu0_diagonals(
lmmc_precond_ilu_impl_t
* impl) {
32
for
(
size_t
i = 0; i < impl->
size
; ++i) {
33
impl->
diag_pos
[i] = (size_t)-1;
34
if
(!
lmmc_find_col_pos
(impl->
col_idx
, impl->
row_ptr
[i],
35
impl->
row_ptr
[i + 1], i, &impl->
diag_pos
[i])) {
36
return
LMMC_STATUS_SINGULAR_MATRIX
;
37
}
38
}
39
return
LMMC_STATUS_OK
;
40
}
41
43
static
lmmc_real_t
lmmc_ilu0_entry_sum(
const
lmmc_precond_ilu_impl_t
* impl,
44
size_t
i,
size_t
p,
size_t
limit) {
45
const
size_t
j = impl->
col_idx
[p];
46
lmmc_real_t
sum = impl->
lu_values
[p];
47
for
(
size_t
q = impl->
row_ptr
[i]; q < impl->row_ptr[i + 1]; ++q) {
48
size_t
k = impl->
col_idx
[q];
49
size_t
pos;
50
if
(k >= limit) {
51
continue
;
52
}
53
if
(
lmmc_find_col_pos
(impl->
col_idx
, impl->
row_ptr
[k],
54
impl->
row_ptr
[k + 1], j, &pos)) {
55
lmmc_real_t
product = impl->
lu_values
[q] * impl->
lu_values
[pos];
56
sum = sum - product;
57
}
58
}
59
return
sum;
60
}
61
62
static
lmmc_status_t
lmmc_ilu0_lower(
lmmc_precond_ilu_impl_t
* impl,
size_t
i) {
63
for
(
size_t
p = impl->
row_ptr
[i]; p < impl->row_ptr[i + 1]; ++p) {
64
size_t
j = impl->
col_idx
[p];
65
if
(j >= i) {
66
continue
;
67
}
68
lmmc_real_t
sum = lmmc_ilu0_entry_sum(impl, i, p, j);
69
lmmc_real_t
diag = impl->
lu_values
[impl->
diag_pos
[j]];
70
if
(!isfinite(sum) || !isfinite(diag) || fabs(diag) <= 1e-15) {
71
return
LMMC_STATUS_SINGULAR_MATRIX
;
72
}
73
impl->
lu_values
[p] = sum / diag;
74
if
(!isfinite(impl->
lu_values
[p])) {
75
return
LMMC_STATUS_NUMERICAL_FAILURE
;
76
}
77
}
78
return
LMMC_STATUS_OK
;
79
}
80
81
static
lmmc_status_t
lmmc_ilu0_upper(
lmmc_precond_ilu_impl_t
* impl,
size_t
i) {
82
for
(
size_t
p = impl->
row_ptr
[i]; p < impl->row_ptr[i + 1]; ++p) {
83
if
(impl->
col_idx
[p] < i) {
84
continue
;
85
}
86
lmmc_real_t
sum = lmmc_ilu0_entry_sum(impl, i, p, i);
87
if
(!isfinite(sum)) {
88
return
LMMC_STATUS_NUMERICAL_FAILURE
;
89
}
90
impl->
lu_values
[p] = sum;
91
}
92
lmmc_real_t
diag = impl->
lu_values
[impl->
diag_pos
[i]];
93
if
(!isfinite(diag) || fabs(diag) <= 1e-15) {
94
return
LMMC_STATUS_SINGULAR_MATRIX
;
95
}
96
return
LMMC_STATUS_OK
;
97
}
98
99
lmmc_status_t
lmmc_precond_create_ilu0
(
const
lmmc_sparse_mat_t
* a,
100
lmmc_precond_t
* out_precond) {
101
lmmc_status_t
st = lmmc_sparse_validate(a);
102
if
(out_precond == NULL || st !=
LMMC_STATUS_OK
|| a->
format
!=
LMMC_SPARSE_CSR
) {
103
return
LMMC_STATUS_INVALID_ARGUMENT
;
104
}
105
if
(a->
rows
!= a->
cols
) {
106
return
LMMC_STATUS_DIMENSION_MISMATCH
;
107
}
108
lmmc_precond_ilu_impl_t
* impl = NULL;
109
st = lmmc_ilu0_clone(a, &impl);
110
if
(st !=
LMMC_STATUS_OK
) {
111
return
st;
112
}
113
st = lmmc_ilu0_diagonals(impl);
114
if
(st !=
LMMC_STATUS_OK
) {
115
goto
fail;
116
}
117
for
(
size_t
i = 0; i < a->
rows
; ++i) {
118
st = lmmc_ilu0_lower(impl, i);
119
if
(st !=
LMMC_STATUS_OK
) {
120
goto
fail;
121
}
122
st = lmmc_ilu0_upper(impl, i);
123
if
(st !=
LMMC_STATUS_OK
) {
124
goto
fail;
125
}
126
}
127
out_precond->
type
=
LMMC_PRECOND_ILU0
;
128
out_precond->
size
= a->
rows
;
129
out_precond->
impl
= impl;
130
out_precond->
owns_data
= 1;
131
return
LMMC_STATUS_OK
;
132
fail:
133
lmmc_ilu_impl_destroy
(impl);
134
return
st;
135
}
lmmc_real_t
double lmmc_real_t
Public and internal LMMC real type.
定义
config.h:28
lmmc_memory_alloc
void * lmmc_memory_alloc(size_t size)
定义
memory_bridge.c:46
lmmc_precond_t::impl
void * impl
定义
precond.h:39
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_create_ilu0
lmmc_status_t lmmc_precond_create_ilu0(const lmmc_sparse_mat_t *a, lmmc_precond_t *out_precond)
创建 ILU(0) 预处理子(零填充不完全 LU 分解)。
定义
precond_ilu0.c:99
LMMC_PRECOND_ILU0
@ LMMC_PRECOND_ILU0
定义
precond.h:23
lmmc_precond_t::size
size_t size
定义
precond.h:38
lmmc_precond_t
通用预处理子句柄。
定义
precond.h:36
precond_internal.h
lmmc_precond_ilu_impl_t::capacity
size_t capacity
定义
precond_internal.h:14
lmmc_ilu_impl_create
lmmc_status_t lmmc_ilu_impl_create(size_t size, lmmc_precond_ilu_impl_t **out)
定义
precond_workspace.c:115
lmmc_precond_ilu_impl_t::nnz
size_t nnz
定义
precond_internal.h:13
lmmc_precond_ilu_impl_t::diag_pos
size_t * diag_pos
定义
precond_internal.h:18
lmmc_precond_ilu_impl_t::col_idx
size_t * col_idx
定义
precond_internal.h:16
lmmc_precond_ilu_impl_t::lu_values
lmmc_real_t * lu_values
定义
precond_internal.h:17
lmmc_precond_ilu_impl_t::row_ptr
size_t * row_ptr
定义
precond_internal.h:15
lmmc_precond_ilu_impl_t::size
size_t size
定义
precond_internal.h:12
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_precond_ilu_impl_t
定义
precond_internal.h:11
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::nnz
size_t nnz
定义
sparse_types.h:37
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_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_INVALID_ARGUMENT
@ LMMC_STATUS_INVALID_ARGUMENT
定义
status.h:24
src
precond_ilu0.c
生成于
, 为 LMMC使用
1.18.0