13 size_t mn, pairs, scalars, extra;
15 if (!lmmc_safe_mul_size(m, n, &mn) ||
16 !lmmc_safe_mul_size(mn, 2, &pairs) ||
17 !lmmc_safe_mul_size(m, 2, &scalars) ||
18 !lmmc_safe_add_size(pairs, scalars, &extra)) {
39 const size_t n = work->
g.
size;
44 for (i = 0; i < n; ++i) {
45 sy += work->
s.
data[newest * n + i] * work->
y.
data[newest * n + i];
46 yy += work->
y.
data[newest * n + i] * work->
y.
data[newest * n + i];
50 for (i = 0; i < n; ++i) {
51 work->
q.
data[i] *= gamma;
59 const size_t n = work->
g.
size;
60 const size_t m = work->
s.
rows;
64 for (k = 0; k < bound; ++k) {
67 for (i = 0; i < n; ++i) {
68 dot += work->
s.
data[idx * n + i] * work->
q.
data[i];
71 for (i = 0; i < n; ++i) {
75 lbfgs_scale_direction(work);
76 for (k = bound; k-- > 0;) {
80 for (i = 0; i < n; ++i) {
81 dot += work->
y.
data[idx * n + i] * work->
q.
data[i];
83 beta = work->
rho.
data[idx] * dot;
84 for (i = 0; i < n; ++i) {
88 for (i = 0; i < n; ++i) {
93static void lbfgs_store_history(
96 const size_t n = x->
size;
97 const size_t m = work->
s.
rows;
107 for (i = 0; i < n; ++i) {
110 sy += work->
s.
data[store_idx * n + i] * work->
y.
data[store_idx * n + i];
112 if (fabs(sy) > 1e-300) {
113 work->
rho.
data[store_idx] = 1.0 / sy;
115 work->
rho.
data[store_idx] = 0.0;
124 for (i = 0; i < work->
g.
size; ++i) {
128 for (i = 0; i < work->
g.
size; ++i) {
142 lbfgs_direction(work);
143 dg = lbfgs_descent_derivative(work, norm);
145 &work->
x_new, value, dg, 40, 0)) {
151 lbfgs_store_history(work, x);
166 if (obj == NULL || grad == NULL ||
177 value = obj(x, user_data);
178 for (iter = 0; ; ++iter) {
181 if (!isfinite(value)) {
186 out->
failure_reason = lbfgs_step(&work, obj, grad, user_data, x, &value, norm);
double lmmc_real_t
Public and internal LMMC real type.
void lmmc_memory_free(void *pointer)
int lmmc_optimize_armijo(lmmc_opt_obj_t obj, void *user_data, const lmmc_vec_t *x, const lmmc_vec_t *direction, lmmc_vec_t *trial, lmmc_real_t *value, lmmc_real_t derivative, int attempts, int subtract)
lmmc_real_t lmmc_optimize_norm(const lmmc_vec_t *v)
计算向量的 L2 范数。
void lmmc_optimize_emit(const lmmc_optimize_config_t *cfg, const char *operation, size_t iteration, const lmmc_real_t *values, size_t value_count)
lmmc_vec_t lmmc_opt_workspace_vector(lmmc_opt_workspace_t *work, size_t n)
int lmmc_optimize_stop(lmmc_real_t norm, lmmc_real_t *initial, size_t iteration, const lmmc_optimize_config_t *cfg, lmmc_optimize_result_t *out)
lmmc_status_t lmmc_opt_workspace_create(size_t n, size_t vectors, size_t matrices, size_t extra, int need_pivots, lmmc_opt_workspace_t *work)
void lmmc_optimize_result_init(lmmc_optimize_result_t *out)
int lmmc_optimize_arguments_valid(const lmmc_vec_t *x, const lmmc_optimize_config_t *cfg, const lmmc_optimize_result_t *out)
lmmc_optimize_failure_t
优化失败原因枚举。
@ LMMC_OPT_FAILURE_LINE_SEARCH_FAILED
@ LMMC_OPT_FAILURE_NUMERICAL_ISSUE
lmmc_status_t lmmc_minimize_lbfgs(lmmc_opt_obj_t obj, lmmc_opt_grad_t grad, void *user_data, lmmc_vec_t *x, const lmmc_optimize_config_t *cfg, lmmc_optimize_result_t *out)
L-BFGS 无约束最小化。
lmmc_optimize_failure_t failure_reason
lmmc_status_t(*) lmmc_opt_grad_t(const lmmc_vec_t *x, lmmc_vec_t *grad, void *user_data)
梯度回调:计算 ∇f(x)。
lmmc_real_t(*) lmmc_opt_obj_t(const lmmc_vec_t *x, void *user_data)
目标函数回调:计算标量 f(x)。
lmmc_real_t final_residual
工作区由本次调用拥有,视图仅借用存储,释放由调用方负责。
lmmc_opt_workspace_t arena
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT