|
LMMC
Lamina Mathematic core
|
优化与非线性方程组求解模块。 更多...
#include <stddef.h>#include "lmmc/status.h"#include "lmmc/config.h"#include "lmmc/dense.h"#include "lmmc/diagnostic.h"结构体 | |
| struct | lmmc_optimize_config_t |
| 优化算法配置参数。 更多... | |
| struct | lmmc_optimize_result_t |
| 优化结果。 更多... | |
类型定义 | |
| typedef lmmc_status_t(*) | lmmc_opt_func_t(const lmmc_vec_t *x, lmmc_vec_t *F, void *user_data) |
| 非线性函数回调:计算 F(x)。 | |
| typedef lmmc_status_t(*) | lmmc_opt_jac_t(const lmmc_vec_t *x, lmmc_mat_t *J, void *user_data) |
| Jacobian 回调:计算 J(x)。 | |
| typedef lmmc_status_t(*) | lmmc_opt_grad_t(const lmmc_vec_t *x, lmmc_vec_t *grad, void *user_data) |
| 梯度回调:计算 ∇f(x)。 | |
| typedef lmmc_real_t(*) | lmmc_opt_obj_t(const lmmc_vec_t *x, void *user_data) |
| 目标函数回调:计算标量 f(x)。 | |
优化与非线性方程组求解模块。
提供 Newton、Broyden 非线性方程组求解器,以及 L-BFGS、 Levenberg-Marquardt、梯度下降等无约束优化算法。
在文件 optimize.h 中定义.
| struct lmmc_optimize_config_t |
优化算法配置参数。
在文件 optimize.h 第 63 行定义.
| 成员变量 | ||
|---|---|---|
| lmmc_real_t | abs_tol |
残差或梯度范数的绝对收敛容差。 |
| lmmc_real_t | rel_tol |
相对于初始范数的收敛容差,范围 [0,1)。 |
| size_t | max_iter |
最大迭代更新次数,必须大于 0;最后一次更新后仍检查收敛。 |
| size_t | lbfgs_memory |
L-BFGS 存储的 (s,y) 对数,必须大于 0。 |
| lmmc_real_t | lm_damping |
LM 初始阻尼参数 λ,必须为有限正数。 |
| lmmc_diagnostic_sink_t | diagnostics |
统一诊断出口。 |
| struct lmmc_optimize_result_t |
优化结果。
在文件 optimize.h 第 86 行定义.
| 成员变量 | ||
|---|---|---|
| int | converged |
非零表示已收敛。 |
| size_t | num_iter |
已完成的迭代更新次数;初始点收敛时为 0。 |
| lmmc_real_t | final_residual |
输出 x 的残差范数(L-BFGS/梯度下降为梯度范数);回调失败无法求值时为 NaN。 |
| lmmc_optimize_failure_t | failure_reason |
失败原因(converged=0 时有效)。 |
| typedef lmmc_status_t(*) lmmc_opt_func_t(const lmmc_vec_t *x, lmmc_vec_t *F, void *user_data) |
非线性函数回调:计算 F(x)。
| [in] | x | 当前迭代点。 |
| [out] | F | 函数值输出向量(与 x 同维)。 |
| [in] | user_data | 用户自定义数据指针。 |
在文件 optimize.h 第 29 行定义.
| typedef lmmc_status_t(*) lmmc_opt_jac_t(const lmmc_vec_t *x, lmmc_mat_t *J, void *user_data) |
Jacobian 回调:计算 J(x)。
| [in] | x | 当前迭代点。 |
| [out] | J | Jacobian 矩阵输出(n×n)。 |
| [in] | user_data | 用户自定义数据指针。 |
在文件 optimize.h 第 39 行定义.
| typedef lmmc_status_t(*) lmmc_opt_grad_t(const lmmc_vec_t *x, lmmc_vec_t *grad, void *user_data) |
梯度回调:计算 ∇f(x)。
| [in] | x | 当前迭代点。 |
| [out] | grad | 梯度输出向量(与 x 同维)。 |
| [in] | user_data | 用户自定义数据指针。 |
在文件 optimize.h 第 49 行定义.
| typedef lmmc_real_t(*) lmmc_opt_obj_t(const lmmc_vec_t *x, void *user_data) |
优化失败原因枚举。
在文件 optimize.h 第 75 行定义.
| lmmc_status_t lmmc_optimize_default_config | ( | lmmc_optimize_config_t * | cfg | ) |
初始化默认优化配置。
默认值:abs_tol=1e-12, rel_tol=1e-10, max_iter=1000, lbfgs_memory=10, lm_damping=1e-3,诊断 sink 为空。 所有求解器在分配工作区或调用用户回调前验证配置。收敛条件为 norm <= abs_tol 或 norm <= rel_tol * initial_norm。
在文件 optimize.c 第 62 行定义.
引用了 lmmc_optimize_config_t::abs_tol, lmmc_optimize_config_t::diagnostics, lmmc_optimize_config_t::lbfgs_memory, lmmc_optimize_config_t::lm_damping, lmmc_optimize_default_config(), LMMC_STATUS_INVALID_ARGUMENT, LMMC_STATUS_OK, lmmc_optimize_config_t::max_iter , 以及 lmmc_optimize_config_t::rel_tol.
被这些函数引用 lmmc_ode_implicit_euler_solve(), lmmc_ode_trapezoidal_solve() , 以及 lmmc_optimize_default_config().
| lmmc_status_t lmmc_nleq_newton | ( | lmmc_opt_func_t | F, |
| lmmc_opt_jac_t | J, | ||
| void * | user_data, | ||
| lmmc_vec_t * | x, | ||
| const lmmc_optimize_config_t * | cfg, | ||
| lmmc_optimize_result_t * | out ) |
Newton 法求解非线性方程组 F(x) = 0。
每步求解 J(x)δ = -F(x) 并通过 LU 分解;若 J 为 NULL,则使用 单边有限差分近似 Jacobian,默认步长大小为 sqrt(LMMC_REAL_EPSILON) * max(|x_j|, 1)。优先使用前向扰动; 当前向点不可表示时自动改用后向扰动,并使用实际可表示步长。 残差范数采用缩放平方和计算,避免有限大残差或小残差因直接平方而 溢出或下溢。
| [in] | F | 非线性函数回调。 |
| [in] | J | Jacobian 回调(可为 NULL,使用有限差分)。 |
| [in] | user_data | 传递给回调的用户数据。 |
| [in,out] | x | 初始猜测 / 输出解。 |
| [in] | cfg | 算法配置。 |
| [out] | out | 迭代结果。 |
检查每个迭代结果,包括最后一次允许的更新。
差分计算复用求解阶段暂时空闲的 delta 与 rhs 缓冲区。
在文件 optimize_newton.c 第 47 行定义.
引用了 lmmc_opt_workspace_t::allocation, lmmc_newton_workspace_t::arena, lmmc_newton_workspace_t::delta, lmmc_optimize_result_t::failure_reason, lmmc_optimize_result_t::final_residual, lmmc_newton_workspace_t::jacobian, lmmc_memory_free(), lmmc_nleq_newton(), LMMC_OPT_FAILURE_NONE, LMMC_OPT_FAILURE_NUMERICAL_ISSUE, lmmc_optimize_arguments_valid(), lmmc_optimize_emit(), lmmc_optimize_jacobian(), lmmc_optimize_norm(), lmmc_optimize_result_init(), lmmc_optimize_stop(), LMMC_STATUS_INVALID_ARGUMENT, LMMC_STATUS_OK, lmmc_optimize_result_t::num_iter, lmmc_newton_workspace_t::rhs, lmmc_vec_t::size , 以及 lmmc_newton_workspace_t::value.
被这些函数引用 lmmc_nleq_newton().
| lmmc_status_t lmmc_nleq_broyden | ( | lmmc_opt_func_t | F, |
| void * | user_data, | ||
| lmmc_vec_t * | x, | ||
| const lmmc_optimize_config_t * | cfg, | ||
| lmmc_optimize_result_t * | out ) |
Broyden 法求解非线性方程组 F(x) = 0。
维护 B ≈ J 的秩一更新:B += (ΔF - B·Δx)·Δxᵀ / (Δxᵀ·Δx)。 初始 B 通过有限差分近似。
| [in] | F | 非线性函数回调。 |
| [in] | user_data | 传递给回调的用户数据。 |
| [in,out] | x | 初始猜测 / 输出解。 |
| [in] | cfg | 算法配置。 |
| [out] | out | 迭代结果。 |
首次更新前尚无步长差分或下一步残差。
在文件 optimize_broyden.c 第 79 行定义.
引用了 lmmc_opt_workspace_t::allocation, lmmc_broyden_workspace_t::arena, lmmc_broyden_workspace_t::B, lmmc_broyden_workspace_t::delta_x, lmmc_optimize_result_t::failure_reason, lmmc_optimize_result_t::final_residual, lmmc_memory_free(), lmmc_nleq_broyden(), LMMC_OPT_FAILURE_NONE, LMMC_OPT_FAILURE_NUMERICAL_ISSUE, lmmc_optimize_arguments_valid(), lmmc_optimize_emit(), lmmc_optimize_jacobian(), lmmc_optimize_norm(), lmmc_optimize_result_init(), lmmc_optimize_stop(), LMMC_STATUS_INVALID_ARGUMENT, LMMC_STATUS_OK, lmmc_broyden_workspace_t::next_value, lmmc_optimize_result_t::num_iter, lmmc_vec_t::size , 以及 lmmc_broyden_workspace_t::value.
被这些函数引用 lmmc_nleq_broyden().
| 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 无约束最小化。
使用两循环递归与 m 个存储的 (s,y) 对。含 Armijo 回溯线搜索。
| [in] | obj | 目标函数回调。 |
| [in] | grad | 梯度回调。 |
| [in] | user_data | 传递给回调的用户数据。 |
| [in,out] | x | 初始猜测 / 输出解。 |
| [in] | cfg | 算法配置(lbfgs_memory 指定 m)。 |
| [out] | out | 迭代结果。 |
在文件 optimize_lbfgs.c 第 157 行定义.
引用了 lmmc_opt_workspace_t::allocation, lmmc_lbfgs_workspace_t::arena, lmmc_optimize_result_t::failure_reason, lmmc_optimize_result_t::final_residual, lmmc_lbfgs_workspace_t::g, lmmc_optimize_config_t::lbfgs_memory, lmmc_memory_free(), lmmc_minimize_lbfgs(), LMMC_OPT_FAILURE_NONE, LMMC_OPT_FAILURE_NUMERICAL_ISSUE, lmmc_optimize_arguments_valid(), lmmc_optimize_emit(), lmmc_optimize_norm(), lmmc_optimize_result_init(), lmmc_optimize_stop(), LMMC_STATUS_INVALID_ARGUMENT, LMMC_STATUS_OK, lmmc_optimize_result_t::num_iter , 以及 lmmc_vec_t::size.
被这些函数引用 lmmc_minimize_lbfgs().
| lmmc_status_t lmmc_minimize_levenberg_marquardt | ( | lmmc_opt_func_t | residual, |
| lmmc_opt_jac_t | J, | ||
| void * | user_data, | ||
| lmmc_vec_t * | x, | ||
| const lmmc_optimize_config_t * | cfg, | ||
| lmmc_optimize_result_t * | out ) |
Levenberg-Marquardt 非线性最小二乘。
求解 (JᵀJ + λI)δ = -Jᵀr,自适应调整 λ(接受步减小 λ,拒绝步增大 λ)。 当 ||r||₂ 或 ||Jᵀr||₂ 满足绝对容差或相对于各自初始范数的相对容差时 收敛,因此允许非零残差的驻点。残差和梯度范数必须均为有限数。 final_residual 为输出 x 处的 ||r||₂。
| [in] | residual | 残差函数回调 r(x)。 |
| [in] | J | Jacobian 回调(可为 NULL,使用有限差分)。 |
| [in] | user_data | 传递给回调的用户数据。 |
| [in,out] | x | 初始猜测 / 输出解。 |
| [in] | cfg | 算法配置(lm_damping 指定初始 λ)。 |
| [out] | out | 迭代结果。 |
尝试阻尼步之前,Jacobian 计算可复用试探缓冲区。
在文件 optimize_lm.c 第 141 行定义.
引用了 lmmc_opt_workspace_t::allocation, lmmc_lm_workspace_t::arena, lmmc_optimize_result_t::failure_reason, lmmc_optimize_result_t::final_residual, lmmc_lm_workspace_t::jacobian, lmmc_optimize_config_t::lm_damping, lmmc_memory_free(), lmmc_minimize_levenberg_marquardt(), LMMC_OPT_FAILURE_NUMERICAL_ISSUE, lmmc_optimize_arguments_valid(), lmmc_optimize_emit(), lmmc_optimize_jacobian(), lmmc_optimize_norm(), lmmc_optimize_result_init(), LMMC_STATUS_INVALID_ARGUMENT, LMMC_STATUS_OK, lmmc_lm_workspace_t::next_residual, lmmc_optimize_result_t::num_iter, lmmc_lm_workspace_t::residual, lmmc_vec_t::size , 以及 lmmc_lm_workspace_t::trial.
被这些函数引用 lmmc_minimize_levenberg_marquardt().
| lmmc_status_t lmmc_minimize_gradient_descent | ( | 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 ) |
梯度下降法(带 Armijo 回溯线搜索)。
| [in] | obj | 目标函数回调。 |
| [in] | grad | 梯度回调。 |
| [in] | user_data | 传递给回调的用户数据。 |
| [in,out] | x | 初始猜测 / 输出解。 |
| [in] | cfg | 算法配置。 |
| [out] | out | 迭代结果。 |
在文件 optimize_gradient.c 第 3 行定义.
引用了 lmmc_opt_workspace_t::allocation, lmmc_vec_t::data, lmmc_optimize_result_t::failure_reason, lmmc_optimize_result_t::final_residual, lmmc_memory_free(), lmmc_minimize_gradient_descent(), LMMC_OPT_FAILURE_LINE_SEARCH_FAILED, LMMC_OPT_FAILURE_NUMERICAL_ISSUE, lmmc_opt_workspace_create(), lmmc_opt_workspace_vector(), lmmc_optimize_arguments_valid(), lmmc_optimize_armijo(), lmmc_optimize_emit(), lmmc_optimize_norm(), lmmc_optimize_result_init(), lmmc_optimize_stop(), LMMC_STATUS_INVALID_ARGUMENT, LMMC_STATUS_OK, lmmc_optimize_result_t::num_iter , 以及 lmmc_vec_t::size.
被这些函数引用 lmmc_minimize_gradient_descent().