LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
precond.c
浏览该文件的文档.
1#include "precond_internal.h"
2
4 if (precond == NULL) {
5 return LMMC_STATUS_OK;
6 }
7 if (precond->size != size) {
9 }
10 if (precond->type == LMMC_PRECOND_NONE) {
11 return LMMC_STATUS_OK;
12 }
13 if (precond->type != LMMC_PRECOND_JACOBI || precond->impl == NULL) {
15 }
16 const lmmc_real_t* inverse = precond->impl;
17 for (size_t i = 0; i < size; ++i) {
18 if (!isfinite(inverse[i])) {
20 }
21 if (inverse[i] <= 0.0) {
23 }
24 }
25 return LMMC_STATUS_OK;
26}
27
29 if (out_precond == NULL || size == 0) {
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
39static 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)) {
45 }
46 lmmc_real_t diag = a->values[pos];
47 if (!isfinite(diag) || fabs(diag) <= 1e-15) {
49 }
50 inverse[i] = 1.0 / diag;
51 if (!isfinite(inverse[i])) {
53 }
54 }
55 return LMMC_STATUS_OK;
56}
57
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) {
63 }
64 if (a->rows != a->cols) {
66 }
67 if (a->rows > (size_t)-1 / sizeof(lmmc_real_t)) {
69 }
70 lmmc_real_t* inverse = lmmc_memory_alloc(a->rows * sizeof(lmmc_real_t));
71 if (inverse == NULL) {
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
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) {
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
104static 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) {
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)) {
114 }
115 out->data[i] = value;
116 }
117 return LMMC_STATUS_OK;
118}
119
121 const lmmc_vec_t* rhs, lmmc_vec_t* out) {
122 if (precond == NULL || rhs == NULL || out == NULL || rhs->data == NULL || out->data == NULL) {
124 }
125 if (rhs->size != precond->size || out->size != precond->size) {
127 }
128 switch (precond->type) {
130 return lmmc_vec_copy(rhs, out);
132 return lmmc_jacobi_apply(precond, rhs, out);
135 return lmmc_ilu_apply(precond, rhs, out);
136 default:
138 }
139}
double lmmc_real_t
Public and internal LMMC real type.
lmmc_status_t lmmc_vec_copy(const lmmc_vec_t *src, lmmc_vec_t *dst)
逐元素复制向量内容:dst = src。
lmmc_real_t * data
一维稠密向量。
void * lmmc_memory_alloc(size_t size)
void lmmc_memory_free(void *pointer)
lmmc_status_t lmmc_precond_validate_spd(const lmmc_precond_t *precond, size_t size)
lmmc_status_t lmmc_precond_create_none(size_t size, lmmc_precond_t *out_precond)
创建恒等预处理子(仅记录尺寸,apply 时直接复制)。
lmmc_status_t lmmc_precond_create_jacobi(const lmmc_sparse_mat_t *a, lmmc_precond_t *out_precond)
由稀疏矩阵的对角线创建 Jacobi 预处理子:M = diag(A)。
lmmc_status_t lmmc_precond_apply(const lmmc_precond_t *precond, const lmmc_vec_t *rhs, lmmc_vec_t *out)
应用预处理子:求解 M*out = rhs。
lmmc_precond_type_t type
void lmmc_precond_destroy(lmmc_precond_t *precond)
销毁预处理子,释放内部资源。
@ LMMC_PRECOND_NONE
@ LMMC_PRECOND_JACOBI
@ LMMC_PRECOND_ILU0
@ LMMC_PRECOND_ILUT
通用预处理子句柄。
lmmc_status_t lmmc_ilu_apply(const lmmc_precond_t *precond, const lmmc_vec_t *rhs, lmmc_vec_t *out)
void lmmc_ilu_impl_destroy(lmmc_precond_ilu_impl_t *impl)
int lmmc_find_col_pos(const size_t *cols, size_t start, size_t end, size_t col, size_t *pos)
@ LMMC_SPARSE_CSR
lmmc_sparse_format_t format
通用稀疏矩阵(CSR / CSC 共用同一结构)。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_NOT_POSITIVE_DEFINITE
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_SINGULAR_MATRIX
@ LMMC_STATUS_NOT_IMPLEMENTED
@ LMMC_STATUS_INVALID_ARGUMENT