5 if (v == NULL || out_norm == NULL || v->
data == NULL || v->
size == 0) {
10 for (
size_t i = 0; i < v->
size; ++i) {
11 if (!lmmc_is_finite(&v->
data[i])) {
21 if (!lmmc_is_finite(&*out_norm)) {
32 if (!lmmc_is_finite(&*out_dot)) {
43 if (precond == NULL) {
60 if (out_cfg == NULL || problem_size == 0) {
64 if (problem_size > ((
size_t)-1) / 20) {
67 max_iter = problem_size * 20;
80 out_cfg->
restart = (problem_size < 30) ? problem_size : 30;
98 if (lmmc_sparse_validate(a) !=
LMMC_STATUS_OK || b == NULL || x == NULL ||
99 b->
data == NULL || x->
data == NULL) {
120 lmmc_status_t st = lmmc_itersolve_square_dimensions(a, b, x);
134 st = lmmc_itersolve_validate_config(out_cfg);
139 if (precond != NULL && precond->
size != b->
size) {
144 if (out_result != NULL) {
158 const size_t* sizes,
size_t count,
lmmc_real_t** storage) {
160 for (
size_t i = 0; i < count; ++i) {
161 if (!lmmc_safe_add_size(total, sizes[i], &total)) {
166 if (!lmmc_safe_mul_size(total,
sizeof(
lmmc_real_t), &bytes)) {
170 if (*storage == NULL) {
173 memset(*storage, 0, bytes);
175 for (
size_t i = 0; i < count; ++i) {
176 *vectors[i] = (
lmmc_vec_t){sizes[i], next, 0};
183 if (result != NULL) {
192 if (result != NULL) {
199 int converged,
size_t iterations,
lmmc_real_t norm) {
200 if (result != NULL) {
203 if (isfinite(norm)) {
215 for (
size_t i = 0; i < b->
size; ++i) {
224 for (
size_t i = 0; i < x->
size; ++i) {
225 if (!isfinite(x->
data[i])) {
233 for (
size_t i = 0; i < b->
size; ++i) {
263 if (b == NULL || x == NULL || b->
data == NULL || x->
data == NULL ||
279 if ((local->
apply_op != NULL) == (a != NULL)) {
282 return lmmc_itersolve_validate_config(local);
304 for (i = 0; i < y_out->
size; ++i) {
305 y_out->
data[i] = 0.0;
307 for (i = 0; i < a->
rows; ++i) {
309 size_t end = a->
row_ptr[i + 1];
310 for (j = start; j < end; ++j) {
325 for (j = 0; j < y_out->
size; ++j) {
326 y_out->
data[j] = 0.0;
329 for (j = 0; j < a->
cols; ++j) {
331 size_t end = a->
row_ptr[j + 1];
333 for (i = start; i < end; ++i) {
337 y_out->
data[j] = acc;
355 return lmmc_matvec_transpose_csr(a, x_in, y_out);
357 return lmmc_matvec_transpose_csc(a, x_in, y_out);
#define LMMC_REAL_INIT(x)
初始化一个 lmmc_real_t 变量(POD 类型为空操作)。
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_SET_D(dst, dbl)
将一个 double 字面量赋值到 lmmc_real_t 。
lmmc_status_t lmmc_vec_dot(const lmmc_vec_t *a, const lmmc_vec_t *b, lmmc_real_t *out_dot)
计算两个等长向量的内积: 。
lmmc_status_t lmmc_vec_norm2(const lmmc_vec_t *x, lmmc_real_t *out_norm)
计算向量的欧几里得(L2)范数: 。 采用缩放平方和累加;最终结果超出 binary64 范围时可为无穷。
lmmc_status_t lmmc_vec_copy(const lmmc_vec_t *src, lmmc_vec_t *dst)
逐元素复制向量内容:dst = src。
void lmmc_diagnostic_emit(const lmmc_diagnostic_sink_t *sink, const lmmc_diagnostic_t *diagnostic)
通过调用方持有的接收器发送一个诊断事件;空接收器直接完成.
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_itersolve_true_residual(const lmmc_sparse_mat_t *a, const lmmc_itersolve_config_t *cfg, const lmmc_vec_t *b, const lmmc_vec_t *x, lmmc_vec_t *r, lmmc_real_t *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_transpose(const lmmc_sparse_mat_t *a, const lmmc_itersolve_config_t *cfg, const lmmc_vec_t *x_in, lmmc_vec_t *y_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_result_init(lmmc_itersolve_result_t *result)
lmmc_status_t lmmc_itersolve_matvec(const lmmc_sparse_mat_t *a, const lmmc_itersolve_config_t *cfg, const lmmc_vec_t *x_in, lmmc_vec_t *y_out)
通过无矩阵算子或稀疏矩阵计算 y = A*x。
void lmmc_itersolve_initial(lmmc_itersolve_result_t *result, lmmc_real_t norm)
lmmc_status_t lmmc_itersolve_dispatch_config(const lmmc_sparse_mat_t *a, const lmmc_vec_t *b, const lmmc_itersolve_config_t *cfg, const lmmc_vec_t *x, lmmc_itersolve_config_t *local)
void lmmc_itersolve_do_log(const lmmc_itersolve_config_t *cfg, size_t iter, lmmc_real_t residual_norm)
lmmc_diagnostic_sink_t diagnostics
lmmc_matvec_op_t apply_transpose_op
lmmc_real_t final_residual_norm
lmmc_status_t lmmc_itersolve_default_config(size_t problem_size, lmmc_itersolve_config_t *out_cfg)
根据问题规模生成迭代求解器默认配置。
lmmc_real_t initial_residual_norm
lmmc_matvec_op_t apply_op
void * lmmc_memory_alloc(size_t size)
#define LMMC_DEFAULT_ABS_TOL
库默认的绝对容差.
lmmc_status_t lmmc_precond_apply(const lmmc_precond_t *precond, const lmmc_vec_t *rhs, lmmc_vec_t *out)
应用预处理子:求解 M*out = rhs。
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。
lmmc_sparse_format_t format
通用稀疏矩阵(CSR / CSC 共用同一结构)。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT