LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
itersolve_cg.c
浏览该文件的文档.
2
7
8static lmmc_status_t lmmc_cg_start(const lmmc_sparse_mat_t* a,
9 const lmmc_vec_t* b, const lmmc_itersolve_config_t* cfg,
11 lmmc_status_t st = lmmc_itersolve_residual(a, b, x, &s->ap, &s->r);
12 if (st != LMMC_STATUS_OK) {
13 return st;
14 }
15 return lmmc_itersolve_threshold(cfg, b, &s->r, &s->norm, &s->threshold);
16}
17
18static lmmc_status_t lmmc_cg_direction(const lmmc_precond_t* precond,
19 lmmc_cg_state_t* s, int initial) {
20 lmmc_real_t rho_new;
21 lmmc_status_t st = lmmc_apply_precond_or_identity(precond, &s->r, &s->z);
22 if (st != LMMC_STATUS_OK) {
23 return st;
24 }
25 st = lmmc_vec_dot_checked(&s->r, &s->z, &rho_new);
26 if (st != LMMC_STATUS_OK) {
27 return st;
28 }
29 if (fabs(rho_new) <= 1e-30) {
31 }
32 if (initial) {
33 s->rho = rho_new;
34 return lmmc_vec_copy(&s->z, &s->p);
35 }
36 lmmc_real_t beta = rho_new / s->rho;
37 if (!isfinite(beta)) {
39 }
40 for (size_t i = 0; i < s->p.size; ++i) {
41 lmmc_real_t product = beta * s->p.data[i];
42 s->p.data[i] = s->z.data[i] + product;
43 if (!isfinite(s->p.data[i])) {
45 }
46 }
47 s->rho = rho_new;
48 return LMMC_STATUS_OK;
49}
50
51static lmmc_status_t lmmc_cg_step(const lmmc_sparse_mat_t* a,
53 lmmc_real_t denom;
54 lmmc_status_t st = lmmc_sparse_mat_vec_mul(a, &s->p, &s->ap);
55 if (st != LMMC_STATUS_OK) {
56 return st;
57 }
58 st = lmmc_vec_dot_checked(&s->p, &s->ap, &denom);
59 if (st != LMMC_STATUS_OK) {
60 return st;
61 }
62 if (fabs(denom) <= 1e-30) {
64 }
65 lmmc_real_t alpha = s->rho / denom;
66 if (!isfinite(alpha)) {
68 }
69 for (size_t i = 0; i < x->size; ++i) {
70 lmmc_real_t product = alpha * s->p.data[i];
71 x->data[i] = x->data[i] + product;
72 if (!isfinite(x->data[i])) {
74 }
75 }
76 st = lmmc_vec_axpy(-alpha, &s->ap, &s->r);
77 if (st != LMMC_STATUS_OK) {
78 return st;
79 }
80 return lmmc_vec_norm2_checked(&s->r, &s->norm);
81}
82
83static lmmc_status_t lmmc_cg_iterate(const lmmc_sparse_mat_t* a,
84 const lmmc_precond_t* precond, const lmmc_itersolve_config_t* cfg,
86 size_t* iterations, int* converged) {
87 lmmc_status_t st = lmmc_cg_direction(precond, s, 1);
88 if (st != LMMC_STATUS_OK) {
89 return st;
90 }
91 for (size_t iter = 0; iter < cfg->max_iter; ++iter) {
92 st = lmmc_cg_step(a, x, s);
93 if (st != LMMC_STATUS_OK) {
94 return st;
95 }
96 *iterations = iter + 1;
97 if (result != NULL) {
98 result->final_residual_norm = s->norm;
99 }
100 lmmc_itersolve_do_log(cfg, *iterations, s->norm);
101 if (s->norm <= s->threshold) {
102 *converged = 1;
103 break;
104 }
105 st = lmmc_cg_direction(precond, s, 0);
106 if (st != LMMC_STATUS_OK) {
107 return st;
108 }
109 }
110 return LMMC_STATUS_OK;
111}
112
114 const lmmc_vec_t* b, const lmmc_precond_t* precond,
115 const lmmc_itersolve_config_t* cfg, lmmc_vec_t* x,
116 lmmc_itersolve_result_t* out_result) {
117 lmmc_itersolve_config_t local = {0};
118 lmmc_cg_state_t s = {0};
119 lmmc_real_t* storage = NULL;
120 size_t iterations = 0;
121 int converged = 0;
122 lmmc_status_t st = lmmc_itersolve_validate(a, b, precond, cfg, x, &local, out_result);
123 if (st != LMMC_STATUS_OK) {
124 goto cleanup;
125 }
126 lmmc_vec_t* vectors[] = {&s.r, &s.z, &s.p, &s.ap};
127 const size_t sizes[] = {b->size, b->size, b->size, b->size};
128 st = lmmc_itersolve_workspace(vectors, sizes, 4, &storage);
129 if (st != LMMC_STATUS_OK) {
130 goto cleanup;
131 }
132 st = lmmc_cg_start(a, b, &local, x, &s);
133 if (st != LMMC_STATUS_OK) {
134 goto cleanup;
135 }
136 lmmc_itersolve_initial(out_result, s.norm);
137 lmmc_itersolve_do_log(&local, 0, s.norm);
138 if (s.norm <= s.threshold) {
139 converged = 1;
140 }
141 else {
142 st = lmmc_cg_iterate(a, precond, &local, x, &s, out_result, &iterations, &converged);
143 }
144cleanup:
145 lmmc_itersolve_finish(out_result, converged, iterations, s.norm);
146 lmmc_memory_free(storage);
147 return st;
148}
double lmmc_real_t
Public and internal LMMC real type.
lmmc_status_t lmmc_vec_axpy(lmmc_real_t alpha, const lmmc_vec_t *x, lmmc_vec_t *y)
向量 AXPY 运算: 。
lmmc_status_t lmmc_vec_copy(const lmmc_vec_t *src, lmmc_vec_t *dst)
逐元素复制向量内容:dst = src。
lmmc_real_t * data
一维稠密向量。
lmmc_status_t lmmc_vec_dot_checked(const lmmc_vec_t *a, const lmmc_vec_t *b, lmmc_real_t *out_dot)
lmmc_status_t lmmc_vec_norm2_checked(const lmmc_vec_t *v, lmmc_real_t *out_norm)
lmmc_status_t lmmc_itersolve_threshold(const lmmc_itersolve_config_t *cfg, const lmmc_vec_t *b, const lmmc_vec_t *r, lmmc_real_t *norm, lmmc_real_t *threshold)
lmmc_status_t lmmc_apply_precond_or_identity(const lmmc_precond_t *precond, const lmmc_vec_t *rhs, lmmc_vec_t *out)
lmmc_status_t lmmc_itersolve_validate(const lmmc_sparse_mat_t *a, const lmmc_vec_t *b, const lmmc_precond_t *precond, const lmmc_itersolve_config_t *cfg, lmmc_vec_t *x, lmmc_itersolve_config_t *out_cfg, lmmc_itersolve_result_t *out_result)
lmmc_status_t lmmc_itersolve_workspace(lmmc_vec_t *const *vectors, const size_t *sizes, size_t count, lmmc_real_t **storage)
所有视图借用求解过程统一分配的存储区,最后一次日志回调后释放。
void lmmc_itersolve_finish(lmmc_itersolve_result_t *result, int converged, size_t iterations, lmmc_real_t norm)
lmmc_status_t lmmc_itersolve_residual(const lmmc_sparse_mat_t *a, const lmmc_vec_t *b, const lmmc_vec_t *x, lmmc_vec_t *ax, lmmc_vec_t *r)
void lmmc_itersolve_initial(lmmc_itersolve_result_t *result, lmmc_real_t norm)
void lmmc_itersolve_do_log(const lmmc_itersolve_config_t *cfg, size_t iter, lmmc_real_t residual_norm)
lmmc_status_t lmmc_cg_solve(const lmmc_sparse_mat_t *a, const lmmc_vec_t *b, const lmmc_precond_t *precond, const lmmc_itersolve_config_t *cfg, lmmc_vec_t *x, lmmc_itersolve_result_t *out_result)
共轭梯度法(CG)求解对称正定稀疏系统 A*x = b。
迭代求解器配置。
迭代求解的结果统计。
lmmc_real_t threshold
void lmmc_memory_free(void *pointer)
通用预处理子句柄。
lmmc_status_t lmmc_sparse_mat_vec_mul(const lmmc_sparse_mat_t *sparse, const lmmc_vec_t *x, lmmc_vec_t *y)
稀疏矩阵-稠密向量乘法:y = A * x。
通用稀疏矩阵(CSR / CSC 共用同一结构)。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_NUMERICAL_FAILURE