LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
nonlinear.c
浏览该文件的文档.
1
5#include <math.h>
6#include <float.h>
7#include "internal.h"
9
11 const lmmc_real_t values[] = {x, f_x};
12 const lmmc_diagnostic_t diagnostic = {
13 LMMC_DIAGNOSTIC_TRACE, "nonlinear", "iteration", iter, values, 2
14 };
15 lmmc_diagnostic_emit(&cfg->diagnostics, &diagnostic);
16}
17
18
20 lmmc_real_t left, lmmc_real_t right) {
21 return lmmc_interval_midpoint(left, right);
22}
23
25 lmmc_real_t left, lmmc_real_t right) {
26 lmmc_real_t center;
27 lmmc_real_t half_width;
28 lmmc_interval_center_half_width(
29 left, right, &center, &half_width);
30 return half_width;
31}
33 lmmc_real_t left, lmmc_real_t right) {
34 const lmmc_real_t difference = left - right;
35 return lmmc_is_finite(&difference) ? lmmc_abs(difference) : DBL_MAX;
36}
37
38
40 const lmmc_nonlinear_config_t* cfg,
42) {
43 if (out_cfg == NULL) {
45 }
46
47 if (cfg != NULL) {
48 *out_cfg = *cfg;
49 } else {
51 if (st != LMMC_STATUS_OK) {
52 return st;
53 }
54 }
55
56 if (!lmmc_is_finite(&out_cfg->abs_tol) || !lmmc_is_finite(&out_cfg->rel_tol) ||
57 !lmmc_is_finite(&out_cfg->derivative_step) || !lmmc_is_finite(&out_cfg->min_derivative) ||
58 !lmmc_is_finite(&out_cfg->min_step)) {
60 }
61 if (out_cfg->abs_tol < 0.0 || out_cfg->rel_tol < 0.0 ||
62 out_cfg->max_iter == 0 || out_cfg->derivative_step <= 0.0 || out_cfg->min_derivative <= 0.0 ||
63 out_cfg->min_step < 0.0) {
65 }
66
67 return LMMC_STATUS_OK;
68}
69
72 const lmmc_nonlinear_config_t* cfg,
73 lmmc_real_t* out_x_tol
74) {
75 lmmc_real_t x_scale = 0.0;
76 lmmc_real_t x_tol = 0.0;
77 lmmc_real_t abs_x = 0.0;
78 lmmc_real_t one = 1.0;
79 lmmc_real_t tmp = 0.0;
80
81 if (cfg == NULL || out_x_tol == NULL || !lmmc_is_finite(&x)) {
83 }
84
85 abs_x = lmmc_abs(x);
86 x_scale = lmmc_max(abs_x, one);
87 LMMC_REAL_MUL(&tmp, &cfg->rel_tol, &x_scale);
88 LMMC_REAL_ADD(&x_tol, &cfg->abs_tol, &tmp);
89
90 if (!lmmc_is_finite(&x_tol)) {
92 }
93
94 *out_x_tol = x_tol;
95 return LMMC_STATUS_OK;
96}
97
99 if (out_result == NULL) {
100 return;
101 }
102
103 out_result->converged = 0;
104 out_result->num_iter = 0;
105 out_result->root = 0.0;
106 out_result->function_value = 0.0;
107 out_result->residual_norm = 0.0;
109}
110
112 switch (reason) {
114 return "none";
116 return "invalid bracket";
118 return "max iterations reached";
120 return "zero derivative";
122 return "numerical issue";
124 return "singular step";
125 default:
126 return "unknown";
127 }
128}
129
131 if (out_cfg == NULL) {
133 }
134
135 out_cfg->abs_tol = LMMC_DEFAULT_ABS_TOL;
136 out_cfg->rel_tol = LMMC_DEFAULT_REL_TOL;
137 out_cfg->max_iter = 100;
138 out_cfg->derivative_step = 1e-6;
139 out_cfg->min_derivative = 1e-14;
140 out_cfg->min_step = 1e-14;
141 out_cfg->diagnostics = (lmmc_diagnostic_sink_t){0};
142 return LMMC_STATUS_OK;
143}
#define LMMC_REAL_ADD(res, a, b)
计算 *res = *a + *b 。
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_MUL(res, a, b)
计算 *res = *a * *b 。
void lmmc_diagnostic_emit(const lmmc_diagnostic_sink_t *sink, const lmmc_diagnostic_t *diagnostic)
通过调用方持有的接收器发送一个诊断事件;空接收器直接完成.
@ LMMC_DIAGNOSTIC_TRACE
LMMC 内部使用的公共工具(仅源文件可见).
lmmc_diagnostic_sink_t diagnostics
lmmc_nonlinear_failure_t
求根失败原因.
@ LMMC_NONLINEAR_FAILURE_INVALID_BRACKET
@ LMMC_NONLINEAR_FAILURE_NONE
@ LMMC_NONLINEAR_FAILURE_ZERO_DERIVATIVE
@ LMMC_NONLINEAR_FAILURE_SINGULAR_STEP
@ LMMC_NONLINEAR_FAILURE_MAX_ITER
@ LMMC_NONLINEAR_FAILURE_NUMERICAL_ISSUE
lmmc_nonlinear_failure_t failure_reason
lmmc_status_t lmmc_nonlinear_default_config(lmmc_nonlinear_config_t *out_cfg)
生成默认配置.
const char * lmmc_nonlinear_failure_string(lmmc_nonlinear_failure_t reason)
获取失败原因对应的可读字符串.
求根算法配置.
求根结果统计.
void lmmc_nonlinear_do_log(const lmmc_nonlinear_config_t *cfg, size_t iter, lmmc_real_t x, lmmc_real_t f_x)
lmmc_status_t lmmc_nonlinear_x_tolerance(lmmc_real_t x, const lmmc_nonlinear_config_t *cfg, lmmc_real_t *out_x_tol)
void lmmc_nonlinear_reset_result(lmmc_nonlinear_result_t *out_result)
lmmc_real_t lmmc_nonlinear_half_width(lmmc_real_t left, lmmc_real_t right)
lmmc_real_t lmmc_nonlinear_distance(lmmc_real_t left, lmmc_real_t right)
lmmc_real_t lmmc_nonlinear_midpoint(lmmc_real_t left, lmmc_real_t right)
lmmc_status_t lmmc_nonlinear_load_and_validate_config(const lmmc_nonlinear_config_t *cfg, lmmc_nonlinear_config_t *out_cfg)
#define LMMC_DEFAULT_REL_TOL
库默认的相对容差.
#define LMMC_DEFAULT_ABS_TOL
库默认的绝对容差.
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_INVALID_ARGUMENT