23static const lmmc_real_t ros_a31 = 4.524708207373116;
24static const lmmc_real_t ros_a32 = 4.163528788597648;
25static const lmmc_real_t ros_c21 = -5.071675338776316;
26static const lmmc_real_t ros_c31 = 6.020152728650786;
27static const lmmc_real_t ros_c32 = 0.1597506846727117;
28static const lmmc_real_t ros_c41 = -1.856343618686113;
29static const lmmc_real_t ros_c42 = -8.505380858179826;
30static const lmmc_real_t ros_c43 = -2.084075136023187;
32 3.957503746640777, 4.624892388363313,
33 0.6174772638750108, 1.282612945269037
36 2.302155402932996, 3.073634485392623,
37 -0.8732808018045032, -1.282612945269037
40 0.231, -0.03962966775244303,
41 0.5507789395789127, -0.05535098457052764
44static const lmmc_real_t ros_c3 = 0.8802083333333334;
61 int callback_failed = 0;
63 if (time_derivative != NULL) {
64 st = time_derivative(t, y, dfdt, dim, user_data);
72 lmmc_real_t delta = sqrt(2.2204460492503131e-16) * fmax(1.0, fabs(t));
78 for (i = 0; i < dim; ++i) {
79 dfdt[i] = (f_pert[i] - f0[i]) / delta;
119 size_t i, j, swap_count = 0;
120 int callback_failed = 0;
146 for (i = 0; i < s->
dim; ++i) {
147 for (j = 0; j < s->
dim; ++j) {
150 s->
W.
data[i * s->
dim + i] += 1.0 / (s->
h * ros_gamma);
161 int callback_failed = 0;
163 for (i = 0; i < s->
dim; ++i) {
169 for (i = 0; i < s->
dim; ++i) {
170 s->
y_stage[i] = s->
y[i] + ros_a21 * s->
k[0][i];
179 for (i = 0; i < s->
dim; ++i) {
185 for (i = 0; i < s->
dim; ++i) {
186 s->
y_stage[i] = s->
y[i] + ros_a31 * s->
k[0][i] + ros_a32 * s->
k[1][i];
195 for (i = 0; i < s->
dim; ++i) {
197 + (ros_c31 / s->
h) * s->
k[0][i] + (ros_c32 / s->
h) * s->
k[1][i];
202 for (i = 0; i < s->
dim; ++i) {
204 + (ros_c41 / s->
h) * s->
k[0][i] + (ros_c42 / s->
h) * s->
k[1][i]
205 + (ros_c43 / s->
h) * s->
k[2][i];
215 for (i = 0; i < s->
dim; ++i) {
216 s->
y_new[i] = s->
y[i] + ros_b[0] * s->
k[0][i] + ros_b[1] * s->
k[1][i]
217 + ros_b[2] * s->
k[2][i] + ros_b[3] * s->
k[3][i];
218 s->
error[i] = ros_e[0] * s->
k[0][i] + ros_e[1] * s->
k[1][i]
219 + ros_e[2] * s->
k[2][i] + ros_e[3] * s->
k[3][i];
232 while (s->
t < t_end && attempts < s->local_cfg.max_steps) {
235 if (s->
h > t_end - s->
t) {
238 st = ros_prepare_system(s);
240 st = ros_evaluate_stages(s);
242 st = ros_estimate_error(s, &error_norm);
244 if (error_norm <= 1.0) {
292 size_t vectors_bytes = 0, matrix_count = 0, matrix_bytes = 0;
307 !lmmc_safe_mul_size(s->
dim, s->
dim, &matrix_count) ||
308 !lmmc_safe_mul_size(matrix_count,
sizeof(
lmmc_real_t), &matrix_bytes) ||
309 !lmmc_safe_mul_size(s->
dim,
sizeof(
size_t), &matrix_count)) {
319 return ros_cleanup(s, st);
337 if (s->
h > t_end - t_start) {
338 s->
h = t_end - t_start;
341 st = ros_integrate(s, t_end);
342 return ros_cleanup(s, st);
double lmmc_real_t
Public and internal LMMC real type.
稠密矩阵直接分解接口(LU、Cholesky、QR)。
lmmc_status_t lmmc_lu_solve(const lmmc_mat_t *lu, const size_t *pivots, const lmmc_vec_t *b, lmmc_vec_t *x)
利用 LU 分解结果求解线性系统 A*x = b。
lmmc_status_t lmmc_lu_decompose_inplace(lmmc_mat_t *a, size_t *pivots, size_t *out_swap_count)
就地 LU 分解(带部分主元选取):P*A = L*U。
void * lmmc_memory_alloc(size_t size)
void lmmc_memory_free(void *pointer)
Private recoverable allocator for persistent LMMC ownership.
常微分方程初值问题求解器:Euler、RK4、RK45(自适应)。
lmmc_status_t(*) lmmc_ode_rhs_t(lmmc_real_t t, const lmmc_real_t *y, lmmc_real_t *y_prime, size_t dim, void *user_data)
ODE 右端函数签名 。
@ LMMC_ODE_FAILURE_NUMERICAL_ISSUE
@ LMMC_ODE_FAILURE_INVALID_STEP
@ LMMC_ODE_FAILURE_RHS_EVAL_FAILED
@ LMMC_ODE_FAILURE_INVALID_DIMENSION
@ LMMC_ODE_FAILURE_MAX_STEPS
lmmc_ode_dfdt_t time_derivative
lmmc_status_t lmmc_ode_rosenbrock_grk4t_solve(lmmc_ode_rhs_t rhs, void *user_data, size_t dim, lmmc_real_t t_start, lmmc_real_t t_end, lmmc_real_t *y, const lmmc_ode_config_t *cfg, lmmc_ode_result_t *out_result)
Rosenbrock-Wanner GRK4T 求解器(线性隐式,四阶,每步一次 LU)。
lmmc_ode_failure_t failure_reason
lmmc_status_t(*) lmmc_ode_dfdt_t(lmmc_real_t t, const lmmc_real_t *y, lmmc_real_t *dfdt, size_t dim, void *user_data)
ODE 对时间偏导回调签名 .
lmmc_status_t lmmc_ode_rhs_eval(lmmc_ode_rhs_t rhs, lmmc_real_t t, const lmmc_real_t *y, lmmc_real_t *y_prime, size_t dim, void *user_data, size_t *io_eval_count, int *out_callback_failed)
lmmc_status_t lmmc_ode_jacobian_eval(const lmmc_ode_jacobian_request_t *request)
lmmc_real_t lmmc_ode_next_step(lmmc_real_t h, lmmc_real_t error_norm, const lmmc_ode_config_t *cfg)
lmmc_status_t lmmc_ode_values_are_finite(const lmmc_real_t *values, size_t count)
lmmc_status_t validate_and_init_ode_config(lmmc_ode_rhs_t rhs, size_t dim, lmmc_real_t t_start, lmmc_real_t t_end, const lmmc_real_t *y, const lmmc_ode_config_t *cfg, lmmc_ode_config_t *out_cfg, lmmc_ode_result_t *out_result, size_t *out_work_bytes)
void lmmc_ode_do_log(const lmmc_ode_config_t *cfg, size_t step, lmmc_real_t t, const lmmc_real_t *y, size_t dim)
lmmc_status_t lmmc_ode_weighted_rms(const lmmc_real_t *error, const lmmc_real_t *y_old, const lmmc_real_t *y_new, size_t dim, lmmc_real_t abs_tol, lmmc_real_t rel_tol, lmmc_real_t *out_norm)
lmmc_real_t * k[ROS_STAGES]
lmmc_real_t * matrix_data
lmmc_ode_config_t local_cfg
lmmc_ode_result_t * out_result
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_CONVERGENCE_FAILED
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT