9static lmmc_status_t lmmc_gmres_scalar_count(
size_t n,
size_t restart,
10 size_t* h_count,
size_t* scalar_count) {
11 size_t basis_count, vector_count, rotations;
12 if (!lmmc_safe_add_size(restart, 1, &basis_count) ||
13 !lmmc_safe_mul_size(basis_count, restart, h_count)) {
16 if (!lmmc_safe_add_size(basis_count, 6, &vector_count) ||
17 !lmmc_safe_mul_size(vector_count, n, scalar_count)) {
20 if (!lmmc_safe_mul_size(restart, 4, &rotations) ||
21 !lmmc_safe_add_size(rotations, 1, &rotations)) {
24 if (!lmmc_safe_add_size(*scalar_count, *h_count, scalar_count) ||
25 !lmmc_safe_add_size(*scalar_count, rotations, scalar_count)) {
31static lmmc_status_t lmmc_gmres_allocation_bytes(
size_t basis_count,
32 size_t scalar_count,
size_t* metadata,
size_t* bytes) {
33 if (!lmmc_safe_mul_size(basis_count,
sizeof(
lmmc_vec_t), metadata)) {
37 size_t padding = (alignment - *metadata % alignment) % alignment;
38 if (!lmmc_safe_add_size(*metadata, padding, metadata) ||
39 !lmmc_safe_mul_size(scalar_count,
sizeof(
lmmc_real_t), bytes) ||
40 !lmmc_safe_add_size(*metadata, *bytes, bytes)) {
48 size_t scalar_count, bytes, metadata;
49 s->
restart = restart == 0 ? (n < 30 ? n : 30) : restart;
60 size_t basis_count = s->
restart + 1;
61 st = lmmc_gmres_allocation_bytes(basis_count, scalar_count, &metadata, &bytes);
66 if (s->
basis == NULL) {
69 memset(s->
basis, 0, bytes);
71 s->
r = lmmc_gmres_view(n, &next);
72 s->
z = lmmc_gmres_view(n, &next);
73 s->
w = lmmc_gmres_view(n, &next);
74 s->
ax = lmmc_gmres_view(n, &next);
75 s->
x_base = lmmc_gmres_view(n, &next);
76 s->
x_trial = lmmc_gmres_view(n, &next);
77 for (
size_t i = 0; i < basis_count; ++i) {
78 s->
basis[i] = lmmc_gmres_view(n, &next);
103 for (
size_t i = 0; i <= j; ++i) {
117 s->
h[(j + 1) * s->
restart + j] = *h_next;
123 for (
size_t i = 0; i < j; ++i) {
128 s->
h[i * s->
restart + j] = first + second;
129 first = -s->
sn[i] * h0;
130 second = s->
cs[i] * h1;
131 s->
h[(i + 1) * s->
restart + j] = first + second;
137 lmmc_gmres_previous_rotations(s, j);
143 if (!isfinite(denom)) {
146 if (denom <= 1e-30) {
150 s->
cs[j] = hj / denom;
151 s->
sn[j] = hsub / denom;
152 if (!isfinite(s->
cs[j]) || !isfinite(s->
sn[j])) {
155 first = s->
cs[j] * hj;
156 second = s->
sn[j] * hsub;
157 s->
h[j * s->
restart + j] = first + second;
158 s->
h[(j + 1) * s->
restart + j] = 0.0;
160 s->
g[j + 1] = -s->
sn[j] * s->
g[j];
166 for (
size_t ii = dim; ii > 0; --ii) {
169 for (
size_t j = i + 1; j < dim; ++j) {
174 if (!isfinite(sum) || !isfinite(diag) || fabs(diag) <= 1e-30) {
177 s->
y[i] = sum / diag;
178 if (!isfinite(s->
y[i])) {
188 for (
size_t k = 0; k <= j; ++k) {
192 if (!isfinite(val)) {
202 for (
size_t i = 0; i < out->
size; ++i) {
204 if (!isfinite(out->
data[i])) {
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_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_apply_precond_or_identity(const lmmc_precond_t *precond, const lmmc_vec_t *rhs, lmmc_vec_t *out)
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_alloc(size_t size)
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_NUMERICAL_FAILURE
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT