LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
itersolve_gmres.c
浏览该文件的文档.
2
3static lmmc_status_t lmmc_gmres_start(const lmmc_sparse_mat_t* a,
4 const lmmc_vec_t* b, const lmmc_itersolve_config_t* cfg,
5 const lmmc_vec_t* x, lmmc_gmres_state_t* s) {
6 lmmc_real_t norm_b;
8 if (st != LMMC_STATUS_OK) {
9 return st;
10 }
11 st = lmmc_itersolve_residual(a, b, x, &s->ax, &s->r);
12 if (st != LMMC_STATUS_OK) {
13 return st;
14 }
15 st = lmmc_vec_norm2_checked(&s->r, &s->norm);
16 if (st != LMMC_STATUS_OK) {
17 return st;
18 }
19 s->threshold = cfg->abs_tol + cfg->rel_tol * norm_b;
21}
22
23static lmmc_status_t lmmc_gmres_restart(const lmmc_sparse_mat_t* a,
24 const lmmc_vec_t* b, const lmmc_precond_t* precond,
26 lmmc_real_t beta;
28 if (st != LMMC_STATUS_OK) {
29 return st;
30 }
31 st = lmmc_itersolve_residual(a, b, &s->x_base, &s->ax, &s->r);
32 if (st != LMMC_STATUS_OK) {
33 return st;
34 }
35 st = lmmc_apply_precond_or_identity(precond, &s->r, &s->z);
36 if (st != LMMC_STATUS_OK) {
37 return st;
38 }
39 st = lmmc_vec_norm2_checked(&s->z, &beta);
40 if (st != LMMC_STATUS_OK) {
41 return st;
42 }
43 if (beta <= 1e-30) {
45 }
46 memset(s->h, 0, s->h_count * sizeof(lmmc_real_t));
47 memset(s->cs, 0, s->restart * sizeof(lmmc_real_t));
48 memset(s->sn, 0, s->restart * sizeof(lmmc_real_t));
49 memset(s->g, 0, (s->restart + 1) * sizeof(lmmc_real_t));
50 memset(s->y, 0, s->restart * sizeof(lmmc_real_t));
51 st = lmmc_gmres_normalize(&s->basis[0], &s->z, beta);
52 if (st == LMMC_STATUS_OK) {
53 s->g[0] = beta;
54 }
55 return st;
56}
57
58static lmmc_status_t lmmc_gmres_step(const lmmc_sparse_mat_t* a,
59 const lmmc_vec_t* b, const lmmc_precond_t* precond,
60 lmmc_gmres_state_t* s, size_t j, lmmc_real_t* h_next, int* breakdown) {
61 lmmc_status_t st = lmmc_gmres_arnoldi(a, precond, s, j, h_next);
62 if (st != LMMC_STATUS_OK) {
63 return st;
64 }
65 st = lmmc_gmres_rotate(s, j, breakdown);
66 if (st != LMMC_STATUS_OK || *breakdown) {
67 return st;
68 }
69 st = lmmc_gmres_back_substitute(s, j + 1);
70 if (st != LMMC_STATUS_OK) {
71 return st;
72 }
73 st = lmmc_gmres_trial(s, j);
74 if (st != LMMC_STATUS_OK) {
75 return st;
76 }
77 st = lmmc_itersolve_residual(a, b, &s->x_trial, &s->ax, &s->r);
78 if (st != LMMC_STATUS_OK) {
79 return st;
80 }
81 return lmmc_vec_norm2_checked(&s->r, &s->norm);
82}
83
84static lmmc_status_t lmmc_gmres_cycle(const lmmc_sparse_mat_t* a,
85 const lmmc_vec_t* b, const lmmc_precond_t* precond,
88 size_t* iterations, int* converged) {
89 size_t limit = s->restart;
90 if (limit > cfg->max_iter - *iterations) {
91 limit = cfg->max_iter - *iterations;
92 }
93 lmmc_status_t st = lmmc_gmres_restart(a, b, precond, x, s);
94 if (st != LMMC_STATUS_OK) {
95 return st;
96 }
97 for (size_t j = 0; j < limit; ++j) {
98 lmmc_real_t h_next;
99 int breakdown;
100 st = lmmc_gmres_step(a, b, precond, s, j, &h_next, &breakdown);
101 if (st != LMMC_STATUS_OK) {
102 return st;
103 }
104 if (breakdown) {
106 }
107 *iterations += 1;
108 if (result != NULL) {
109 result->final_residual_norm = s->norm;
110 }
111 lmmc_itersolve_do_log(cfg, *iterations, s->norm);
112 st = lmmc_vec_copy(&s->x_trial, x);
113 if (st != LMMC_STATUS_OK) {
114 return st;
115 }
116 if (s->norm <= s->threshold) {
117 *converged = 1;
118 return LMMC_STATUS_OK;
119 }
120 if (h_next <= 1e-30) {
122 }
123 st = lmmc_gmres_normalize(&s->basis[j + 1], &s->w, h_next);
124 if (st != LMMC_STATUS_OK) {
125 return st;
126 }
127 }
128 return LMMC_STATUS_OK;
129}
130
132 const lmmc_vec_t* b, const lmmc_precond_t* precond,
133 const lmmc_itersolve_config_t* cfg, lmmc_vec_t* x,
134 lmmc_itersolve_result_t* out_result) {
135 lmmc_itersolve_config_t local = {0};
136 lmmc_gmres_state_t s = {0};
137 size_t iterations = 0;
138 int converged = 0;
139 lmmc_status_t st = lmmc_itersolve_validate(a, b, precond, cfg, x, &local, out_result);
140 if (st != LMMC_STATUS_OK) {
141 goto cleanup;
142 }
143 st = lmmc_gmres_workspace(b->size, local.restart, &s);
144 if (st != LMMC_STATUS_OK) {
145 goto cleanup;
146 }
147 st = lmmc_gmres_start(a, b, &local, x, &s);
148 if (st != LMMC_STATUS_OK) {
149 goto cleanup;
150 }
151 lmmc_itersolve_initial(out_result, s.norm);
152 lmmc_itersolve_do_log(&local, 0, s.norm);
153 converged = s.norm <= s.threshold;
154 while (iterations < local.max_iter && !converged) {
155 st = lmmc_gmres_cycle(a, b, precond, &local, x, &s, out_result, &iterations, &converged);
156 if (st != LMMC_STATUS_OK) {
157 break;
158 }
159 }
160cleanup:
161 lmmc_itersolve_finish(out_result, converged, iterations, s.norm);
163 return st;
164}
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_status_t lmmc_vec_norm2_checked(const lmmc_vec_t *v, lmmc_real_t *out_norm)
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)
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_gmres_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)
重启型 GMRES 求解一般非对称稀疏系统 A*x = b。
迭代求解器配置。
迭代求解的结果统计。
lmmc_status_t lmmc_gmres_trial(lmmc_gmres_state_t *s, size_t j)
lmmc_status_t lmmc_gmres_normalize(lmmc_vec_t *out, const lmmc_vec_t *in, lmmc_real_t norm)
lmmc_status_t lmmc_gmres_workspace(size_t n, size_t restart, lmmc_gmres_state_t *s)
lmmc_status_t lmmc_gmres_arnoldi(const lmmc_sparse_mat_t *a, const lmmc_precond_t *precond, lmmc_gmres_state_t *s, size_t j, lmmc_real_t *h_next)
lmmc_status_t lmmc_gmres_back_substitute(lmmc_gmres_state_t *s, size_t dim)
lmmc_status_t lmmc_gmres_rotate(lmmc_gmres_state_t *s, size_t j, int *breakdown)
void lmmc_memory_free(void *pointer)
通用预处理子句柄。
通用稀疏矩阵(CSR / CSC 共用同一结构)。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_NUMERICAL_FAILURE