LMMC
Lamina Mathematic core
Toggle main menu visibility
载入中...
搜索中...
未找到
nonlinear.c
浏览该文件的文档.
1
5
#include <math.h>
6
#include <float.h>
7
#include "
internal.h
"
8
#include "
internal/nonlinear_internal.h
"
9
10
void
lmmc_nonlinear_do_log
(
const
lmmc_nonlinear_config_t
* cfg,
size_t
iter,
lmmc_real_t
x,
lmmc_real_t
f_x) {
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
19
lmmc_real_t
lmmc_nonlinear_midpoint
(
20
lmmc_real_t
left,
lmmc_real_t
right) {
21
return
lmmc_interval_midpoint(left, right);
22
}
23
24
lmmc_real_t
lmmc_nonlinear_half_width
(
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, ¢er, &half_width);
30
return
half_width;
31
}
32
lmmc_real_t
lmmc_nonlinear_distance
(
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
39
lmmc_status_t
lmmc_nonlinear_load_and_validate_config
(
40
const
lmmc_nonlinear_config_t
* cfg,
41
lmmc_nonlinear_config_t
* out_cfg
42
) {
43
if
(out_cfg == NULL) {
44
return
LMMC_STATUS_INVALID_ARGUMENT
;
45
}
46
47
if
(cfg != NULL) {
48
*out_cfg = *cfg;
49
}
else
{
50
lmmc_status_t
st =
lmmc_nonlinear_default_config
(out_cfg);
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
)) {
59
return
LMMC_STATUS_INVALID_ARGUMENT
;
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) {
64
return
LMMC_STATUS_INVALID_ARGUMENT
;
65
}
66
67
return
LMMC_STATUS_OK
;
68
}
69
70
lmmc_status_t
lmmc_nonlinear_x_tolerance
(
71
lmmc_real_t
x,
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)) {
82
return
LMMC_STATUS_INVALID_ARGUMENT
;
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)) {
91
return
LMMC_STATUS_NUMERICAL_FAILURE
;
92
}
93
94
*out_x_tol = x_tol;
95
return
LMMC_STATUS_OK
;
96
}
97
98
void
lmmc_nonlinear_reset_result
(
lmmc_nonlinear_result_t
* out_result) {
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;
108
out_result->
failure_reason
=
LMMC_NONLINEAR_FAILURE_NONE
;
109
}
110
111
const
char
*
lmmc_nonlinear_failure_string
(
lmmc_nonlinear_failure_t
reason) {
112
switch
(reason) {
113
case
LMMC_NONLINEAR_FAILURE_NONE
:
114
return
"none"
;
115
case
LMMC_NONLINEAR_FAILURE_INVALID_BRACKET
:
116
return
"invalid bracket"
;
117
case
LMMC_NONLINEAR_FAILURE_MAX_ITER
:
118
return
"max iterations reached"
;
119
case
LMMC_NONLINEAR_FAILURE_ZERO_DERIVATIVE
:
120
return
"zero derivative"
;
121
case
LMMC_NONLINEAR_FAILURE_NUMERICAL_ISSUE
:
122
return
"numerical issue"
;
123
case
LMMC_NONLINEAR_FAILURE_SINGULAR_STEP
:
124
return
"singular step"
;
125
default
:
126
return
"unknown"
;
127
}
128
}
129
130
lmmc_status_t
lmmc_nonlinear_default_config
(
lmmc_nonlinear_config_t
* out_cfg) {
131
if
(out_cfg == NULL) {
132
return
LMMC_STATUS_INVALID_ARGUMENT
;
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
}
LMMC_REAL_ADD
#define LMMC_REAL_ADD(res, a, b)
计算 *res = *a + *b 。
定义
config.h:46
lmmc_real_t
double lmmc_real_t
Public and internal LMMC real type.
定义
config.h:28
LMMC_REAL_MUL
#define LMMC_REAL_MUL(res, a, b)
计算 *res = *a * *b 。
定义
config.h:50
lmmc_diagnostic_emit
void lmmc_diagnostic_emit(const lmmc_diagnostic_sink_t *sink, const lmmc_diagnostic_t *diagnostic)
通过调用方持有的接收器发送一个诊断事件;空接收器直接完成.
定义
diagnostic.c:3
LMMC_DIAGNOSTIC_TRACE
@ LMMC_DIAGNOSTIC_TRACE
定义
diagnostic.h:17
lmmc_diagnostic_sink_t
定义
diagnostic.h:37
lmmc_diagnostic_t
定义
diagnostic.h:23
internal.h
LMMC 内部使用的公共工具(仅源文件可见).
lmmc_nonlinear_result_t::num_iter
size_t num_iter
定义
nonlinear.h:47
lmmc_nonlinear_result_t::residual_norm
lmmc_real_t residual_norm
定义
nonlinear.h:50
lmmc_nonlinear_config_t::abs_tol
lmmc_real_t abs_tol
定义
nonlinear.h:58
lmmc_nonlinear_result_t::converged
int converged
定义
nonlinear.h:46
lmmc_nonlinear_config_t::rel_tol
lmmc_real_t rel_tol
定义
nonlinear.h:59
lmmc_nonlinear_config_t::diagnostics
lmmc_diagnostic_sink_t diagnostics
定义
nonlinear.h:64
lmmc_nonlinear_failure_t
lmmc_nonlinear_failure_t
求根失败原因.
定义
nonlinear.h:33
LMMC_NONLINEAR_FAILURE_INVALID_BRACKET
@ LMMC_NONLINEAR_FAILURE_INVALID_BRACKET
定义
nonlinear.h:35
LMMC_NONLINEAR_FAILURE_NONE
@ LMMC_NONLINEAR_FAILURE_NONE
定义
nonlinear.h:34
LMMC_NONLINEAR_FAILURE_ZERO_DERIVATIVE
@ LMMC_NONLINEAR_FAILURE_ZERO_DERIVATIVE
定义
nonlinear.h:37
LMMC_NONLINEAR_FAILURE_SINGULAR_STEP
@ LMMC_NONLINEAR_FAILURE_SINGULAR_STEP
定义
nonlinear.h:39
LMMC_NONLINEAR_FAILURE_MAX_ITER
@ LMMC_NONLINEAR_FAILURE_MAX_ITER
定义
nonlinear.h:36
LMMC_NONLINEAR_FAILURE_NUMERICAL_ISSUE
@ LMMC_NONLINEAR_FAILURE_NUMERICAL_ISSUE
定义
nonlinear.h:38
lmmc_nonlinear_config_t::min_derivative
lmmc_real_t min_derivative
定义
nonlinear.h:62
lmmc_nonlinear_result_t::failure_reason
lmmc_nonlinear_failure_t failure_reason
定义
nonlinear.h:51
lmmc_nonlinear_config_t::min_step
lmmc_real_t min_step
定义
nonlinear.h:63
lmmc_nonlinear_default_config
lmmc_status_t lmmc_nonlinear_default_config(lmmc_nonlinear_config_t *out_cfg)
生成默认配置.
定义
nonlinear.c:130
lmmc_nonlinear_result_t::function_value
lmmc_real_t function_value
定义
nonlinear.h:49
lmmc_nonlinear_config_t::derivative_step
lmmc_real_t derivative_step
定义
nonlinear.h:61
lmmc_nonlinear_config_t::max_iter
size_t max_iter
定义
nonlinear.h:60
lmmc_nonlinear_result_t::root
lmmc_real_t root
定义
nonlinear.h:48
lmmc_nonlinear_failure_string
const char * lmmc_nonlinear_failure_string(lmmc_nonlinear_failure_t reason)
获取失败原因对应的可读字符串.
定义
nonlinear.c:111
lmmc_nonlinear_config_t
求根算法配置.
定义
nonlinear.h:57
lmmc_nonlinear_result_t
求根结果统计.
定义
nonlinear.h:45
nonlinear_internal.h
lmmc_nonlinear_do_log
void lmmc_nonlinear_do_log(const lmmc_nonlinear_config_t *cfg, size_t iter, lmmc_real_t x, lmmc_real_t f_x)
定义
nonlinear.c:10
lmmc_nonlinear_x_tolerance
lmmc_status_t lmmc_nonlinear_x_tolerance(lmmc_real_t x, const lmmc_nonlinear_config_t *cfg, lmmc_real_t *out_x_tol)
定义
nonlinear.c:70
lmmc_nonlinear_reset_result
void lmmc_nonlinear_reset_result(lmmc_nonlinear_result_t *out_result)
定义
nonlinear.c:98
lmmc_nonlinear_half_width
lmmc_real_t lmmc_nonlinear_half_width(lmmc_real_t left, lmmc_real_t right)
定义
nonlinear.c:24
lmmc_nonlinear_distance
lmmc_real_t lmmc_nonlinear_distance(lmmc_real_t left, lmmc_real_t right)
定义
nonlinear.c:32
lmmc_nonlinear_midpoint
lmmc_real_t lmmc_nonlinear_midpoint(lmmc_real_t left, lmmc_real_t right)
定义
nonlinear.c:19
lmmc_nonlinear_load_and_validate_config
lmmc_status_t lmmc_nonlinear_load_and_validate_config(const lmmc_nonlinear_config_t *cfg, lmmc_nonlinear_config_t *out_cfg)
定义
nonlinear.c:39
LMMC_DEFAULT_REL_TOL
#define LMMC_DEFAULT_REL_TOL
库默认的相对容差.
定义
numeric_scalar.h:35
LMMC_DEFAULT_ABS_TOL
#define LMMC_DEFAULT_ABS_TOL
库默认的绝对容差.
定义
numeric_scalar.h:31
lmmc_status_t
lmmc_status_t
LMMC 库统一返回的状态码.
定义
status.h:22
LMMC_STATUS_OK
@ LMMC_STATUS_OK
定义
status.h:23
LMMC_STATUS_NUMERICAL_FAILURE
@ LMMC_STATUS_NUMERICAL_FAILURE
定义
status.h:29
LMMC_STATUS_INVALID_ARGUMENT
@ LMMC_STATUS_INVALID_ARGUMENT
定义
status.h:24
src
nonlinear.c
生成于
, 为 LMMC使用
1.18.0