49 double anorm,
int* converged) {
64 if (norm_atr != 0.0) {
69 double ratio = norm_atr / anorm;
70 if (!isfinite(ratio)) {
73 *converged = ratio <= cfg->
rel_tol;
80 for (
size_t i = 0; i < s->
u.
size; ++i) {
91 for (
size_t i = 0; i < s->
v.
size; ++i) {
100 int* basis_exhausted) {
101 const double old_alpha = s->
alpha;
106 for (
size_t i = 0; i < s->
u.
size; ++i) {
114 if (!isfinite(s->
anorm)) {
118 if (s->
beta != 0.0) {
119 for (
size_t i = 0; i < s->
u.
size; ++i) {
126 for (
size_t i = 0; i < s->
v.
size; ++i) {
133 if (s->
alpha != 0.0) {
134 for (
size_t i = 0; i < s->
v.
size; ++i) {
139 *basis_exhausted = s->
beta == 0.0 || s->
alpha == 0.0;
147 if (!isfinite(s->
rho)) {
154 const double sn = s->
beta / s->
rho;
157 const double phi = cs * s->
phi_bar;
159 const double scale = phi / s->
rho;
160 if (!isfinite(cs) || !isfinite(sn) || !isfinite(s->
theta) ||
161 !isfinite(s->
rho_bar) || !isfinite(phi) || !isfinite(s->
phi_bar) ||
165 for (
size_t i = 0; i < x->
size; ++i) {
167 if (!isfinite(x->
data[i])) {
182 if (s->
alpha == 0.0) {
183 return lmmc_lsqr_stationary(a, cfg, s, 0.0, converged);
185 for (
size_t iter = 0; iter < cfg->
max_iter; ++iter) {
187 st = lmmc_lsqr_bidiagonalize(a, cfg, s, &basis_exhausted);
193 st = lmmc_lsqr_rotate(x, s, &updated);
198 *iterations = iter + 1;
210 st = lmmc_lsqr_stationary(a, cfg, s, s->
anorm, converged);
215 if (!updated || *converged || basis_exhausted || *iterations == cfg->
max_iter) {
218 const double scale = s->
theta / s->
rho;
219 if (!isfinite(scale)) {
222 for (
size_t i = 0; i < s->
w.
size; ++i) {
224 if (!isfinite(s->
w.
data[i])) {
242 size_t iterations = 0;
251 st = lmmc_lsqr_start(a, b, &local, x, &s);
260 st = lmmc_lsqr_iterate(a, b, &local, x, &s, &iterations, &converged);
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_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_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_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)
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_matvec_op_t apply_transpose_op
lmmc_status_t lmmc_lsqr_solve(const lmmc_sparse_mat_t *a, const lmmc_vec_t *b, const lmmc_itersolve_config_t *cfg, lmmc_vec_t *x, lmmc_itersolve_result_t *out_result)
LSQR 求解最小二乘问题 min ||Ax - b||_2 。
void lmmc_memory_free(void *pointer)
通用稀疏矩阵(CSR / CSC 共用同一结构)。
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_INVALID_ARGUMENT